El volumen de sombra es una técnica utilizada en gráficos de computadora en 3D para agregar sombras a una escena renderizada. Fue propuesta por primera vez por Frank Crow en 1977 [1] como la geometría que describe la forma 3D de la región oculta por una fuente de luz. Un volumen de sombra divide el mundo virtual en dos: áreas que están en sombra y áreas que no lo están.
La implementación de volúmenes de sombras mediante el uso de buffers de plantillas se considera generalmente una de las técnicas de sombreado en tiempo real de uso general más prácticas para su uso en hardware de gráficos 3D moderno [ cita requerida ] . Se ha popularizado gracias al videojuego Doom 3 , y una variación particular de la técnica utilizada en este juego se conoce como Carmack's Reverse.
Los volúmenes de sombra se han convertido en una herramienta popular para el sombreado en tiempo real, junto con el más venerable mapeo de sombras . La principal ventaja de los volúmenes de sombra es que son precisos al píxel (aunque muchas implementaciones tienen un pequeño problema de auto-sombreado a lo largo del borde de la silueta, vea la construcción a continuación), mientras que la precisión de un mapa de sombra depende de la memoria de textura asignada al mismo, así como del ángulo en el que se proyectan las sombras (en algunos ángulos, la precisión de un mapa de sombras sufre inevitablemente). Sin embargo, la técnica requiere la creación de geometría de sombra, que puede consumir mucha CPU (dependiendo de la implementación). La ventaja del mapeo de sombras es que a menudo es más rápido, porque los polígonos de volumen de sombra suelen ser muy grandes en términos de espacio de pantalla y requieren mucho tiempo de relleno (especialmente para objetos convexos), mientras que los mapas de sombras no tienen esta limitación.
Para construir un volumen de sombra, se proyecta un rayo desde la fuente de luz a través de cada vértice del objeto que proyecta la sombra hasta un punto determinado (generalmente el infinito). Estas proyecciones juntas formarán un volumen; cualquier punto dentro de ese volumen estará en sombra, todo lo que esté afuera estará iluminado por la luz.
En el caso de un modelo poligonal, el volumen se forma generalmente clasificando cada cara del modelo como orientada hacia la fuente de luz o orientada en sentido contrario a la misma. El conjunto de todos los bordes que conectan una cara orientada hacia una cara opuesta forman la silueta con respecto a la fuente de luz. Los bordes que forman la silueta se extruyen en sentido contrario a la luz para construir las caras del volumen de sombra. Este volumen debe extenderse por todo el rango de la escena visible; a menudo, las dimensiones del volumen de sombra se extienden hasta el infinito para lograr esto (consulte la optimización a continuación). Para formar un volumen cerrado, se deben cubrir los extremos delantero y trasero de esta extrusión. Estas coberturas se denominan "tapas". Según el método utilizado para el volumen de sombra, el extremo delantero puede estar cubierto por el propio objeto y, a veces, se puede omitir el extremo trasero (consulte el paso de profundidad a continuación).
También existe un problema con la sombra, ya que las caras a lo largo del borde de la silueta son relativamente poco profundas. En este caso, la sombra que un objeto proyecta sobre sí mismo será nítida y revelará sus facetas poligonales, mientras que el modelo de iluminación habitual tendrá un cambio gradual en la iluminación a lo largo de la faceta. Esto deja un artefacto de sombra irregular cerca del borde de la silueta que es difícil de corregir. Aumentar la densidad poligonal minimizará el problema, pero no lo eliminará. Si se limita el frente del volumen de sombra, todo el volumen de sombra puede desplazarse ligeramente hacia afuera de la luz para eliminar cualquier autointersección de sombra dentro de la distancia de desplazamiento del borde de la silueta (esta solución se usa más comúnmente en el mapeo de sombras ).
Los pasos básicos para formar un volumen de sombra son:
Después de Crow, en 1991 Tim Heidmann demostró cómo utilizar el búfer de esténcil para renderizar sombras con volúmenes de sombras lo suficientemente rápido como para usarlas en aplicaciones en tiempo real. Hay tres variaciones comunes de esta técnica, depth pass , depth fail y unique-or , pero todas ellas utilizan el mismo proceso:
La diferencia entre estos tres métodos se produce en la generación de la máscara en el segundo paso. Algunos implican dos pasadas y otros sólo una; algunos requieren menos precisión en el buffer de esténcil.
Los volúmenes de sombras tienden a cubrir grandes porciones de la escena visible y, como resultado, consumen un valioso tiempo de rasterización (tiempo de relleno) en el hardware de gráficos 3D. Este problema se ve agravado por la complejidad de los objetos que proyectan sombras, ya que cada objeto puede proyectar su propio volumen de sombra de cualquier tamaño potencial en la pantalla. Consulte la optimización a continuación para obtener una discusión de las técnicas utilizadas para combatir el problema del tiempo de relleno.
Heidmann propuso que si las superficies frontales y posteriores de las sombras se renderizaban en pasadas separadas, se podía contar la cantidad de caras frontales y posteriores frente a un objeto utilizando el búfer de esténcil. Si la superficie de un objeto está en sombra, habrá más superficies de sombra frontales entre ella y el ojo que superficies de sombra posteriores. Sin embargo, si sus números son iguales, la superficie del objeto no está en sombra. La generación de la máscara de esténcil funciona de la siguiente manera:
Una vez logrado esto, todas las superficies iluminadas corresponderán a un 0 en el búfer de plantilla, donde los números de superficies frontales y posteriores de todos los volúmenes de sombra entre el ojo y esa superficie son iguales.
Este enfoque tiene problemas cuando el ojo mismo está dentro de un volumen de sombra (por ejemplo, cuando la fuente de luz se mueve detrás de un objeto). Desde este punto de vista, el ojo ve la cara posterior de este volumen de sombra antes que cualquier otra cosa, y esto agrega un sesgo de -1 a todo el búfer de esténcil, invirtiendo efectivamente las sombras. Esto se puede remediar agregando una superficie de "tapa" al frente del volumen de sombra que mira hacia el ojo, como en el plano de recorte frontal . Existe otra situación en la que el ojo puede estar en la sombra de un volumen proyectado por un objeto detrás de la cámara, que también debe taparse de alguna manera para evitar un problema similar. En las implementaciones más comunes, debido a que la tapa adecuada para el paso de profundidad puede ser difícil de lograr, el método de falla de profundidad (ver a continuación) puede tener licencia para estas situaciones especiales. Alternativamente, se puede dar al búfer de esténcil un sesgo de +1 para cada volumen de sombra en el que se encuentre la cámara, aunque realizar la detección puede ser lento.
Existe otro problema potencial si el buffer de la plantilla no tiene suficientes bits para acomodar la cantidad de sombras visibles entre el ojo y la superficie del objeto, porque utiliza aritmética de saturación . (Si en cambio utilizaran desbordamiento aritmético , el problema sería insignificante).
La prueba de paso de profundidad también se conoce como prueba de paso z , ya que el búfer de profundidad a menudo se denomina búfer z.
Alrededor del año 2000, varias personas descubrieron que el método de Heidmann podía funcionar en todas las posiciones de la cámara invirtiendo la profundidad. En lugar de contar las superficies de sombra que se encuentran delante de la superficie del objeto, las superficies que se encuentran detrás de él se pueden contar con la misma facilidad, con el mismo resultado final. Esto resuelve el problema de que el ojo esté en la sombra, ya que los volúmenes de sombra entre el ojo y el objeto no se cuentan, pero introduce la condición de que el extremo posterior del volumen de sombra debe estar cubierto, o las sombras terminarán faltando donde el volumen apunta hacia atrás, al infinito.
El método de falla de profundidad tiene las mismas consideraciones con respecto a la precisión del buffer de esténcil que el método de paso de profundidad. Además, al igual que el paso de profundidad, a veces se lo denomina método de falla z .
William Bilodeau y Michael Songy descubrieron esta técnica en octubre de 1998 y la presentaron en Creativity, una conferencia para desarrolladores de Creative Labs, en 1999. [2] Sim Dietrich presentó esta técnica tanto en GDC en marzo de 1999 como en Creativity a finales de 1999. [3] [4] Unos meses más tarde, William Bilodeau y Michael Songy presentaron una solicitud de patente estadounidense para la técnica el mismo año titulada "Método para renderizar sombras utilizando un volumen de sombra y un búfer de esténcil". [5] John Carmack de id Software descubrió el algoritmo de forma independiente en 2000 durante el desarrollo de Doom 3. [ 6]
Cualquiera de los tipos anteriores se puede aproximar con una variación exclusiva o , que no trata adecuadamente los volúmenes de sombras que se cruzan, pero ahorra un paso de renderizado (si no tiempo de relleno) y solo requiere un búfer de plantilla de 1 bit. Los siguientes pasos son para la versión de paso de profundidad: