WebGL - Geometri

Setelah mendapatkan konteks WebGL, Anda harus menentukan geometri untuk primitif (objek yang ingin Anda gambar) dan menyimpannya. Di WebGL, kami mendefinisikan detail geometri - misalnya, simpul, indeks, warna primitif - menggunakan larik JavaScript. Untuk meneruskan detail ini ke program shader, kita harus membuat objek buffer dan menyimpan (melampirkan) array JavaScript yang berisi data di buffer masing-masing.

Note: Nantinya, objek buffer ini akan dikaitkan dengan atribut program shader (vertex shader).

Mendefinisikan Geometri yang Dibutuhkan

Model 2D atau 3D yang digambar menggunakan simpul disebut a mesh. Setiap faset dalam jaring elemen disebut apolygon dan poligon terbuat dari 3 atau lebih simpul.

Untuk menggambar model dalam konteks rendering WebGL, Anda harus menentukan simpul dan indeks menggunakan array JavaScript. Misalnya, jika kita ingin membuat segitiga yang terletak pada koordinat {(5,5), (-5,5), (-5, -5)} seperti yang ditunjukkan pada diagram, maka Anda dapat membuat array untuk simpul sebagai -

var vertices = [
   0.5,0.5,    //Vertex 1
   0.5,-0.5,   //Vertex 2
   -0.5,-0.5,  //Vertex 3
];

Demikian pula, Anda dapat membuat array untuk indeks. Indeks untuk indeks segitiga di atas akan menjadi [0, 1, 2] dan dapat didefinisikan sebagai -

var indices = [ 0,1,2 ]

Untuk pemahaman yang lebih baik tentang indeks, pertimbangkan model yang lebih kompleks seperti persegi. Kita dapat merepresentasikan sebuah persegi sebagai himpunan dua segitiga. Jika (0,3,1) dan (3,1,2) adalah dua segitiga yang akan kita gunakan untuk menggambar persegi, maka indeks akan didefinisikan sebagai -

var indices = [0,3,1,3,1,2];

Note -

Untuk menggambar primitif, WebGL menyediakan dua metode berikut -

  • drawArrays() - Saat menggunakan metode ini, kami meneruskan simpul dari primitif menggunakan array JavaScript.

  • drawElements() - Saat menggunakan metode ini, kami meneruskan simpul dan indeks primitif menggunakan larik JavaScript.

Objek Penyangga

Objek buffer adalah mekanisme yang disediakan oleh WebGL yang menunjukkan area memori yang dialokasikan dalam sistem. Dalam objek buffer ini, Anda dapat menyimpan data model yang ingin Anda gambar, sesuai dengan simpul, indeks, warna, dll.

Dengan menggunakan objek buffer ini, Anda dapat meneruskan beberapa data ke program shader (vertex shader) melalui salah satu variabel atributnya. Karena objek buffer ini berada di memori GPU, mereka dapat dirender secara langsung, yang pada akhirnya meningkatkan kinerja.

Untuk memproses geometri, ada dua jenis objek penyangga. Mereka adalah -

  • Vertex buffer object (VBO)- Ini menyimpan data per-vertex dari model grafis yang akan diberikan. Kami menggunakan objek penyangga simpul di WebGL untuk menyimpan dan memproses data mengenai simpul seperti koordinat simpul, normal, warna, dan koordinat tekstur.

  • Index buffer objects (IBO) - Ini menyimpan indeks (data indeks) dari model grafis yang akan diberikan.

Setelah menentukan geometri yang diperlukan dan menyimpannya dalam array JavaScript, Anda perlu meneruskan array ini ke objek buffer, dari situ data akan diteruskan ke program shader. Langkah-langkah berikut harus diikuti untuk menyimpan data di buffer.

  • Buat buffer kosong.

  • Ikat objek larik yang sesuai ke buffer kosong.

  • Meneruskan data (simpul / indeks) ke buffer menggunakan salah satu file typed arrays.

  • Lepaskan buffer (Opsional).

Membuat Buffer

Untuk membuat objek buffer kosong, WebGL menyediakan metode yang disebut createBuffer(). Metode ini mengembalikan objek buffer yang baru dibuat, jika pembuatan berhasil; selain itu mengembalikan nilai nol jika terjadi kegagalan.

WebGL beroperasi sebagai mesin negara. Setelah buffer dibuat, operasi buffer berikutnya akan dijalankan pada buffer saat ini sampai kita melepaskannya. Gunakan kode berikut untuk membuat buffer -

var vertex_buffer = gl.createBuffer();

Note - gl adalah variabel referensi ke konteks WebGL saat ini.

Ikat Buffer

Setelah membuat objek buffer kosong, Anda perlu mengikat buffer array yang sesuai (target) padanya. WebGL menyediakan metode yang disebutbindBuffer() untuk tujuan ini.

