WebGL Konsep
WebGL (Web Graphics Library) adalah API JavaScript untuk merender grafik 2D dan 3D langsung di browser menggunakan GPU (Graphics Processing Unit). WebGL berbasis OpenGL ES dan memberikan akses langsung ke hardware grafis.
Mengapa WebGL?
Canvas 2D context menggambar menggunakan CPU. Untuk ribuan objek atau 3D, CPU menjadi bottleneck. WebGL memanfaatkan GPU yang dirancang khusus untuk operasi grafis paralel.
| Canvas 2D | WebGL | |
|---|---|---|
| Hardware | CPU | GPU |
| Dimensi | 2D | 2D & 3D |
| Kecepatan | OK untuk ratusan objek | Jutaan poligon |
| Kompleksitas | Mudah | Sangat kompleks |
| Use case | UI, grafik sederhana | Game, 3D, efek visual berat |
GPU Rendering Pipeline
WebGL memproses grafik melalui pipeline (jalur pemrosesan) yang terdiri dari beberapa tahap:
Vertex Data → Vertex Shader → Rasterization → Fragment Shader → Frame Buffer → Layar
- Vertex Data — titik-titik (vertices) yang membentuk geometri. Sebuah segitiga punya 3 vertex.
- Vertex Shader — program yang berjalan di GPU, memproses SETIAP vertex. Menentukan posisi akhir vertex di layar.
- Rasterization — GPU menentukan piksel mana yang berada di dalam geometri.
- Fragment Shader — program yang berjalan di GPU, menentukan warna SETIAP piksel (fragment).
- Frame Buffer — hasil akhir yang ditampilkan di layar.
Vertex Shader & Fragment Shader
Shader ditulis dalam GLSL (OpenGL Shading Language), bahasa yang mirip C:
// Vertex Shader — dijalankan 1x per vertex
attribute vec4 a_position; // koordinat vertex dari JS
attribute vec3 a_color; // warna per-vertex dari JS
varying vec3 v_color; // kirim ke fragment shader
void main() {
gl_Position = a_position; // set posisi vertex di clip space
v_color = a_color; // oper warna — GPU interpolasi otomatis
}
// Fragment Shader — dijalankan 1x per piksel
precision mediump float;
uniform float u_time; // waktu (detik) dari JS, untuk animasi
varying vec3 v_color; // warna yang di-interpolasi dari vertex shader
void main() {
// Gradasi warna yang berdenyut mengikuti waktu
float pulse = 0.5 + 0.5 * sin(u_time * 2.0); // 0..1 sine wave
vec3 finalColor = v_color * pulse;
gl_FragColor = vec4(finalColor, 1.0); // rgba: warna * alpha
}
Di atas, vertex shader menerima posisi + warna, lalu mengoper warna ke fragment shader via varying. GPU otomatis meng-interpolasi nilai varying antar 3 vertex segitiga — jadi kalau 3 vertex merah/hijau/biru, piksel di tengahnya dapat warna transisi. Fragment shader kemudian memodulasi warna dengan sin(u_time) untuk efek berdenyut.
Tipe variabel GLSL:
attribute— input per-vertex (posisi, warna, normal). Hanya di vertex shader.uniform— input konstan untuk semua vertex/fragment di satu draw call (warna, matrix, waktu).varying— data yang di-pass dari vertex shader ke fragment shader, otomatis di-interpolasi.vec2,vec3,vec4— vektor 2D, 3D, 4D.mat4— matrix 4x4 (untuk transformasi 3D).
Kunci intuisi: vertex shader mengatur di mana piksel digambar, fragment shader mengatur warna apa tiap piksel. Dua program kecil ini berjalan paralel jutaan kali per frame — itulah kenapa GPU jauh lebih cepat dari CPU untuk grafis.
Setup WebGL Dasar
const canvas = document.getElementById("myCanvas");
const gl = canvas.getContext("webgl");
if (!gl) {
console.error("WebGL tidak didukung di browser ini");
}
// Compile shader
function createShader(gl, type, source) {
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
console.error(gl.getShaderInfoLog(shader));
gl.deleteShader(shader);
return null;
}
return shader;
}
// Buat program dari vertex + fragment shader
function createProgram(gl, vertexShader, fragmentShader) {
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
console.error(gl.getProgramInfoLog(program));
return null;
}
return program;
}
Menggambar Segitiga (Hello World WebGL)
// Shader source
const vsSource = `
attribute vec2 a_position;
void main() {
gl_Position = vec4(a_position, 0.0, 1.0);
}
`;
const fsSource = `
precision mediump float;
void main() {
gl_FragColor = vec4(0.2, 0.6, 1.0, 1.0); // biru
}
`;
// Setup
const vs = createShader(gl, gl.VERTEX_SHADER, vsSource);
const fs = createShader(gl, gl.FRAGMENT_SHADER, fsSource);
const program = createProgram(gl, vs, fs);
// Data vertex — 3 titik segitiga
// Koordinat WebGL: -1 sampai 1
const vertices = new Float32Array([
0.0, 0.5, // atas
-0.5, -0.5, // kiri bawah
0.5, -0.5, // kanan bawah
]);
// Kirim data ke GPU
const buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
// Hubungkan buffer ke attribute
const posLocation = gl.getAttribLocation(program, "a_position");
gl.enableVertexAttribArray(posLocation);
gl.vertexAttribPointer(posLocation, 2, gl.FLOAT, false, 0, 0);
// Gambar!
gl.useProgram(program);
gl.clearColor(0.1, 0.1, 0.1, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, 3);
Mengapa WebGL Cepat?
GPU menjalankan shader secara paralel untuk semua vertex/piksel sekaligus. Jika kamu punya 1 juta piksel, GPU bisa memproses ribuan piksel bersamaan — berbeda dengan CPU yang memproses satu per satu secara sequential.
Realita: Gunakan Library
WebGL langsung sangat verbose dan kompleks. Dalam praktik, developer menggunakan library:
- Three.js — library 3D paling populer (kita pelajari selanjutnya!)
- PixiJS — library 2D berbasis WebGL, sangat cepat
- Babylon.js — alternatif Three.js dengan fitur lebih lengkap
- Regl — wrapper WebGL yang minimalis
Memahami konsep WebGL penting agar kamu tahu apa yang terjadi di balik layar saat menggunakan library-library tersebut.