La instancia mejora el rendimiento (significativamente) cuando se procesan varias copias (¿miles? ¿Miles?) De la misma malla a la vez. Pero, ¿cuánto sobrecarga tiene cuando se procesa exactamente una copia con una llamada de extracción? ¿Sería una buena o mala idea usar instancias para toda la geometría renderizada por el motor?
Editar: Digamos que estamos creando un juego FPS. La mayoría de los objetos tienen una sola instancia: un cuchillo, una pistola, una ametralladora, un edificio y una torre de radio. Pero también hay algunos objetos con múltiples instancias: árboles (por ejemplo, 3 tipos de árboles con cientos de instancias), hierba, etc. Lo que quiero decir es: en lugar de representar los objetos de una instancia de la manera "tradicional" y los árboles y hierba usando instancias, los renderizamos todos usando instancias. Entonces, nuestra torre de radio tiene solo una instancia (cuya información almacenamos en un búfer de datos de instancia) y representamos esa torre usando algún tipo de DrawInstanced()
llamada con el recuento de instancias igual 1
. Lo mismo con todos los demás objetos (por supuesto, los árboles y el césped tienen múltiples instancias).
Entonces mi pregunta es: ¿es una mala idea dibujar una sola instancia de un objeto usando instancing? ¿La creación de instancias tiene demasiada sobrecarga (en cuanto a memoria y rendimiento) o es de alguna manera no deseada para representar objetos de instancia única?
fuente
(En mi sistema, no lo probé en ningún otro lado) En GL, la creación de una sola malla (dibujo con conteo = 1) tiene una sobrecarga desagradable, pero no sé de dónde viene. Sugiero no hacerlo.
Probé esto en una aplicación práctica hace un par de meses. Codifiqué algunos algoritmos de iluminación global en la escena Crytek Sponza, que consta de aproximadamente 350 mallas (no recuerdo exactamente), de las cuales un par comparte un puñado de casos. Al principio lo hice como sugieres, simplemente instancia todo y dibuja el resto con el recuento de instancias de 1, ya que simplificó un poco el código de representación.
Más adelante, cuando optimicé el renderizador, simplemente volví de instanciar los objetos count = 1 a enviarlos de la manera habitual, lo que me ahorró aproximadamente 3.5 milisegundos por fotograma en un i7 3770k (y GTX 770). Cambiar las mallas con múltiples instancias a solo hacerlo de la manera tradicional me ahorró otros 0.5 ms. En general, la aplicación pasó de ~ 120 FPS a aproximadamente ~ 230 FPS.
Estas cifras, por supuesto, siempre dependen de dónde están los cuellos de botella en su aplicación, y los últimos 0.5 ms podrían llegar a ser más lentos en una aplicación en la que está muy atraído por las llamadas de llamada. Pero de lo contrario, en mi experiencia, la instancia tiene algunos gastos generales desagradables si no está dibujando muchas cosas a la vez.
fuente
Puede estar seguro de que dibujar un solo objeto instanciado es más costoso que dibujar un solo objeto normalmente. Para la creación de instancias, la GPU se está preparando para una gran cantidad de objetos y esta preparación será diferente a la de un solo objeto. Sin embargo, cuán grande es esta brecha de rendimiento solo se puede encontrar experimentando y depende en gran medida de su configuración de representación real. La única forma de saberlo con certeza es probándolo usted mismo. Es difícil comparar una sola llamada de sorteo aquí hay varias ideas sobre cómo podría proceder.
fuente
Han pasado 4 años ... y creo que es seguro decir que está perfectamente bien enviar llamadas de sorteo "instanciadas" con 1. Como habrás notado, las nuevas API DX12 y Vk tienen un recuento de instancias que puede ser de 0 a NUM_INSTANCES . También tenga en cuenta que no hay DrawIndexed (...) .
EDITAR
Como nota de precaución, lo anterior probablemente esté bien con estas API modernas, tal vez usar algo antiguo como Gl <3.3 o quizás DX11 requerirá algunos perfiles como lo mencionan otros usuarios.
fuente