GPURenderBundle
Limited availability
This feature is not Baseline because it does not work in some of the most widely-used browsers.
Experimentell: Dies ist eine experimentelle Technologie
Überprüfen Sie die Browser-Kompatibilitätstabelle sorgfältig, bevor Sie diese produktiv verwenden.
Sicherer Kontext: Diese Funktion ist nur in sicheren Kontexten (HTTPS) in einigen oder allen unterstützenden Browsern verfügbar.
Hinweis: Dieses Feature ist verfügbar in Web Workers.
Die GPURenderBundle
-Schnittstelle der WebGPU API stellt einen Container für voraufgezeichnete Befehlspakete dar.
Die Befehlspakete werden mit einem GPURenderBundleEncoder
kodiert; sobald die gewünschten Befehle kodiert wurden, werden sie mit der Methode GPURenderBundleEncoder.finish()
in einem GPURenderBundle
-Objektinstanz aufgezeichnet.
Diese Befehlspakete können dann über mehrere Rendervorgänge hinweg wiederverwendet werden, indem die GPURenderBundle
-Objekte in Aufrufe von GPURenderPassEncoder.executeBundles()
übergeben werden. Die Wiederverwendung von voraufgezeichneten Befehlen kann die Leistung der Anwendung erheblich verbessern, insbesondere in Situationen, in denen der Overhead von JavaScript-Zeichenaufrufen ein Engpass ist. Render-Bundles sind besonders effektiv in Situationen, in denen eine Gruppe von Objekten auf die gleiche Weise über mehrere Ansichten oder Frames gezeichnet wird, wobei die einzigen Unterschiede der verwendete Pufferinhalt sind (z. B. aktualisierte Matrix-Uniformen).
Ein gutes Beispiel ist das VR-Rendering. Das Aufzeichnen des Renderings als Render-Bundle und das anschließende Anpassen der Ansichts-Matrix und das erneute Abspielen für jedes Auge ist eine effizientere Methode, Zeichnungsaufrufe für beide Renderings der Szene auszugeben.
Instanz-Eigenschaften
Beispiele
Im WebGPU Samples Animometer Beispiel werden viele ähnliche Operationen gleichzeitig an vielen verschiedenen Objekten ausgeführt. Ein Render-Bundle wird mit der folgenden Funktion kodiert:
function recordRenderPass(
passEncoder: GPURenderBundleEncoder | GPURenderPassEncoder
) {
if (settings.dynamicOffsets) {
passEncoder.setPipeline(dynamicPipeline);
} else {
passEncoder.setPipeline(pipeline);
}
passEncoder.setVertexBuffer(0, vertexBuffer);
passEncoder.setBindGroup(0, timeBindGroup);
const dynamicOffsets = [0];
for (let i = 0; i < numTriangles; ++i) {
if (settings.dynamicOffsets) {
dynamicOffsets[0] = i * alignedUniformBytes;
passEncoder.setBindGroup(1, dynamicBindGroup, dynamicOffsets);
} else {
passEncoder.setBindGroup(1, bindGroups[i]);
}
passEncoder.draw(3, 1, 0, 0);
}
}
Später wird ein GPURenderBundleEncoder
erstellt, die Funktion wird aufgerufen, und das Render-Bundle wird mit GPURenderBundleEncoder.finish()
aufgezeichnet:
const renderBundleEncoder = device.createRenderBundleEncoder({
colorFormats: [presentationFormat],
});
recordRenderPass(renderBundleEncoder);
const renderBundle = renderBundleEncoder.finish();
GPURenderPassEncoder.executeBundles()
wird dann verwendet, um die Arbeit über mehrere Rendervorgänge hinweg wiederzuverwenden, um die Leistung zu verbessern. Studieren Sie den Beispielcode für den vollständigen Kontext.
// ...
return function doDraw(timestamp) {
if (startTime === undefined) {
startTime = timestamp;
}
uniformTime[0] = (timestamp - startTime) / 1000;
device.queue.writeBuffer(uniformBuffer, timeOffset, uniformTime.buffer);
renderPassDescriptor.colorAttachments[0].view = context
.getCurrentTexture()
.createView();
const commandEncoder = device.createCommandEncoder();
const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
if (settings.renderBundles) {
passEncoder.executeBundles([renderBundle]);
} else {
recordRenderPass(passEncoder);
}
passEncoder.end();
device.queue.submit([commandEncoder.finish()]);
};
// ...
Spezifikationen
Specification |
---|
WebGPU # gpurenderbundle |
Browser-Kompatibilität
BCD tables only load in the browser
Siehe auch
- Die WebGPU API