Tutorial9 WebGPU Encoding and Compression
Tutorial9 WebGPU Encoding and Compression
Enable it manually:
1. Go to chrome://flags
2. Search for WebGPU
3. Set it to Enabled
4. Restart Chrome
• Unsafe WebGPU
• Dawn backend
On Linux, WebGPU may still be behind a flag or disabled depending on your GPU and
drivers.
https://webgpureport.org
// Grab elements
const canvas = document.getElementById('gpu-canvas');
const info = document.getElementById('info');
context.configure({
device,
format,
alphaMode: 'opaque',
size: [canvas.clientWidth * devicePixelRatio, canvas.clientHeight * devicePixelRatio],
});
// Torus generation
function createTorus(radius = 0.5, tube = 0.2, radialSegments = 16, tubularSegments =
32) {
const positions = [];
const indices = [];
for(let j = 0; j <= radialSegments; j++) {
const v = j / radialSegments * 2 * Math.PI;
const cosV = Math.cos(v);
const sinV = Math.sin(v);
for(let i = 0; i <= tubularSegments; i++) {
const u = i / tubularSegments * 2 * Math.PI;
const cosU = Math.cos(u);
const sinU = Math.sin(u);
const x = (radius + tube * cosV) * cosU;
const y = tube * sinV;
const z = (radius + tube * cosV) * sinU;
positions.push(x, y, z);
}
}
for(let j = 0; j < radialSegments; j++) {
for(let i = 0; i < tubularSegments; i++) {
const a = (tubularSegments + 1) * j + i;
const b = (tubularSegments + 1) * (j + 1) + i;
const c = b + 1;
const d = a + 1;
indices.push(a, b, d);
indices.push(b, c, d);
}
}
return {
positions: new Float32Array(positions),
indices: new Uint16Array(indices)
};
}
// 5. Create shaders
function createShaderModule(device) {
return device.createShaderModule({
code: `
struct Uniforms {
mvpMatrix : mat4x4<f32>
};
@group(0) @binding(0) var<uniform> uniforms : Uniforms;
struct VertexOutput {
@builtin(position) Position : vec4<f32>,
@location(0) color : vec3<f32>
};
@vertex
fn vs_main(@location(0) position : vec3<f32>) -> VertexOutput {
var output : VertexOutput;
output.Position = uniforms.mvpMatrix * vec4<f32>(position, 1.0);
output.color = (position + vec3<f32>(0.5, 0.5, 0.5));
return output;
}
@fragment
fn fs_main(@location(0) color : vec3<f32>) -> @location(0) vec4<f32> {
return vec4<f32>(color, 1.0);
}
`
});
}
// Main program
async function main() {
const { device, context, format } = await initWebGPU();
// Interaction state
let rotationX = 0, rotationY = 0;
let isDragging = false;
let lastMouseX = 0, lastMouseY = 0;
canvas.addEventListener('mousedown', e => {
isDragging = true;
lastMouseX = e.clientX;
lastMouseY = e.clientY;
});
window.addEventListener('mouseup', () => { isDragging = false; });
window.addEventListener('mousemove', e => {
if (!isDragging) return;
const dx = (e.clientX - lastMouseX) * 0.005;
const dy = (e.clientY - lastMouseY) * 0.005;
rotationY += dx;
rotationX += dy;
lastMouseX = e.clientX;
lastMouseY = e.clientY;
});
// Render loop
function render() {
// Update canvas size and configure context
canvas.width = canvas.clientWidth * devicePixelRatio;
canvas.height = canvas.clientHeight * devicePixelRatio;
context.configure({
device,
format,
alphaMode: 'opaque',
size: [canvas.width, canvas.height],
});
updateDepthTexture();
passEncoder.setPipeline(pipeline);
passEncoder.setBindGroup(0, bindGroup);
passEncoder.setVertexBuffer(0, obj.buffers.vertexBuffer);
passEncoder.setIndexBuffer(obj.buffers.indexBuffer, 'uint16');
passEncoder.drawIndexed(obj.buffers.indexCount);
}
passEncoder.end();
device.queue.submit([commandEncoder.finish()]);
requestAnimationFrame(render);
}
info.innerHTML = `
Total triangles: ${totalTriangles}<br>
Estimated hidden triangles: ${hiddenTriangles} (${(hiddenRatio *
100).toFixed(1)}%)<br>
Estimated data saved by removing hidden surfaces: ~${savedBytes} bytes<br>
<br>
<em>Controls:</em><br>
Drag mouse to rotate scene<br>
Arrow Up/Down to zoom
`;
lastReport = timestamp;
}
requestAnimationFrame(reportStats);
}
// Start loops
render();
requestAnimationFrame(reportStats);
}
initWebGPU().then(main);
</script>
</body>
</html>
Detailed Explanation
1. WebGPU Initialization
2. Geometry Creation
4. Interaction
5. Rendering
• On each frame:
o Update canvas size and depth texture if changed.
o Compute projection and view matrices.
o For each object:
▪ Compute model matrix (object position).
▪ Calculate MVP matrix and upload it to GPU uniform buffer.
▪ Issue draw call.
• Submit command buffer for execution.
6. Statistics Reporting