¿Cuántos polígonos en una escena puede alcanzar el hardware moderno mientras se mantiene en tiempo real y cómo llegar allí?

11

Una pregunta bastante básica, en algunos aspectos, pero que muchas personas, incluido yo mismo, realmente no saben la respuesta. Los fabricantes de GPU a menudo citan números extremadamente altos, y la propagación entre los recuentos de polígonos que varios motores de juego afirman admitir a menudo abarca múltiples órdenes de magnitud, y luego aún depende en gran medida de muchas variables.

Soy consciente de que esta es una pregunta amplia, bastante abierta, y me disculpo por eso, solo pensé que sería una pregunta valiosa para tener aquí.

Llamageddon
fuente
2
No creo que la pregunta sea necesariamente demasiado abierta, pero cualquier respuesta numérica será incorrecta dentro de 12 meses.
Dan Hulme
@DanHulme Sí, pero los enfoques utilizados para alcanzar ese tipo de eficiencia siguen siendo los mismos. Y cuando no, he visto preguntas que requieren actualizaciones periódicas en otros sitios de stackexchange, así que creo que está bien.
Llamageddon
77
Esto es realmente imposible de responder. En primer lugar, ¿qué es "tiempo real": 60 fps? 30? ¿Menos? En segundo lugar, la respuesta variará enormemente según la GPU que tenga y la resolución a la que esté procesando. Tercero, la respuesta variará enormemente dependiendo de los detalles de cómo funciona el renderizado. Los límites en la complejidad de la escena son más complicados que solo el número de polígonos en sí, pero involucran cosas como el número de llamadas de sorteo, cambios de estado, pases de procesamiento, etc., que se ven afectados por la forma en que funciona el motor, cómo los artistas construyeron el escena, y así sucesivamente ...
Nathan Reed
1
@Llamageddon Teniendo en cuenta sus comentarios, no estoy muy seguro de lo que realmente pide. Por un lado, el título de su pregunta es bastante claro (maximiza la geometría y cómo hacerlo), pero como señaló Nathan, esto es algo imposible de responder. Por otro lado, en sus comentarios dice que desea saber cómo minimizar el costo por fotograma. Esta es una pregunta extremadamente amplia, porque podría mejorar / optimizar sus sombreadores, gráficos de escena, modelos, texturas, uso de API, simplemente todo lo que hace parte de su renderizado. Probablemente podría escribir libros completos sobre esto (si no lo ha hecho ya alguien).
Nero
1
Esto es un poco tarde, pero aquí puedes ver una malla ESTÁTICA con 24.000.000 de vértices en Blender. Y puedo rotarlo SUAVE con 40 FPS. Creo que es increíble lo que pueden hacer las tarjetas gráficas modernas.
user6420

Respuestas:

5

Creo que es comúnmente aceptado que el tiempo real es todo lo que está por encima de lo interactivo. Y interactivo se define como "responde a la entrada pero no es uniforme en el hecho de que la animación parece irregular".
Entonces, el tiempo real dependerá de la velocidad de los movimientos que uno necesita representar. El cine proyecta a 24 FPS y es lo suficientemente real como para muchos casos.

Entonces, cuántos polígonos puede manejar una máquina es fácilmente verificable comprobándolo usted mismo. Simplemente cree un pequeño parche VBO como una prueba simple y un contador FPS, muchas muestras DirectX u OpenGL le darán el banco de pruebas perfecto para este punto de referencia.

Si tiene una tarjeta gráfica de gama alta, podrá ver aproximadamente 1 millón de polígonos en tiempo real. Sin embargo, como dijiste, los motores no reclamarán soporte tan fácilmente porque los datos de la escena del mundo real causarán una cantidad de cerdos de rendimiento que no están relacionados con el recuento de polígonos.

Tienes:

  • tasa de relleno
    • muestreo de textura
    • Salida ROP
  • dibujar llamadas
  • renderizar interruptores de destino
  • actualizaciones de búfer (uniforme u otro)
  • girar en descubierto
  • complejidad del sombreador
  • complejidad de la tubería (¿alguna retroalimentación utilizada? ¿sombreado de geometría iterativa? ¿oclusión?)
  • puntos de sincronización con la CPU (¿lectura de píxeles?)
  • riqueza poligonal

Dependiendo de los puntos débiles y fuertes de una tarjeta gráfica en particular, uno u otro de estos puntos será el cuello de botella. No es como si pudieras decir con certeza "ahí, ese es".

EDITAR:

Quería agregar que, uno no puede usar la figura de especificaciones GFlops de una tarjeta específica y asignarla linealmente a la capacidad de empuje de polígonos. Debido al hecho de que el tratamiento de polígonos tiene que pasar por un cuello de botella secuencial en la tubería de gráficos como se explica con gran detalle aquí: https://fgiesen.wordpress.com/2011/07/03/a-trip-through-the-graphics -pipeline-2011-part-3 /
TLDR: los vértices tienen que caber en una pequeña caché antes del ensamblaje primitivo, que es una secuencia nativa (el orden del búfer de vértices es importante).

