GPURenderBundle
注意:此功能在 Web Workers 中可用。
GPURenderBundle 接口是 WebGPU API 的一部分,它表示一个用于预先录制命令包的容器。
命令包使用 GPURenderBundleEncoder 进行编码;一旦所需的命令被编码,它们就会通过 GPURenderBundleEncoder.finish() 方法录制到一个 GPURenderBundle 对象实例中。
然后,通过将 GPURenderBundle 对象传递给 GPURenderPassEncoder.executeBundles() 调用,可以在多个渲染通道中重用这些命令包。在 JavaScript 绘制调用开销成为瓶颈的情况下,重用预先录制的命令可以显著提高应用程序性能。当一批对象需要在多个视图或帧中以相同方式绘制,而唯一区别是使用的缓冲区内容(例如更新的矩阵 uniform)时,渲染包最为有效。
VR 渲染是一个很好的例子。将渲染录制为渲染包,然后为每只眼睛调整视图矩阵并重放它,是为场景的两个渲染发出绘制调用的更有效方法。
实例属性
示例
在 WebGPU 示例的 Animometer 示例 中,许多类似的opertions同时在许多不同的对象上进行。渲染包使用以下函数进行编码:
js
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);
}
}
稍后,会创建一个 GPURenderBundleEncoder,调用该函数,并使用 GPURenderBundleEncoder.finish() 录制渲染包。
js
const renderBundleEncoder = device.createRenderBundleEncoder({
colorFormats: [presentationFormat],
});
recordRenderPass(renderBundleEncoder);
const renderBundle = renderBundleEncoder.finish();
然后使用 GPURenderPassEncoder.executeBundles() 在多个渲染通道中重用该工作以提高性能。请参阅示例代码列表以获取完整上下文。
js
// …
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()]);
};
// …
规范
| 规范 |
|---|
| WebGPU # gpurenderbundle |
浏览器兼容性
加载中…