GPU instancing draws multiple copies of the same geometry in one draw call, using @builtin(instance_index) to differentiate each copy
Instancing renders N copies of the same geometry with a single draw(vertexCount, N) call instead of N separate draw calls. Each copy is an ‘instance’. Inside the vertex shader, @builtin(instance_index) provides a per-instance integer (0 to N-1) that the shader uses to compute a unique transform — for example, mapping a linear index to a 2D grid cell. Instancing is far faster than N draw calls because it avoids per-call CPU overhead and keeps the GPU fed continuously. A 32×32 grid of 1024 cells is rendered with pass.draw(6, 1024).
Examples
@vertex fn vertexMain(@location(0) pos: vec2f,
@builtin(instance_index) instance: u32) -> @builtin(position) vec4f {
let i = f32(instance);
let cell = vec2f(i % grid.x, floor(i / grid.x));
// ... compute per-instance offset
}
Assessment
Rewrite pass.draw(6, 1) to draw a 32×32 grid of instances. Why is calling draw(6,1) in a JS loop 1024 times slower than a single draw(6, 1024)?