Sí, pero necesitas un cambio de paradigma.
Lo que está acostumbrado se llama renderizado hacia adelante. Envía su geometría y luego procede inmediatamente con el pase de sombreado. En el renderizado directo básico, puede realizar un bucle dentro del sombreador para cada luz o realizar una pasada por luz y mezclar el resultado (con una combinación de aditivos).
Pero las cosas han evolucionado bastante. Entra: Renderizado diferido
Ahora que hay tantas variantes que las describen a todas en detalle, será mucho más que aceptable para una respuesta aquí. Así que aquí solo voy a describir la esencia del sombreado diferido, hay muchos otros recursos que puede encontrar fácilmente usando google, con suerte, después de leer esto, tendrá las palabras clave correctas para encontrar lo que necesita.
La idea básica es diferir el sombreado después de la tubería. Tienes dos pasos principales:
- Renderice su geometría y toda la información necesaria para sombrear en múltiples objetivos de renderizado. Esto significa que, por lo general, en una implementación básica, tendría un búfer de profundidad, un búfer que contiene las normales de su geometría y el color albedo. Pronto descubrirá que necesita otra información de los materiales (por ejemplo, rugosidad, factor "metálico", etc.).
Esta imagen de wikipedia muestra tres búferes (color, profundidad y normales)
Nuevamente, la cantidad, el tipo y el contenido de los buffers utilizados varía bastante entre los diferentes proyectos. Encontrará el conjunto de buffers con el nombre de GBuffers.
- Después de este es el momento de aplicar la iluminación real. Durante el pase de iluminación para cada luz, desea dibujar un volumen de luz que dependa del tipo de luz:
- Para una luz direccional, representa un quad de pantalla completa.
- Para un punto de luz, representa una esfera donde el radio se basa en la atenuación de su punto de luz.
- Para un foco, renderiza un cono cuyas dimensiones nuevamente dependen de las características de su luz.
En el sombreador de píxeles de este pase, pasa sus GBuffers y realiza su iluminación y sombreado utilizando la información en ellos. De esta manera, solo procesa los píxeles afectados por cada una de las luces que tienen una aceleración razonable en comparación con el renderizado hacia adelante clásico.
También tiene varias desventajas, sobre todo el manejo de objetos transparentes y un mayor consumo de ancho de banda y memoria de video. Pero también es más complicado manejar varios modelos de materiales.
Tiene otras ventajas secundarias (como tener mucha información lista para el procesamiento posterior) y también es bastante fácil de implementar. Pero esto ya no es lo mejor para muchas luces.
Las técnicas más nuevas son, por ejemplo, las de representación en mosaico. La idea principal de estos es subdividir la escena en "mosaicos" de espacio de pantalla y asignar a cada mosaico las luces que lo afectan. Esto existe tanto de manera diferida como avanzada. Estas técnicas provocan algunos problemas cuando tiene varias discontinuidades de profundidad en un mosaico, pero generalmente es más rápido que el clásico diferido y resuelve varios problemas. Por ejemplo, entre las ventajas, con el mosaico diferido, lee los GBuffers una vez por fragmento iluminado y los píxeles en el mismo mosaico procesan coherentemente las mismas luces.
La evolución adicional en este lado es el sombreado en clúster, que es conceptualmente similar a los enfoques basados en mosaico, que en lugar de mosaicos de espacio de pantalla, agrupa con una extensión 3D. Este método maneja mejor el problema de las discontinuidades de profundidad y generalmente funciona mejor que los métodos en mosaico.
NOTA IMPORTANTE: he descrito los conceptos básicos del sombreado diferido. Existen múltiples variaciones, optimizaciones y mejoras, por lo que le recomiendo que experimente con una versión simple y luego haga algunas investigaciones sobre otras técnicas como la que mencioné anteriormente.