Pembahasan Singkat WebGL - CRUDPRO

Pembahasan Singkat WebGL

Dalam posting ini, saya akan membahas pengantar singkat tentang WebGL untuk siapa saja yang ingin memulai dengan grafik web 3D. Jelaskan cara kerja pipa rendering dan buat grafik sederhana sebagai contoh.

Apa itu WebGL

WebGL adalah API bebas royalti lintas platform yang digunakan untuk membuat grafik 3D di browser web. Berdasarkan OpenGL ES 2.0, WebGL menggunakan bahasa shading OpenGL GLSL dan akrab dengan OpenGL API standar.

Fitur utama WebGL adalah:

  • Lintas platform dan lintas browser
  • Akselerasi GPU3D
  • API asli untuk mendukung GLSL
  • Bekerja di canvas
  • Integrasi dengan antarmuka DOM

Cara Penggunaan

Untuk merender beberapa grafik, Anda perlu mempelajari apa itu pipeline rendering dan cara kerjanya.

Pipeline rendering adalah serangkaian tahapan yang dilakukan WebGL saat merender grafik 3D. Model rendering ini sangat cocok karena GPU adalah prosesor yang sangat paralel. Tahap pipa berjalan secara bersamaan di unit pemrosesan GPU.

Pada gambar berikut Anda dapat melihat tahapan rendering pipeline.

Keluaran dari satu tahap digunakan sebagai masukan untuk tahap berikutnya. Tahapan VertexShader dan FragmentShader dapat diprogram, sehingga Anda dapat memprogram tahapan Anda sendiri.

Shader vertex menangani pemrosesan vertex grafik. Pada tahap ini, Anda perlu menyediakan aliran yang berisi simpul. Shader simpul kemudian menerima satu simpul dari aliran ini dan menghasilkan satu simpul dalam aliran simpul keluaran. Pemetaan 1: 1 dari simpul input ke simpul keluaran diperlukan. Ini adalah tahap di mana Anda dapat menerapkan transformasi simpul seperti rotasi, translasi, dan penskalaan.

Fragmen shader memproses fragmen yang dihasilkan oleh tahap rasterisasi menjadi satu set warna dan satu nilai kedalaman. Ini adalah tahap setelah primitif diraster (pada tahap rasterisasi, primitif geometris diubah menjadi fragmen yang terkait dengan area piksel). Sebuah "fragmen" dihasilkan untuk setiap sampel piksel yang dicakup oleh primitif. Setiap fragmen memiliki posisi ruang jendela dan beberapa nilai lainnya, dan berisi semua nilai keluaran per simpul yang diinterpolasi dari tahap pemrosesan simpul terakhir. Ini adalah tahap di mana Anda dapat menerapkan warna dan tekstur pada grafik Anda.

Bagian selanjutnya menunjukkan cara membuat segitiga sederhana sebagai contoh. Untuk melakukan ini, programkan shader Vertex dan Fragmend.

Render segitiga di WebGL

Seperti yang disebutkan sebelumnya, kita perlu mendefinisikan kanvas di dalamnya untuk merender grafik, jadi buatlah template HTML sederhana seperti ini:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8" />
    <title>WebGL Sample Triangle</title>
    <meta name="author" content="Martín Lamas" />
    <meta name="description" content="WebGL Triangle" />
</head>

<body>
    <canvas id="canvas" width="600" height="600"></canvas>
    <script>
      // We will put our WebGL code here
    </script>
</body>

</html>

Atribut lebar dan tinggi kanvas menentukan ukuran area pandang, tetapi ada beberapa pertimbangan yang perlu dipertimbangkan. WebGL mengharapkan semua simpul yang ditampilkan berada dalam koordinat perangkat yang dinormalisasi setelah menjalankan setiap shader simpul. Artinya, koordinat x, y, dan z dari setiap simpul harus antara -1.0 dan 1.0. Koordinat di luar rentang ini tidak akan ditampilkan. Koordinat perangkat dan ukuran viewport yang dinormalisasi ini diteruskan ke rasterizer dan dikonversi ke koordinat / piksel 2D di layar, jadi Anda perlu mempertimbangkan ukuran viewport dan rasio aspeknya.

Untuk menyederhanakan contoh ini, kita akan menggunakan kanvas persegi. Seperti yang ditunjukkan pada gambar di bawah, kita perlu mendefinisikan tiga simpul untuk membuat segitiga.

Bagian skrip pertama-tama mendeklarasikan array simpul.

const vertices = new Float32Array([
   0.0,  0.5, 0.0, // First vertex
  -0.5, -0.5, 0.0, // Second vertex
   0.5, -0.5, 0.0  // Third vertex
]);

Karena kita menggambar dalam 2D, kita perlu melewati koordinat z. Selanjutnya, inisialisasi konteks dan pertama-tama tentukan vertex shader.

const gl = document.getElementById("canvas").getContext("webgl");

// Vertex shader
const vertexShader = `
    attribute vec4 position;
    void main() {
        gl_Position = position;
    }`;

