Setelah di Part 2 kita bongkar bagaimana Basemark menggunakan WebGL 2.0 untuk melakukan pengujian performa, sekarang waktunya kita bikin versi buatan sendiri, Geometry Stress Test berbasis WebGPU.
Tujuan artikel atau tutorial kali ini adalah:
Menggambar ribuan segitiga acak di layar dan mengukur seberapa cepat GPU kamu menyelesaikannya.
▶️ Konsep Stress Test
Kita akan menggunakan WebGPU sebagai alat stress test rendering, dengan membebani GPU langsung dari browser dan menyuruhnya menggambar ribuan vertex segitiga secara acak.
Logika dasarnya:
- Buat
N
segitiga acak di koordinat NDC (-1…+1). Keterangan: NDC adalah Normalized Device Coordinates, atau istilahnya sistem koordinat di dunia grafik komputer. - Render semuanya dalam satu pass.
- Ukur waktu render.
- Hitung operations per second (Ops/sec).
Output akhirnya semacam ini:
✅ WebGPU aktif
GPU: ANGLE (Apple, ANGLE Metal Renderer: Apple M1, Unspecified Version) - (Google Inc. (Apple))
🎨 Geometry Stress Test selesai
Triangles : 10
Vertices : 30
GPU Time (ms) : 65.500
Ops/Second : 916
Backend : WebGPU (bgra8unorm)
▶️ Demo & Implementasi
Demo langsung bisa dicoba disini:
File yang digunakan:
- tests/geometry-test/
└─ test-geometri.js
1. Menyiapkan Data Geometri
Pada file test-geometri.js
,
// file test-geometri.js
const triCount = 10000; // jumlah segitiga
const vertexCount = triCount * 3;
const vertexData = new Float32Array(vertexCount * 2);
for (let i = 0; i < vertexData.length; i++) {
vertexData[i] = Math.random() * 2 - 1; // posisi acak di layar (-1 s.d 1)
}
const vertexBuffer = device.createBuffer({
size: vertexData.byteLength,
usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
});
device.queue.writeBuffer(vertexBuffer, 0, vertexData);
Di bagian ini:
- Kita mengirim data vertex (titik sudut 2D) ke GPU buffer agar bisa dirender.
- Membuat ribuan segitiga acak di ruang NDC (Normalized Device Coordinates).
- Setiap vertex memiliki 2 nilai (
x
,y
).
2. Siapkan Shader Pipeline
const shader = /* wgsl */ `
@vertex
fn vs_main(@location(0) pos: vec2f) -> @builtin(position) vec4f {
return vec4f(pos * 0.9, 0.0, 1.0); // sedikit diskalakan
}
@fragment
fn fs_main() -> @location(0) vec4f {
return vec4f(0.3, 0.7, 1.0, 1.0); // warna biru muda
}
`;
const pipeline = device.createRenderPipeline({
layout: "auto",
vertex: {
module: device.createShaderModule({ code: shader }),
entryPoint: "vs_main",
buffers: [
{
arrayStride: 8,
attributes: [{ shaderLocation: 0, offset: 0, format: "float32x2" }],
},
],
},
fragment: {
module: device.createShaderModule({ code: shader }),
entryPoint: "fs_main",
targets: [{ format }],
},
primitive: { topology: "triangle-list", cullMode: "none" },
});
Ini adalah core dari geometry-test, dimana kita menggunakan
wgsl
untuk membuat gambar segitiga. Code tersebut mencakup beberapa hal, yakni:
- Menentukan shader untuk vertex dan fragment (mengatur posisi & warna) pada
const shader
. (Menggunakanwgsl
)
- Membuat render pipeline melalui
createRenderPipeline
yang akan digunakan untuk menggambar semua segitiga.
arrayStride: 8
artinya setiap vertex punya dua angka float (2 × 4 byte).
3. Menjalankan Render & Mengukur Waktu
const start = performance.now();
const encoder = device.createCommandEncoder();
const pass = encoder.beginRenderPass({
colorAttachments: [
{
view: context.getCurrentTexture().createView(),
clearValue: [0.05, 0.05, 0.07, 1.0],
loadOp: "clear",
storeOp: "store",
},
],
});
pass.setPipeline(pipeline);
pass.setVertexBuffer(0, vertexBuffer);
pass.draw(vertexCount);
pass.end();
device.queue.submit([encoder.finish()]);
await device.queue.onSubmittedWorkDone();
const end = performance.now();
const gpuTime = (end - start).toFixed(3);
Di bagian akhir
geometry-test.js
, kita melakukan langkah finalisasi untuk:
- Memulai render dan membersihkan layar.
- Menjalankan pipeline untuk menggambar seluruh segitiga sekaligus.
- Mengukur waktu dari submit hingga selesai (perkiraan waktu render GPU).
▶️ Kesimpulan
Dari test geometry diatas kita dapat menyimpulkan beberapa hal:
- WebGPU mampu menggambar ribuan segitiga primitif dengan latency sangat rendah karena pipeline dan command encoder-nya langsung memetakan perintah ke API GPU native (Metal/Vulkan/D3D12).
- Dalam tes nyata, perbedaan performa antara WebGL 2 vs WebGPU bisa mencapai 2–5× tergantung arsitektur GPU.
Bagian selanjutnya: kita akan mencoba membuat Compute Pass WebGPU untuk simulasi fisika ringan, semacam “stress test + mini AI simulation” versi browser. Thanks & Stay tuned!