GPURenderBundleEncoder
GPURenderBundleEncoder
是 WebGPU API 的一个接口,用于预先录制命令包。
命令包通过调用 GPURenderBundleEncoder
的方法进行编码;一旦编码了所需的命令,就会使用 GPURenderBundleEncoder.finish()
方法将它们记录到 GPURenderBundle
对象实例中。然后,这些渲染包可以通过将 GPURenderBundle
对象传递到 GPURenderPassEncoder.executeBundles()
调用中,在多个渲染通道中重复使用。
实际上,这就像一个部分渲染传递 - `GPURenderBundleEncoder` 与 GPURenderPassEncoder
具有相同的全部功能,只是它们不能开始和结束遮挡查询,也不能设置剪切矩形、视口、混合常量和模板参考。`GPURenderBundle` 将从执行它的 GPURenderPassEncoder
继承所有这些值。
注意:目前,在执行渲染包之前和之后,所有已设置的顶点缓冲区、索引缓冲区、绑定组和管道都会被清除。
在 JavaScript 绘制调用开销成为瓶颈的情况下,重用预先编码的命令可以显著提高应用程序性能。在将一批对象以相同的方式绘制到多个视图或帧中时,渲染包最为有效,唯一的区别是使用的缓冲区内容(例如更新的矩阵一致)。VR 渲染就是一个很好的例子。将渲染录制为渲染包,然后调整视图矩阵并为每个眼睛重放,是一种更高效地为场景的两种渲染发出绘制调用的方法。
通过 GPUDevice.createRenderBundleEncoder()
属性创建 `GPURenderBundleEncoder` 对象实例。
注意:`GPURenderBundleEncoder` 的方法在功能上与 GPURenderPassEncoder
上的等效方法相同,除了 GPURenderBundleEncoder.finish()
,它的用途类似于 GPUCommandEncoder.finish()
。
实例属性
实例方法
draw()
实验性-
基于
setVertexBuffer()
提供的顶点缓冲区绘制图元。 drawIndexed()
实验性-
基于
setVertexBuffer()
和setIndexBuffer()
提供的顶点和索引缓冲区绘制索引图元。 drawIndirect()
实验性-
使用从
GPUBuffer
读取的参数绘制图元。 drawIndexedIndirect()
实验性-
使用从
GPUBuffer
读取的参数绘制索引图元。 finish()
实验性-
完成当前渲染传递命令序列的录制。
insertDebugMarker()
实验性-
使用标签标记一系列编码命令中的特定点。
popDebugGroup()
实验性-
结束一个调试组,调试组由
pushDebugGroup()
调用开始。 pushDebugGroup()
实验性-
开始一个调试组,用指定的标签标记,并将包含所有后续的编码命令,直到调用
popDebugGroup()
方法。 setBindGroup()
实验性-
为给定的索引设置后续渲染包命令要使用的
GPUBindGroup
。 setIndexBuffer()
实验性-
设置当前的
GPUBuffer
,它将为后续的绘制命令提供索引数据。 setPipeline()
实验性-
设置此渲染包要使用的
GPURenderPipeline
。 setVertexBuffer()
实验性-
设置或取消设置当前的
GPUBuffer
,它将为后续的绘制命令提供顶点数据。
示例
在 WebGPU 示例 Animometer 示例 中,许多类似的操作同时在许多不同的对象上进行。使用以下函数编码命令包
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`,调用函数,并将命令包记录到 GPURenderBundle
中,使用 GPURenderBundleEncoder.finish()
const renderBundleEncoder = device.createRenderBundleEncoder({
colorFormats: [presentationFormat],
});
recordRenderPass(renderBundleEncoder);
const renderBundle = renderBundleEncoder.finish();
然后使用 GPURenderPassEncoder.executeBundles()
在多个渲染传递中重用工作,以提高性能。研究示例代码清单以了解完整的内容。
// ...
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 |
浏览器兼容性
BCD 表格仅在浏览器中加载