¿Por qué Vertex Buffer Objects mejora el rendimiento?

10

Desde mi comprensión básica, un objeto búfer Vertex funciona de manera similar (pseudocódigo):

Normalmente, si uno quisiera decir, dibujar un cuadrado, uno podría emitir comandos de dibujo lineal.

line (0, 0) -> (1, 0)
line (1, 0) -> (1, 1)
line (1, 1) -> (0, 1)
line (0, 1) -> (0, 0)

Usar un VBO, si lo entiendo correctamente, cargaría los vértices en un VBO.

define VBO
load (0,0) -> VBO
load (1,0) -> VBO
load (1,1) -> VBO
load (0,1) -> VBO
load (0,0) -> VBO

Entonces puede emitir un comando de dibujo.

draw VBO vertices

Si bien entiendo cómo funcionan los VBO, no sé por qué mejoran el rendimiento.

¿Cómo mejoran el rendimiento?

Ethan Bierlein
fuente

Respuestas:

11

En general, cuando renderiza un objeto en un modo inmediato, emitiendo comandos de dibujo lineal, por ejemplo, crea una serie de comandos que envía a la tarjeta gráfica para dibujar. Si dibuja muchos datos, o dibuja con mucha frecuencia, puede perder mucho tiempo enviando estos datos una y otra vez.

Un búfer de vértices le permite producir un solo objeto que envíe a la tarjeta gráfica una vez. Si no necesita cambiar su geometría, puede dejarla en la tarjeta gráfica y simplemente enviarle una solicitud para dibujar ese objeto. Como evita la copia cada vez que dibuja, hay mucho menos gastos generales para cada dibujo.

Tenga en cuenta que el uso de un objeto de búfer de vértices no siempre proporciona una aceleración muy significativa. Si solo está dibujando el objeto una vez por cuadro y está reemplazando la geometría entre cada cuadro, entonces no obtiene los beneficios de evitar la copia de cada cuadro.

La mayor parte de mi experiencia proviene de la escritura de programas que utilizan API de gráficos como OpenGL, por lo que alguien que se haya metido con el backend de un controlador de gráficos probablemente pueda proporcionar una respuesta más detallada, pero espero que esto aclare un poco las cosas.

porglezomp
fuente
10

Hay dos pasos que hacen que el VBO sea más eficiente que el modo inmediato.

  1. El modo inmediato ( glBegin / glEnd , glVertex * , etc.) significa que en cada cuadro, usted alimenta los vértices, atributo por atributo (posición, normal, color, etc.), al controlador, que luego los reformatea y finalmente los envía todo el paquete como un comando para la GPU. Que muchas funciones llaman por vértice en cada cuadro.
    (Tenga en cuenta que el modo inmediato está en desuso desde OpenGL 3.0 y se elimina por completo de 3.2 .)

  2. Mediante el uso de matrices de vértices (consulte glDrawArrays , glDrawElements , glVertexPointer , etc.), puede darle al controlador todo de una vez y ahorrarle la carga de formatear los vértices. Está reemplazando efectivamente varias llamadas de función por vértice con solo un puñado de llamadas para toda la malla. Pero aún necesita hacer eso una vez por cuadro

  3. Vertex Buffer Object , o VBO (vea glGenBuffers , glBindBuffer , etc.) vaya un paso más allá y almacene los datos en el lado de la GPU: solo los envía una vez, y luego se refiere a ellos mediante un identificador. Usted ahorra ancho de banda al no enviar los mismos datos una y otra vez en cada cuadro.

Julien Guertault
fuente
6

Al usar una interfaz de modo inmediato (por ejemplo, OpenGL glBegin () / glEnd () / glVertex ()) de estilo antiguo, está goteando los datos de alimentación al controlador de una pieza a la vez. Luego tiene que tomar esa única pieza de datos, formatearla y pasarla al hardware (lo que en estos días significa ponerla en un búfer de comando).

Al usar un objeto de búfer de vértices, está proporcionando un bloque (con suerte) de datos al controlador antes de que sea necesario usarlo. Puede realizar una serie de optimizaciones (reformatear, colocar en la memoria de video) y no tener que alimentar la GPU por partes.

En la práctica, si solo está dibujando una pequeña cantidad de primitivas, entonces probablemente no habrá mucha diferencia, sin embargo, si está dibujando una malla triangular multimillonaria, entonces los VBO en la memoria de video son el camino a seguir.

Andrew Sidwell
fuente