Esto probablemente se ha preguntado una y otra vez, pero no pude encontrar nada útil así que aquí va de nuevo ...Ajuste del rendimiento de OpenGL para el rendimiento de la geometría
En mi aplicación tengo que rendir una malla bastante grande (una un par de millones de triángulos o más) y estoy teniendo algunos problemas para obtener tasas de fotogramas decentes. La CPU está bastante inactiva, así que definitivamente estoy vinculado a la GPU. Cambiar la resolución no afecta el rendimiento, por lo que no está unida a fragmentos o ráster.
La malla es dinámica (pero localmente estática) por lo que no puedo almacenar todo en la tarjeta de video y procesarla con una sola llamada. Por razones específicas de la aplicación, los datos se almacenan como un octárbol con voxels en las hojas, con lo que obtengo el descarte de frustum básicamente gratis. Los datos de los vértices consisten en coordenadas, normales y colores; no se utilizan texturas ni sombreadores.
Mi primer enfoque fue simplemente renderizar todo desde la memoria usando un gran STREAM_DRAW
VBO, que resultó ser demasiado lento. Mi idea inicial fue que quizás estaba sobrecargando el bus (empujando ~ 150 MiB por cuadro), así que implementé un esquema de almacenamiento en caché que almacena la geometría utilizada recientemente para representar el objeto en VBO estáticos en la tarjeta gráfica, con cada VBO almacenando un par de 100 KiB a un par de datos de MiB (almacenar más por VBO da más cacheo, por lo que aquí hay una compensación). La siguiente imagen es un ejemplo de cómo se ven los datos, donde todo lo que se colorea en rojo se extrae de las VBO almacenadas en caché.
Example of the rendered data http://gimaker.users.sourceforge.net/0010.png
Como los números siguientes muestran, no veo un aumento espectacular en el rendimiento cuando se utiliza la memoria caché. Para una malla totalmente estática de aproximadamente 1 millón de triángulos I obtener los siguientes valores de frecuencia:
- Sin caché: 1,95 Hz
- almacenamiento en caché utilizando matrices de vértices: 2.0 Hz (> 75% de la malla se almacena en caché)
- almacenamiento en caché utilizando
STATIC_DRAW
OISCIV: 2,4 Hz
Así que mi pregunta es ¿cómo puedo acelerar esto? Es decir .:
- ¿Cuál es el formato de vértice recomendado para obtener un rendimiento decente? Uso el almacenamiento intercalado con posiciones y normales como
GL_FLOAT
yGL_UNSIGNED_BYTE
para los colores, con un byte de relleno para obtener la alineación de 4 bytes (28 bytes/vértice total). - Si usar el mismo búfer para las normales para todos mis cuadros podría ser útil (todas las casillas están alineadas con el eje, así puedo asignar un búfer normal al tamaño de la entrada de la memoria caché más grande y usarlo para todas).
- ¿Cómo puedo saber qué parte de la tubería es el cuello de botella? No tengo una tarjeta de video espectacular (Intel GM965 con controladores Linux de código abierto) por lo que es posible que llegue a su límite. ¿Cuánto rendimiento puedo esperar del hardware típico (gráficos integrados de 2 a 3 años, gráficos integrados modernos, gráficos discretos modernos)?
- ¿Alguna otra sugerencia sobre cómo podría hacer frente a esto, trampas, etc.
No estoy interesado en las respuestas que sugieren LOD (ya probado esto), consejos específicos del proveedor o el uso de funciones de OpenGL de cualquier cosa más adelante que 1.5.
¿Sus primitivos consisten solo en cajas alineadas con el eje? – Stringer
@Stringer Bell: Sí (pero no necesariamente alineado con los ejes del mundo). – Staffan
No estoy seguro, pero supongo que tocas el límite de la tarjeta gráfica. He buscado en Google un poco y parece que Intel GM965 tiene un rendimiento bastante bajo, especialmente para juegos. (El tuyo no es un juego pero parece bastante "difícil" de renderizar). Nvidia tiene una lista de cuántos triángulos pueden mostrar sus tarjetas/segundo: tal vez pueda categorizar su tarjeta con esta lista para averiguar el límite "teórico". – InsertNickHere