performance - que - OpenGL es mejor dibujar por lotes o tener VBO estáticos
que significa vbo en minecraft (1)
¿Qué es preferible, desde un punto de vista de eficiencia (u otro punto de vista si es importante)?
Situación
Una aplicación OpenGL que dibuja muchas líneas en diferentes posiciones cada fotograma (60 fps). Digamos que hay 10 líneas. O 100 000 líneas. ¿Sería la respuesta diferente?
- # 1 Tener un VBO estático que nunca cambia, conteniendo 2 vértices de una línea
Cada fotograma tendría una llamada a glDrawArrays por línea para dibujar, y entre ellas habría transformaciones matriciales para posicionar nuestra única línea
- # 2 Actualice el VBO con los datos de todas las líneas en cada fotograma.
Cada cuadro tendría una sola llamada de sorteo.
El segundo es increíblemente más eficiente.
Los estados cambiantes, particularmente la transformación y las matrices, tienden a provocar el recálculo de otros estados y generalmente más matemáticas.
Sin embargo, la actualización de la geometría simplemente implica sobrescribir un búfer.
Con el hardware de video moderno en buses de ancho de banda bastante masivo, enviar algunos flotadores es trivial. Están diseñados para mover toneladas de datos rápidamente, es un efecto secundario del trabajo. Actualizar los buffers de vértices es exactamente lo que hacen a menudo y rápido. Si asumimos puntos de 32 bytes cada uno (posición y color de float4), 100000 segmentos de línea son menos de 6 MB y PCIe 2.0 x16 es de aproximadamente 8 GB / s, creo.
En algunos casos, dependiendo de cómo el controlador o la tarjeta maneje las transformaciones, el cambio de una puede ocasionar la multiplicación de matrices y el recálculo de otros valores, incluidas las transformaciones, los planos de corte y recorte, etc. Esto no es un problema si cambia el estado. Unos pocos miles de polis, y repetir, pero cuando los cambios de estado son a menudo, tendrán un costo significativo.
Un buen ejemplo de lo que se resolvió anteriormente es el concepto de procesamiento por lotes, que minimiza los cambios de estado para poder dibujar más geometría entre ellos. Esto se utiliza para dibujar con mayor eficiencia grandes cantidades de geometría.
Como un ejemplo muy claro, considere el mejor caso para # 1: el conjunto de transformaciones no genera cálculos adicionales y el controlador amortigua con celo y perfectamente. Para dibujar 100000 líneas, necesitas:
- 100000 conjuntos de matrices (en la memoria RAM del sistema)
- 100000 llamadas a conjunto de matrices con función de sobrecarga de llamada (al controlador de video, copiando la matriz al búfer allí)
- 100000 matrices copiadas a RAM de video, realizadas en un solo bulto
- 100000 líneas de sorteo de llamadas
La función de sobrecarga de llamadas solo va a matar el rendimiento.
Por otro lado, el procesamiento por lotes implica:
- Cálculos y sets de 100000 puntos, en RAM del sistema.
- 1 vbo copia a video RAM. Esta será una gran parte, pero una sola parte contigua y ambas partes saben qué esperar. Se puede manejar bien.
- 1 llamada de conjunto de matrices
- 1 matriz de copia a video RAM
- 1 sorteo de llamadas
Copia más datos, pero es muy probable que los contenidos de VBO aún no sean tan caros como copiar los datos de matriz. Además, ahorras una gran cantidad de tiempo de CPU en las llamadas a funciones (200000 hasta 2). Esto simplifica la vida para usted, el controlador (que tiene que almacenar todo en búfer y verificar si hay llamadas redundantes y optimizar y manejar la descarga) y probablemente también la tarjeta de video (que puede haber tenido que recalcular). Para que sea realmente claro, visualice un código simple para él:
1:
for (i = 0; i < 100000; ++i)
{
matrix = calcMatrix(i);
setMatrix(matrix);
drawLines(1, vbo);
}
(ahora desenvuelve eso)
2:
matrix = calcMatrix();
setMatrix(matrix);
for (i = 0; i < 100000; ++i)
{
localVBO[i] = point[i];
}
setVBO(localVBO);
drawLines(100000, vbo);