Seperti yang kita pelajari sebelumnya, vertex shader berjalan pada setiap vertex input dan menghasilkan vertex baru sebagai output. Contoh ini menggunakan atribut position sebagai input (atribut tersebut adalah input ke Vertex Shader yang mendapatkan data dari buffer, yang akan kita bahas lebih detail nanti) dan menempatkan output dalam variabel gl_Position (bawaan). Variabel gl_Position menampung output). Vertex shader simpul). Tidak ada konversi yang dilakukan, sehingga simpul keluaran sama dengan simpul masukan. Kami akan segera menunjukkan kepada Anda bagaimana menginisialisasi buffer menggunakan array simpul input.

Selanjutnya, tentukan shader fragmen.
// Fragment shader
const fragmentShader = `
    precision mediump float;
    uniform vec4 color;
    void main() {
        gl_FragColor = color;
    }`;

Kami menggunakan seragam yang mempertahankan warna fragmen (seragam tetap sama untuk semua simpul dalam satu panggilan undian). Seperti Vertex Shader, variabel gl_FragColor bawaan menyimpan warna keluaran shader. Seperti yang Anda lihat, tidak ada konversi warna.

Terakhir, kompilasi shader ini sehingga GPU dapat menjalankannya, dan tentukan program WebGL yang melampirkan shader ini ke dalamnya.

// Compile vertex shader
const vs = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vs, vertexShader);
gl.compileShader(vs);

// Compile fragment shader
const fs = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fs, fragmentShader);
gl.compileShader(fs);

// Create and initialize the WebGL program
const program = gl.createProgram();
gl.attachShader(program, vs);
gl.attachShader(program, fs);
gl.linkProgram(program);
gl.useProgram(program);

Setelah mendefinisikan dan mengkompilasi shader ini, kita perlu menyediakan data input untuk segitiga.

Pertama, buat buffer array dan isi dengan koordinat titik. VertexShader yang ditentukan sebelumnya menggunakan buffer ini sebagai input melalui atribut position. Untuk melakukannya, gunakan metode gl.createBuffer untuk membuat buffer dan mengikatnya sebagai jenis gl.ARRAY_BUFFER. Kemudian gunakan metode gl.bufferData untuk mengisi buffer ini. Terakhir, arahkan atribut position ke buffer dan panggil serta ikat masing-masing metode gl.vertexAttribPointer dan gl.enableVertexAttribArray.

// Shader attribute variable for position
const position = gl.getAttribLocation(program, "position");

// Create the GPU array buffer with the vertices
const buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
gl.vertexAttribPointer(
  position, // Target
  3,        // Chunk size (send the values 3 by 3)
  gl.FLOAT, // Type
  false,    // Normalize
  0,        // Stride
  0         // Offset
);
gl.enableVertexAttribArray(position);

Kemudian gunakan metode gl.uniform4f untuk menentukan warna dan meneruskannya ke shader fragmen melalui seragam warna.

// Shader uniform variable for color (read-only)
const color = gl.getUniformLocation(program, "color");

// Set color        R  G  B  A
gl.uniform4f(color, 0, 1, 0, 1);

Perhatikan bahwa koordinat warna harus ditentukan menggunakan koordinat perangkat yang dinormalisasi, jadi gunakan rumus berikut untuk menghitung setiap koordinat. Koordinat ternormalisasi RGBA = Koordinat RGBA / 255.

Pada titik ini, Anda memiliki semua yang Anda butuhkan untuk membuat segitiga. Kemudian bersihkan latar belakang kanvas dan panggil metode gl.drawArrays untuk merender segitiga.

// Set the clear color
gl.clearColor(0.0, 0.0, 0.0, 1.0);

// Clear canvas
gl.clear(gl.COLOR_BUFFER_BIT);

// Render
gl.drawArrays(
  gl.TRIANGLES, // Mode
  0,            // Start
  3             // Count
);

Metode gl.drawArrays menggunakan buffer array terbatas sebagai data input. Dalam contoh ini, tiga simpul diambil dari buffer dan mode gl.TRIANGLES dipilih untuk merender bentuk. Bentuk berikut tersedia di WebGL:

Seperti yang Anda lihat, Anda dapat merender gambar rangka segitiga hanya dengan mengganti mode dengan nilai gl.LINE_LOOP.

Terakhir, Anda dapat melihat segitiga yang membuka template di browser web Anda. Sesuatu seperti dibawah

Ringkasan

Saat ini, WebGL API tersedia di sebagian besar browser web. Anda dapat menggunakannya untuk merender grafik 2D dan 3D yang dipercepat di aplikasi web Anda. Beberapa library tingkat tinggi dibangun di atas WebGL API, sehingga memudahkan programmer untuk bekerja dengannya. Namun, menarik untuk mempelajari API WebGL tingkat rendah dan cara kerja pipeline rendering.

Dalam posting mendatang, saya akan menunjukkan cara membuat bentuk 3D dan menerapkan transformasi seperti rotasi dan terjemahan. Kita juga akan melihat bagaimana menerapkan tekstur dan melihat beberapa perpustakaan menarik yang bekerja di WebGL.