Qu'est-ce qu'un tampon d'index et comment est-il lié aux tampons de sommet?

11

J'ai un tampon de vertex comme celui-ci:

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

J'ai le tampon d'index suivant:

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

Je sais que je veux dessiner en gl.LINESutilisant WebGL, signifie plusieurs segments de ligne séparés.

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

Il semble permettre de dessiner plusieurs segments de ligne en un seul appel de dessin dans WebGL.

Quelqu'un pourrait-il ELI5 pour moi, qu'est-ce qu'un tampon d'index et comment est-il lié aux tampons de sommet? Comment générer des tampons d'index à partir de mes primitives?

Afr
la source

Réponses:

12

Quelqu'un pourrait-il ELI5 pour moi, qu'est-ce qu'un tampon d'index et comment est-il lié aux tampons de sommet

Votre tampon de sommets contient les coordonnées X et Y de 5 sommets. Elles sont:

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

Votre tampon d'index contient des informations sur les lignes à tracer entre ces sommets. Il utilise l'index de chaque sommet du tampon de sommets comme valeur.

Puisque vous dessinez des lignes, chaque paire de valeurs consécutives dans votre tampon d'index indique un segment de ligne. Par exemple, si le tampon d'index commence par 0, 2, cela signifie tracer une ligne entre les 0e et 2e sommets du tableau de sommets, qui dans ce cas tracerait une ligne allant de [0.0, 0.0]à [0.0, 0.6].

Dans le graphique suivant, chaque paire d'indices est de couleur coordonnée avec la ligne qu'elle indique:

entrez la description de l'image ici

De même, si vous dessinez des triangles au lieu de lignes, vous devrez fournir un tampon d'index où chaque 3 valeurs consécutives indiquent les indices de trois sommets dans le tampon de vertex, par exemple

0, 1, 2,
2, 1, 3,
2, 3, 4,
Rotem
la source
5

Si vous avez un tampon de vertex comme celui-ci:

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
]

Et dessinez-le simplement tel quel:

// 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);

Il faudrait deux coordonnées dédiées pour chaque segment de ligne. Avec le verticestel que défini ci-dessus, il ne serait possible que de tracer deux lignes :

deux lignes

Si vous avez défini les indices suivants:

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

Il est possible de tracer des lignes qui coupent encore et encore les mêmes sommets. Cela réduit la redondance. Si vous liez le tampon d'index et dites au GPU de dessiner des segments de ligne reliant les sommets par l'ordre spécifié dans le tableau indecies:

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);

On peut dessiner des figures plus complexes sans redéfinir les mêmes sommets encore et encore. Voici le résultat:

une maison

Pour obtenir le même résultat sans index, le tampon de vertex doit ressembler à ceci:

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);

Ce qui donne la même image:

encore une autre maison

Notez l'énorme redondance des sommets stockés.

Afr
la source
2
Si vous prévoyez de répondre immédiatement à votre propre question, veuillez au moins le mentionner dans la question afin que les autres ne perdent pas leur temps.
Rotem
2
Chaque bonne question devrait avoir 2 ou 3 bonnes réponses. Vous n'avez pas perdu votre temps et j'ai vraiment apprécié vos efforts. J'ai besoin de ce fil pour expliquer la logique à un partenaire de projet et votre message l'aidera beaucoup.
Afr
1
@ 5chdn L'auto-réponse est fortement encouragée . Merci d'avoir ajouté cette réponse. Si vous avez une réponse en tête au moment où vous postez une question, il y a une case à cocher sous la question qui vous permettra d'écrire votre réponse avant de poster la question, donc les deux apparaîtront en même temps. C'est juste pour vous faire savoir au cas où cela serait utile - vous n'avez certainement pas besoin de le faire et les réponses personnelles sont toujours les bienvenues à n'importe quel intervalle de temps après avoir posté la question.
trichoplax