GPURenderBundle
Limited availability
This feature is not Baseline because it does not work in some of the most widely-used browsers.
Secure context: This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.
Note: This feature is available in Web Workers.
Giao diện GPURenderBundle của WebGPU API đại diện cho một vùng chứa các gói lệnh được ghi trước.
Các gói lệnh được mã hóa bằng GPURenderBundleEncoder; sau khi các lệnh mong muốn được mã hóa, chúng được ghi vào đối tượng GPURenderBundle bằng phương thức GPURenderBundleEncoder.finish().
Các gói lệnh này có thể được tái sử dụng trên nhiều lần render pass bằng cách truyền đối tượng GPURenderBundle vào lệnh gọi GPURenderPassEncoder.executeBundles(). Tái sử dụng các lệnh được ghi trước có thể cải thiện đáng kể hiệu suất ứng dụng trong các tình huống mà chi phí gọi JavaScript để vẽ là nút thắt cổ chai. Gói render hiệu quả nhất trong các tình huống khi một loạt đối tượng sẽ được vẽ theo cùng một cách trên nhiều khung nhìn hoặc khung, với sự khác biệt duy nhất là nội dung bộ đệm đang được sử dụng (chẳng hạn như các uniform ma trận đã cập nhật).
Một ví dụ điển hình là kết xuất VR. Việc ghi kết xuất dưới dạng gói render rồi điều chỉnh ma trận khung nhìn và phát lại cho mỗi mắt là cách hiệu quả hơn để phát lệnh vẽ cho cả hai lần kết xuất của cảnh.
Thuộc tính phiên bản
Ví dụ
Trong ví dụ Animometer của WebGPU Samples, nhiều thao tác tương tự được thực hiện trên nhiều đối tượng khác nhau đồng thời. Gói render được mã hóa bằng hàm sau:
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);
}
}
Sau đó, một GPURenderBundleEncoder được tạo, hàm được gọi, và gói render được ghi bằng GPURenderBundleEncoder.finish():
const renderBundleEncoder = device.createRenderBundleEncoder({
colorFormats: [presentationFormat],
});
recordRenderPass(renderBundleEncoder);
const renderBundle = renderBundleEncoder.finish();
GPURenderPassEncoder.executeBundles() sau đó được sử dụng để tái sử dụng công việc trên nhiều render pass để cải thiện hiệu suất. Nghiên cứu danh sách mã ví dụ để biết toàn bộ ngữ cảnh.
// …
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()]);
};
// …
Thông số kỹ thuật
| Specification |
|---|
| WebGPU> # gpurenderbundle> |