Apa itu buffer indeks dan bagaimana kaitannya dengan buffer verteks?

11

Saya memiliki buffer vertex seperti ini:

0.0, 0.0,
1.0, 0.0,
0.0, 0.6,
1.0, 0.6,
0.5, 1.0

Saya memiliki buffer indeks berikut:

0, 2,
2, 4,
4, 3,
3, 2,
2, 1,
1, 0,
0, 3,
3, 1

Saya tahu saya ingin menggambar gl.LINESmenggunakan WebGL, berarti beberapa segmen garis yang terpisah.

gl.drawElements(gl.LINES, 16, gl.UNSIGNED_SHORT, indexBuffer);

Tampaknya memungkinkan menggambar beberapa segmen garis dalam satu panggilan undian di WebGL.

Bisakah seseorang ELI5 kepada saya, apa itu buffer indeks dan bagaimana hubungannya dengan buffer vertex? Bagaimana cara menghasilkan buffer indeks dari primitif saya?

Afr
sumber

Jawaban:

12

Bisakah seseorang ELI5 kepada saya, apa itu buffer indeks dan bagaimana hal itu terkait dengan buffer vertex

Buffer vertex Anda berisi koordinat X dan Y dari 5 simpul. Mereka:

index |  X  |  Y
  0   | 0.0 | 0.0 
  1   | 1.0 | 0.0
  2   | 0.0 | 0.6
  3   | 1.0 | 0.6
  4   | 0.5 | 1.0

Buffer indeks Anda berisi informasi tentang garis mana yang harus ditarik di antara simpul-simpul ini. Ini menggunakan indeks dari setiap vertex dalam buffer vertex sebagai nilai.

Karena Anda menggambar garis, setiap pasangan nilai berurutan di buffer indeks Anda menunjukkan segmen garis. Misalnya, jika buffer indeks dimulai dengan 0, 2, itu berarti menggambar garis antara 0 dan 2 simpul dalam array verteks, yang dalam hal ini akan menarik garis dari [0.0, 0.0]ke [0.0, 0.6].

Dalam grafik berikut, setiap pasang indeks dikoordinasikan warna dengan garis yang ditunjukkannya:

masukkan deskripsi gambar di sini

Demikian pula, jika Anda menggambar segitiga alih-alih garis, Anda perlu menyediakan buffer indeks di mana masing-masing 3 nilai berturut-turut menunjukkan indeks tiga simpul dalam buffer vertex, misalnya

0, 1, 2,
2, 1, 3,
2, 3, 4,
Rotem
sumber
5

Jika Anda memiliki vertex buffer seperti ini:

var vertices = [
  0.0, 0.0, 0.0,
  1.0, 0.0, 0.0,
  0.0, 0.6, 0.0,
  1.0, 0.6, 0.0,
  0.5, 1.0, 0.0
]

Dan cukup gambarkan seperti apa adanya:

// Create an empty buffer object
var vertex_buffer = gl.createBuffer();

// Bind appropriate array buffer to it
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);

// Pass the vertex data to the buffer
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);

/* [...] */

// Draw the lines
gl.drawArrays(gl.LINES, 0, 5);

Dibutuhkan dua koordinat khusus untuk setiap segmen garis. Dengan verticesseperti yang didefinisikan di atas, hanya mungkin dua garis dua garis :

dua baris

Jika Anda memiliki indeks berikut yang ditentukan:

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

Dimungkinkan untuk menggambar garis yang memotong simpul yang sama berulang kali. Ini mengurangi redundansi. Jika Anda mengikat buffer indeks dan memberi tahu GPU untuk menggambar segmen garis yang menghubungkan simpul dengan urutan yang ditentukan dalam array tidak valid:

var index_buffer = gl.createBuffer();

gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buffer);

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

// draw geometry lines by indices
gl.drawElements(gl.LINES, 16, gl.UNSIGNED_SHORT, index_buffer);

Seseorang dapat menggambar angka yang lebih kompleks tanpa mendefinisikan ulang simpul yang sama berulang-ulang. Ini hasilnya:

rumah

Untuk mencapai hasil yang sama tanpa indeks, buffer vertex akan terlihat seperti berikut:

var vertices = [
  0.0, 0.0, 0.0,
  0.0, 0.6, 0.0,
  0.0, 0.6, 0.0,
  0.5, 1.0, 0.0,
  0.5, 1.0, 0.0,
  1.0, 0.6, 0.0,
  1.0, 0.6, 0.0,
  0.0, 0.6, 0.0,
  0.0, 0.6, 0.0,
  1.0, 0.0, 0.0,
  1.0, 0.0, 0.0,
  0.0, 0.0, 0.0,
  0.0, 0.0, 0.0,
  1.0, 0.6, 0.0,
  1.0, 0.6, 0.0,
  1.0, 0.0, 0.0
]

/* [...] */

// Draw the lines
gl.drawArrays(gl.LINES, 0, 16);

Yang menghasilkan gambar yang sama:

rumah lain

Perhatikan redundansi besar dalam simpul yang disimpan.

Afr
sumber
2
Jika Anda berencana untuk segera menjawab pertanyaan Anda sendiri, setidaknya sebutkan dalam pertanyaan agar orang lain tidak membuang waktu mereka.
Rotem
2
Setiap pertanyaan yang bagus harus memiliki 2 atau 3 jawaban yang baik. Anda tidak membuang waktu Anda dan saya sangat menghargai upaya Anda. Saya perlu utas ini untuk menjelaskan logika ke mitra proyek dan posting Anda akan banyak membantunya.
Afr
1
@ 5chdn Menjawab sendiri sangat dianjurkan . Terima kasih telah menambahkan jawaban ini. Jika Anda memiliki jawaban dalam pikiran pada saat Anda memposting pertanyaan, ada kotak centang di bawah pertanyaan yang akan memungkinkan Anda untuk menulis jawaban Anda sebelum memposting pertanyaan, sehingga keduanya akan muncul pada saat yang sama. Ini hanya untuk memberi tahu Anda jika itu berguna - Anda tentu tidak perlu melakukan ini dan jawaban sendiri masih sangat disambut pada interval waktu setelah mengirim pertanyaan.
trichoplax