A WebGPU render loop re-records and re-submits a command buffer each frame; requestAnimationFrame or setInterval drives the cadence
WebGPU has no built-in render loop. Each frame requires: (1) recording a new command encoder and render pass; (2) calling context.getCurrentTexture() to get the current frame’s canvas texture; (3) submitting the command buffer. A previous command buffer cannot be reused. For smooth 60fps animation, use requestAnimationFrame(). For simulations updating at a fixed slower rate, use setInterval(updateGrid, ms). The step counter must be incremented each update to correctly alternate ping-pong bind groups.
Examples
function updateGrid() {
step++;
const encoder = device.createCommandEncoder();
const pass = encoder.beginRenderPass({ colorAttachments: [{ view: context.getCurrentTexture().createView(), loadOp: 'clear', storeOp: 'store' }] });
pass.setPipeline(cellPipeline);
pass.setBindGroup(0, bindGroups[step % 2]);
pass.draw(6, GRID_SIZE * GRID_SIZE);
pass.end();
device.queue.submit([encoder.finish()]);
}
setInterval(updateGrid, 200);
Assessment
Why must context.getCurrentTexture() be called inside the update function rather than once at initialization? What happens if you submit the same command buffer twice?