Si compara la GeForce 7800 (¿tiene 9 años?) Con la 980 de este año, parece que la cantidad de operaciones por segundo que es capaz de hacer se ha multiplicado por mil. Pero puede apostar que no va a empujar polígonos mil veces más rápido (lo que sería alrededor de 200 mil millones por segundo con esta simple métrica).

EDIT2:

Para responder a la pregunta "¿qué se puede hacer para optimizar un motor", como en "no perder demasiada eficiencia en los interruptores de estado y otros gastos generales".
Esa es una pregunta tan antigua como los propios motores. Y se está volviendo más complejo a medida que avanza la historia.

De hecho, en una situación del mundo real, los datos típicos de la escena contendrán muchos materiales, muchas texturas, muchos sombreadores diferentes, muchos objetivos y pases de renderizado, y muchos búferes de vértices, etc. Un motor con el que trabajé trabajó con la noción de paquetes:

Un paquete es lo que se puede representar con una llamada de sorteo.
Contiene identificadores para:

  • tampón de vértice
  • búfer de índice
  • cámara (da el pase y el objetivo de renderizado)
  • Identificación del material (da sombreador, texturas y UBO)
  • distancia al ojo
  • es visible

Entonces, el primer paso de cada cuadro es ejecutar una clasificación rápida en la lista de paquetes utilizando una función de clasificación con un operador que da prioridad a la visibilidad, luego pasar, luego material, luego geometría y finalmente distancia.

Dibujar objetos cercanos obtiene priroridad para maximizar el sacrificio Z temprano.
Los pases son pasos fijos, por lo que no tenemos más remedio que respetarlos.
El material es lo más caro para cambiar de estado después de renderizar objetivos.

Incluso entre diferentes ID de materiales, se puede realizar un suborden utilizando un criterio heurístico para disminuir el número de cambios de sombreado (más costoso dentro de las operaciones de cambio de estado del material) y, en segundo lugar, cambios de unión de textura.

Después de todo este pedido, uno puede aplicar mega texturizado, texturizado virtual y renderizado ( enlace ) sin atributos si lo considera necesario.

Acerca de la API del motor también una cosa común es diferir la emisión de los comandos de configuración de estado requeridos por el cliente. Si un cliente solicita "establecer cámara 0", es mejor simplemente almacenar esta solicitud y si más tarde el cliente llama "establecer cámara 1" pero sin otros comandos intermedios, el motor puede detectar la inutilidad del primer comando y soltarlo . Esta es la eliminación de la redundancia, que es posible mediante el uso de un paradigma "totalmente retenido". Por oposición al paradigma "inmediato", que sería solo un contenedor por encima de la API nativa y emitir los comandos correctamente según lo ordenado por el código del cliente. ( ejemplo: virtrev )

Y, por último, con el hardware moderno, un paso muy costoso (para desarrollar), pero potencialmente muy gratificante, es cambiar la API al estilo metal / mantle / vulkan / DX12 y preparar los comandos de renderizado a mano.

Un motor que prepara los comandos de representación crea un búfer que contiene una "lista de comandos" que se sobrescribe en cada cuadro.

Por lo general, existe una noción de "presupuesto" de marco, que un juego puede permitirse. Debe hacer todo en 16 milisegundos, por lo que debe dividir claramente el tiempo de GPU "2 ms para el paso de lightpre", "4 ms para el paso de materiales", "6 ms para la iluminación indirecta", "4 ms para los posprocesos" ...

v.oddou
fuente
1
Un millón me parece un poco bajo.
joojaa
solo tome cuántos MPoly / s es capaz de hacer la tarjeta, y ese es el FPS al que rendirá 1 millón. Acabo de recordar un experimento para un renderizador de terreno en un ATI4800HD. Si toma esta lista en.wikipedia.org/wiki/List_of_Nvidia_graphics_processing_units , no le darán información a los vértices a partir de la era de la arquitectura unificada. pero el hardware de 10 años parece anunciar unos 40 FPS por 1 millón de triángulos. + cf edit en mi respuesta
v.oddou
@ v.oddou Sí, pero para acercarte a ese número necesitas hacer un lote de geometría o instancias, en caso de escenas dinámicas, y eso es lo que estoy preguntando. Cómo no embotellarte el 2% del camino hacia lo que el hardware puede hacer.
Llamageddon
@Llamageddon aaah, ya veo, ESA es una pregunta de hecho. Déjame ver qué puedo decir al respecto. (EDIT2)
v.oddou
Gran respuesta en profundidad! He realizado algunas ediciones menores, como usuario en lugar de moderador. Siéntase libre de retroceder cualquiera / todos si no coinciden con su intención.
trichoplax