Sintaksis

Sintaks dari bindBuffer() metode adalah sebagai berikut -

void bindBuffer (enum target, Object buffer)

Metode ini menerima dua parameter dan dibahas di bawah ini.

target- Variabel pertama adalah nilai enum yang mewakili jenis buffer yang ingin kita ikat ke buffer kosong. Anda memiliki dua nilai enum yang telah ditentukan sebagai opsi untuk parameter ini. Mereka adalah -

  • ARRAY_BUFFER yang mewakili data titik.

  • ELEMENT_ARRAY_BUFFER yang mewakili data indeks.

Object buffer- Yang kedua adalah variabel referensi ke objek penyangga yang dibuat pada langkah sebelumnya. Variabel referensi dapat berupa objek penyangga simpul atau objek penyangga indeks.

Contoh

Potongan kode berikut menunjukkan bagaimana menggunakan metode bindBuffer ().

//vertex buffer
var vertex_buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);

//Index buffer
var Index_Buffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buffer);

Meneruskan Data ke Buffer

Langkah selanjutnya adalah meneruskan data (simpul / indeks) ke buffer. Sampai saat ini data dalam bentuk array dan sebelum diteruskan ke buffer, kita perlu membungkusnya dalam salah satu array tipe WebGL. WebGL menyediakan metode bernamabufferData() untuk tujuan ini.

Sintaksis

Sintaks metode bufferData () adalah sebagai berikut -

void bufferData (enum target, Object data, enum usage)

Metode ini menerima tiga parameter dan dibahas di bawah -

target - Parameter pertama adalah nilai enum yang mewakili jenis buffer array yang kita gunakan. Opsi untuk parameter ini adalah -

  • ARRAY_BUFFER yang mewakili vertex data.

  • ELEMENT_ARRAY_BUFFER yang mewakili index data.

Object data- Parameter kedua adalah nilai objek yang berisi data yang akan dituliskan ke objek buffer. Di sini kita harus melewatkan data menggunakantyped arrays.

Usage- Parameter ketiga dari metode ini adalah variabel enum yang menentukan cara menggunakan data objek buffer (data yang disimpan) untuk menggambar bentuk. Ada tiga opsi untuk parameter ini seperti yang tercantum di bawah ini.

  • gl.STATIC_DRAW - Data akan ditentukan sekali dan digunakan berkali-kali.

  • gl.STREAM_DRAW - Data akan ditentukan satu kali dan digunakan beberapa kali.

  • gl.DYNAMIC_DRAW - Data akan ditentukan berulang kali dan digunakan berkali-kali.

Contoh

Cuplikan kode berikut menunjukkan cara menggunakan bufferData()metode. Asumsikan simpul dan indeks adalah larik yang masing-masing memegang data simpul dan indeks.

//vertex buffer
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);

//Index buffer
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);

Array yang Diketik

WebGL menyediakan tipe array khusus yang disebut typed arraysuntuk mentransfer elemen data seperti simpul indeks dan tekstur. Larik yang diketik ini menyimpan data dalam jumlah besar dan memprosesnya dalam format biner asli yang menghasilkan kinerja yang lebih baik. Larik yang diketik yang digunakan oleh WebGL adalah Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, UInt32Array, Float32Array, dan Float64Array.

Note

  • Umumnya untuk menyimpan data vertex, kami menggunakan Float32Array; dan untuk menyimpan data indeks, kami menggunakanUint16Array.

  • Anda dapat membuat array yang diketik seperti array JavaScript menggunakan new kata kunci.

Lepaskan Buffer

Direkomendasikan agar Anda melepaskan buffer setelah menggunakannya. Ini dapat dilakukan dengan meneruskan nilai null sebagai pengganti objek buffer, seperti yang ditunjukkan di bawah ini.

gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);

WebGL menyediakan metode berikut untuk melakukan operasi buffer -

Sr.No. Metode dan Deskripsi
1

kosong bindBuffer(enum target , Object buffer )

target - ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER

2

kosong bufferData( target enum , ukuran panjang , penggunaan enum )

target - ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER

penggunaan - STATIC_DRAW, STREAM_DRAW, DYNAMIC_DRAW

3

kosong bufferData( target enum , data objek , penggunaan enum )

target dan penggunaan - Sama seperti untukbufferData atas

4

kosong bufferSubData( target enum , offset panjang , data objek )

target - ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER

5 Obyek createBuffer()
6 kosong deleteBuffer( Penyangga objek )
7

apa saja getBufferParameter(enum target , enum pname )

target - ARRAY_BUFFER, ELEMENT_ ARRAY_BUFFER

pname - BUFFER_SIZE, BUFFER_USAGE

8 bool isBuffer( Penyangga objek )