
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!
Leave a Reply