Como ejercicio de aprendizaje, he escrito un motor de renderizado diferido. Ahora me gustaría agregar un gráfico de escena a este motor, pero estoy un poco desconcertado sobre cómo hacerlo.
En un motor de renderizado normal (normal), simplemente agregaría todos los elementos (todos implementando IDrawable e IUpdateAble) a mi gráfico de escena, que viajar primero por la amplitud del gráfico de escena y llamar a Draw () a todas partes.
Sin embargo, en un motor de renderizado diferido, tengo que separar las llamadas de extracción. Primero tengo que dibujar la geometría, luego las ruedas de sombra y luego las luces (todas para diferentes objetivos de renderizado), antes de combinarlas todas. Entonces, en este caso, no puedo simplemente recorrer el gráfico de la escena y simplemente llamar a dibujar. De la forma en que lo veo, tengo que viajar por todo el gráfico de la escena 3 veces, verificando qué tipo de objeto es el que debe dibujarse, o tengo que crear 3 gráficos de escena separados que de alguna manera están conectados entre sí. Ambas parecen soluciones pobres, me gustaría manejar los objetos de escena más transparentes.
Otra solución que he pensado fue viajar a través del gráfico de la escena como normal y agregar elementos a 3 listas separadas, separar la geometría, las ruedas de sombra y las luces, y luego iterar estas listas para dibujar las cosas correctas, es esto mejor, y ¿es ¿Es prudente repoblar 3 listas en cada cuadro?
fuente
Mi sugerencia sería un enfoque de 2 pasos adaptado a sus requisitos específicos, similar a lo que usted mismo describió. Necesita un gráfico de escena y una "colección de renderizado" para cada uno de los pasos de renderizado, en su caso sombra, geometría, luces (¿quizás un cuarto sean objetos transparentes?)
El gráfico de escena se puede basar en cualquier tipo de relaciones, pero mi preferencia personal se basaría en relaciones espaciales donde cada nodo puede contener los otros nodos para facilitar el sacrificio rápido.
Las colecciones de render pueden ser cualquier tipo de estructura de datos adaptada al paso específico. Por ejemplo, la colección de sombras podría ser una lista o un árbol ordenado por profundidad para maximizar el rechazo temprano de z. La colección de geometría podría clasificarse según el uso del sombreador para minimizar los cambios de sombreado (estado). La colección de luces podría ser una lista o un árbol ordenados por distancia de luz, tamaño o una combinación de ellos, de modo que pueda limitar el renderizado de luz a solo las luces más efectivas si el rendimiento es un problema.
Independientemente de las estructuras de datos que elija, asegúrese de que la operación de inserción sea rápida y asegúrese de que use la agrupación y otras técnicas para eliminar cualquier asignación / destrucción de datos porque va a borrar y completar estas listas en cada cuadro.
Ahora unir todo es fácil. Simplemente recorra el gráfico de la escena y agregue cada elemento a las colecciones de renderizado relevantes. Ayuda si su estructura de datos ordena / estructura automáticamente nuevas entradas en función de los requisitos. Cuando haya terminado, revise las colecciones de render en el orden requerido y renderícelas.
Debido a que sus estructuras de datos tienen una inserción rápida y no generan basura, no hay penalización por repoblar listas como usted mencionó.
fuente