WebGL - Warna: Panduan Pemula untuk Menambahkan Kehidupan ke Grafik 3D Anda
Hai teman-teman, penggemar WebGL yang bersemangat! Saya sangat senang menjadi panduan Anda dalam perjalanan warna-warna ini melalui dunia WebGL. Sebagai seseorang yang telah mengajar grafik komputer selama lebih dari satu dekade, saya bisa katakan bahwa menambahkan warna ke scene 3D Anda seperti memberikan kehidupan kepada sebuah foto hitam putih. Itu magis, dan hari ini, kita akan membuka keajaiban itu bersama!
Mengerti Warna di WebGL
Sebelum kita memasuki hal-hal teknis tentang penambahan warna, mari kitaah kita sedikit untuk memahami apa arti warna dalam konteks WebGL. Dalam realm digital ini, warna direpresentasikan menggunakan model warna RGB (Merah, Hijau, Biru). Setiap warna adalah kombinasi dari tiga warna primer ini, dengan nilai berada dalam rentang 0.0 hingga 1.0.
Misalnya:
- Merah: (1.0, 0.0, 0.0)
- Hijau: (0.0, 1.0, 0.0)
- Biru: (0.0, 0.0, 1.0)
- Putih: (1.0, 1.0, 1.0)
- Hitam: (0.0, 0.0, 0.0)
Pertimbangkan hal ini seperti mencampur cat, tapi dengan cahaya bukannya pigmen. Itu seperti menjadi seorang seniman digital dengan palet tak terbatas di ujung jari Anda!
Menambahkan Warna di WebGL
Sekarang kita telah memahami dasar-dasar, mari kita mulai menambahkan warna di WebGL.
Langkah untuk Menambahkan Warna
- Definisikan atribut warna di shader vertex Anda
- Kirim data warna dari kode JavaScript Anda
- Gunakan warna di shader fragment Anda
mari kitauraikan langkah ini dengan beberapa contoh kode.
Langkah 1: Definisikan Atribut Warna di Shader Vertex
Pertama, kita perlu memberitahu shader vertex bahwa kita akan bekerja dengan warna. Berikut cara kita melakukannya:
attribute vec4 a_Position;
attribute vec4 a_Color;
varying vec4 v_Color;
void main() {
gl_Position = a_Position;
v_Color = a_Color;
}
Dalam kode ini, kita mendefinisikan atribut a_Color
untuk menerima data warna, dan variabel v_Color
untuk mengirimkan warna ke shader fragment. Itu seperti membuat saluran warna dari kode JavaScript kita hingga piksel kita!
Langkah 2: Kirim Data Warna dari JavaScript
Sekarang, kita perlu mengirimkan data warna dari kode JavaScript kita ke shader. Berikut contoh bagaimana kita dapat melakukannya:
// Definisikan vertices dan warna
var vertices = new Float32Array([
0.0, 0.5, 1.0, 0.0, 0.0, // Vertex 1: x, y, r, g, b
-0.5,-0.5, 0.0, 1.0, 0.0, // Vertex 2: x, y, r, g, b
0.5,-0.5, 0.0, 0.0, 1.0 // Vertex 3: x, y, r, g, b
]);
// Buat buffer dan kirim data kepadanya
var vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
// Beritahu WebGL bagaimana membaca buffer
var FSIZE = vertices.BYTES_PER_ELEMENT;
var a_Position = gl.getAttribLocation(program, 'a_Position');
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, FSIZE * 5, 0);
gl.enableVertexAttribArray(a_Position);
var a_Color = gl.getAttribLocation(program, 'a_Color');
gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, FSIZE * 5, FSIZE * 2);
gl.enableVertexAttribArray(a_Color);
Kode ini mungkin terlihat menakutkan pertama kalinya, tapi mari kitauraikan:
- Kita mendefinisikan vertex dan warna dalam sebuah array tunggal. Setiap vertex memiliki 5 nilai: x, y, r, g, b.
- Kita buat buffer dan mengirimkan data kita kepadanya.
- Kita memberitahu WebGL bagaimana membaca buffer ini, baik untuk posisi (2 nilai pertama) maupun warna (3 nilai terakhir).
Itu seperti mempack suitcase dengan pakaian dan peralatan, dan kemudian memberitahu teman Anda bagaimana mempergiatnya!
Langkah 3: Gunakan Warna di Shader Fragment
Akhirnya, kita gunakan warna di shader fragment:
precision mediump float;
varying vec4 v_Color;
void main() {
gl_FragColor = v_Color;
}
Shader ini mengambil warna yang kita kirim dari shader vertex dan menerapkannya ke fragment (piksel). Itu langkah terakhir dalam perjalanan warna kita, tempat warna akhirnya bersinar di layar!
Contoh – Menambahkan Warna
Mari kita gabungkan semua ini dengan sebuah contoh lengkap. Kita akan membuat sebuah segitiga berwarna menggunakan kode yang kita diskusikan.
<!DOCTYPE html>
<html>
<head>
<title>Segitiga WebGL Berwarna</title>
</head>
<body>
<canvas id="glCanvas" width="640" height="480"></canvas>
<script>
// Shader program vertex
const vsSource = `
attribute vec4 a_Position;
attribute vec4 a_Color;
varying vec4 v_Color;
void main() {
gl_Position = a_Position;
v_Color = a_Color;
}
`;
// Shader program fragment
const fsSource = `
precision mediump float;
varying vec4 v_Color;
void main() {
gl_FragColor = v_Color;
}
`;
function main() {
const canvas = document.querySelector("#glCanvas");
const gl = canvas.getContext("webgl");
if (!gl) {
alert("Tidak dapat menginisialisasi WebGL. Browser atau mesin Anda mungkin tidak mendukungnya.");
return;
}
// Inisialisasi program shader
const shaderProgram = initShaderProgram(gl, vsSource, fsSource);
// Dapatkan lokasi atribut
const programInfo = {
program: shaderProgram,
attribLocations: {
vertexPosition: gl.getAttribLocation(shaderProgram, 'a_Position'),
vertexColor: gl.getAttribLocation(shaderProgram, 'a_Color'),
},
};
// Buat buffer
const buffers = initBuffers(gl);
// Gambar scene
drawScene(gl, programInfo, buffers);
}
function initBuffers(gl) {
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
const positions = [
0.0, 0.5, 1.0, 0.0, 0.0,
-0.5, -0.5, 0.0, 1.0, 0.0,
0.5, -0.5, 0.0, 0.0, 1.0,
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
return {
position: positionBuffer,
};
}
function drawScene(gl, programInfo, buffers) {
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.useProgram(programInfo.program);
{
const numComponents = 2; //ambil 2 nilai per iterasi
const type = gl.FLOAT; //data di buffer adalah float 32bit
const normalize = false; //jangan normalisasi
const stride = 20; //berapa byte untuk mendapatkan dari satu set nilai ke yang berikutnya
const offset = 0; //berapa byte di dalam buffer untuk mulai
gl.bindBuffer(gl.ARRAY_BUFFER, buffers.position);
gl.vertexAttribPointer(
programInfo.attribLocations.vertexPosition,
numComponents,
type,
normalize,
stride,
offset);
gl.enableVertexAttribArray(
programInfo.attribLocations.vertexPosition);
}
{
const numComponents = 3;
const type = gl.FLOAT;
const normalize = false;
const stride = 20;
const offset = 8;
gl.vertexAttribPointer(
programInfo.attribLocations.vertexColor,
numComponents,
type,
normalize,
stride,
offset);
gl.enableVertexAttribArray(
programInfo.attribLocations.vertexColor);
}
gl.drawArrays(gl.TRIANGLES, 0, 3);
}
function initShaderProgram(gl, vsSource, fsSource) {
const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource);
const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource);
const shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
alert('Tidak dapat menginisialisasi program shader: ' + gl.getProgramInfoLog(shaderProgram));
return null;
}
return shaderProgram;
}
function loadShader(gl, type, source) {
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert('Terjadi kesalahan kompilasi shader: ' + gl.getShaderInfoLog(shader));
gl.deleteShader(shader);
return null;
}
return shader;
}
window.onload = main;
</script>
</body>
</html>
Ketika Anda menjalankan kode ini, Anda akan melihat sebuah segitiga yang indah dengan titik warna merah, hijau, dan biru. Itu seperti melihat彩虹 hidup di layar Anda!
Kesimpulan
Dan begitu, teman-teman! Kita telah melintasi dunia warna-warna WebGL, dari memahami bagaimana warna direpresentasikan hingga menerapkannya ke grafik 3D kita. Ingat, ini hanya permulaan. Dengan dasar-dasar ini di punggung Anda, Anda sudah siap untuk menciptakan grafik 3D yang menakjubkan dan berwarna.
Saat kita berakhir, saya teringat sebuah murid yang pernah mengatakan bahwa belajar warna di WebGL seperti belajar menggambar dengan cahaya. Dan Anda tahu apa? Dia benar. Jadi, teruslah maju, teman-teman saya, dan lukis kanvas digital Anda dengan semua warna angin (ya, itu referensi Disney, dan tidak, saya tidak merasa malu tentangnya!).
Selamat coding, dan may your WebGL adventures always be colorful!
Credits: Image by storyset