uniform buffer와 bind group
WebGL에서는 uniform 값을 직접 program에 설정했습니다. WebGPU에서는 uniform data를 buffer에 담고, shader가 사용할 resource 묶음을 bind group으로 연결합니다.
uniform buffer와 bind group 코드
camera matrix를 담을 uniform buffer를 만들고, shader의 @group(0) @binding(0)에 연결합니다.
const uniformBuffer = device.createBuffer({
size: 16 * Float32Array.BYTES_PER_ELEMENT,
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
});
device.queue.writeBuffer(
uniformBuffer,
0,
new Float32Array(cameraProjectionMatrix)
);
const bindGroup = device.createBindGroup({
layout: pipeline.getBindGroupLayout(0),
entries: [{
binding: 0,
resource: { buffer: uniformBuffer }
}]
});
render pass에서는 pipeline을 설정한 뒤 bind group을 끼웁니다.
pass.setPipeline(pipeline);
pass.setBindGroup(0, bindGroup);
pass.setVertexBuffer(0, vertexBuffer);
pass.draw(vertexCount);
WGSL 쪽에서는 같은 binding 번호로 uniform을 읽습니다.
@group(0) @binding(0)
var<uniform> u_matrix: mat4x4f;
uniform buffer는 공유 상수 데이터다
camera matrix처럼 draw 중 많은 vertex가 공유하는 값은 uniform buffer에 넣을 수 있습니다.
camera matrix
viewport size
time
device queue를 통해 buffer 내용을 갱신합니다.
device.queue.writeBuffer(uniformBuffer, 0, matrixData);
bind group은 shader resource 묶음이다
shader가 어떤 buffer와 texture를 볼 수 있는지는 bind group으로 정합니다.
bind group
binding 0: uniform buffer
binding 1: texture
binding 2: sampler
pipeline layout은 이 bind group 구조와 맞아야 합니다.
camera 변경은 uniform buffer 갱신이다
pan/zoom으로 camera가 바뀌면 vertex geometry를 다시 만들 필요가 없습니다. camera uniform buffer만 갱신하면 됩니다.
same vertex buffer
updated camera uniform buffer
draw again
WebGL에서 matrix uniform을 바꾸던 감각과 같은 목적입니다.
오늘의 핵심
WebGPU는 uniform과 texture 같은 shader resource를 bind group으로 명시적으로 연결합니다.
data buffer
bind group layout
bind group
pipeline
draw
장황하지만 이 명시성이 큰 renderer에서 안정성을 줍니다.