Pregunta

Estoy tratando de tener una idea clara de cuándo debería usar matrices indexadas de vértices OpenGL, dibujados con Draenelements GL [múltiples] y similares, en lugar de cuándo debería usar simplemente matrices contiguas de vértices, dibujados con GL [múltiples] .

(Actualizar: El consenso en las respuestas que obtuve es que siempre se debe usar vértices indexados).

He ido de ida y vuelta en este tema varias veces, así que voy a describir mi comprensión actual, con la esperanza de que alguien pueda decirme que ahora finalmente estoy más o menos correcto, o de lo contrario señalar dónde están mis malentendidos restantes. . Específicamente, tengo tres conclusiones, en negrita. Corrijalos si están equivocados.

Un caso simple es si mi geometría consiste en mallas para formar superficies curvas. En este caso, los vértices en el medio de la malla tendrán atributos idénticos (posición, normal, color, coorden de textura, etc.) para cada triángulo que usa el vértice.

Esto me lleva a concluir que:

1. Para la geometría con pocas costuras, las matrices indexadas son una gran victoria.

Siga la regla 1 siempre, excepto:

Para la geometría que es muy 'bloquea', en la que cada borde representa una costura, el beneficio de las matrices indexadas es menos obvio. Para tomar un cubo simple como ejemplo, aunque cada vértice se usa en tres caras diferentes, no podemos compartir vértices entre ellos, porque para un solo vértice, las normales de superficie (y otras cosas posibles, como el color y la textura coorden las coordenadas ) diferirá en cada cara. Por lo tanto, necesitamos introducir explícitamente posiciones de vértice redundantes en nuestra matriz, de modo que la misma posición se pueda usar varias veces con diferentes normales, etc. Esto significa que las matrices indexadas son de menor uso.

Por ejemplo, al renderizar una sola cara de un cubo:

 0     1
  o---o
  |\  |
  | \ |
  |  \|
  o---o
 3     2

(Esto puede considerarse de forma aislada, porque las costuras entre esta cara y todas las caras adyacentes significan que ninguno de estos vértices se puede compartir entre caras)

Si se reproduce usando GL_TRIangle_Fan (o _strip), entonces cada cara del cubo se puede representar así:

verts  = [v0, v1, v2, v3]
colors = [c0, c0, c0, c0]
normal = [n0, n0, n0, n0]

Agregar índices no nos permite simplificar esto.

De esto concluyo que:

2. Al renderizar la geometría que es todas las costuras o principalmente costuras, cuando usa GL_TRIangle_Strip o _fan, entonces nunca debería usar matrices indexadas, y en su lugar siempre debería usar GL [multi] DRINGArays.

(Actualizar: Las respuestas indican que esta conclusión es incorrecta. Aunque los índices no nos permiten reducir el tamaño de las matrices aquí, aún deben usarse debido a otros beneficios de rendimiento, como se discutió en los comentarios)

La única excepción a la Regla 2 es:

Cuando se usa GL_Triangles (en lugar de tiras o ventiladores), la mitad de los vértices aún se pueden reutilizar dos veces, con normales y colores idénticos, etc., porque cada cara de cubo se representa como dos triángulos separados. De nuevo, para la misma cara de cubo:

 0     1
  o---o
  |\  |
  | \ |
  |  \|
  o---o
 3     2

Sin índices, usando GL_Triangles, las matrices serían algo así como:

verts =   [v0, v1, v2,  v2, v3, v0]
normals = [n0, n0, n0,  n0, n0, n0]
colors =  [c0, c0, c0,  c0, c0, c0]

Dado que un vértice y una normalidad son a menudo 3 flotadores cada uno, y un color a menudo es 3 bytes, eso da, para cada cara de cubo, sobre:

verts   = 6 * 3 floats = 18 floats
normals = 6 * 3 floats = 18 floats
colors  = 6 * 3 bytes  = 18 bytes

= 36 floats and 18 bytes per cube face.

(Entiendo que el número de bytes podría cambiar si se usan diferentes tipos, las cifras exactas son solo para ilustración).

Con índices, podemos simplificar esto un poco, dando:

verts   = [v0, v1, v2, v3]     (4 * 3 = 12 floats)
normals = [n0, n0, n0, n0]     (4 * 3 = 12 floats)
colors  = [c0, c0, c0, c0]     (4 * 3 = 12 bytes)
indices = [0, 1, 2,  2, 3, 0]  (6 shorts)

= 24 floats + 12 bytes, and maybe 6 shorts, per cube face.

Vea cómo en el último caso, los vértices 0 y 2 se usan dos veces, pero solo se representan una vez en cada una de las matrices de verts, normales y colores. Esto suena como una pequeña victoria para usar índices, incluso en el caso extremo de que cada borde de geometría sea una costura.

Esto me lleva a concluir que:

3. Cuando se usa GL_Triangles, uno siempre debe usar matrices indexadas, incluso para la geometría, que es todas las costuras.

Corrija mis conclusiones en negrita si están equivocados.

¿Fue útil?

Solución

A partir de esto, concluyo que al renderizar la geometría que es todas las costuras o principalmente costuras, al usar GL_TRIangle_Strip o _Fan, entonces nunca debería usar matrices indexadas, y en su lugar siempre debería usar GL [múltiples

No, y la razón es bastante simple.

Su conclusión se basa en el hecho de que ha analizado un solo quad compuesto por dos triángulos. Estos dos triángulos dibujados con ventilador/tira triangular no se pueden simplificar usando matrices indexadas.

Pero trate de pensar en una gran geometría de terreno. Cada bloque de terreno se dibuja como un quad, usando ventilador de triángulo/tira primitiva. Por ejemplo:

Cada tira de triángulo en la figura tiene en común todos los vértices con tiras de triángulo adyacentes, y el uso de índices permite comprimir la definición de geometría, en lugar de repetir vértices para cada tira de triángulo.


Básicamente, dibujar primitivas (triángulos, ventiladores y tiras) que usan índices son útiles siempre que puedas compartir la mayoría de los vértices de una sola primitiva con otro.

Compartir la información permite guardar el ancho de banda de transmisión de información, pero no es la única ventaja. En realidad, las matrices indexadas permiten:

  • Evite la sincronización de la información que pertenece al mismo vértice "conceptual", especificado muchas veces
  • Deje realizar la misma operación de sombreador en un solo vértice en lugar de ejecutar muchas veces, uno para cada duplicación de vértice.
  • Además, la combinación del uso de tiras/ventiladores e índices de triángulo permite que la aplicación comprime el búfer de índices, ya que la especificación de tira/ventilador requiere menos índices (un triángulo requiere siempre 3 índices para cada cara).

La matriz indexada no se puede utilizar, como ha especificado, cada vez que un vértice no puede compartir cada información asociada (color, coords de textura, etc.) con otro vértice coincidente.


Solo en aras de la integridad, el tamaño de la información necesaria para la especificación de geometría no es el único factor que determina la operación de representación óptima.

De hecho, otro factor fundamental para la representación primitiva es la localización de caché de los datos. Los datos de geometría mal especificados (objetos de búfer sin encinteres, tiras de triángulo largas ...) provocan muchas fallas de caché, degradando el rendimiento de la tarjeta gráfica.

Para optimizar la operación de renderizado, la especificación de vértice se reordenará de manera que reutilice los vértices especificados previamente, con la mayor probabilidad. De esa manera, la línea de caché de tarjeta gráfica puede reutilizar vértices especificados previamente sin obtenerlos de la memoria.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top