11/08/2020
Las sombras son uno de los elementos más importantes para dotar de realismo y profundidad a cualquier escena en un videojuego. Sin ellas, los objetos parecen flotar en el espacio y el mundo se siente plano y sin vida. Una de las técnicas más fundamentales y extendidas para generar sombras dinámicas en tiempo real es el mapa de sombras o shadow mapping. Concebida por Lance Williams en 1978, esta metodología ha evolucionado hasta convertirse en un pilar de los gráficos por computadora, presente en incontables títulos de PC y consolas.

A diferencia de las sombras precalculadas (lightmaps), que son estáticas, el shadow mapping permite que las sombras reaccionen dinámicamente a los movimientos de los objetos y las fuentes de luz. Su principio es ingeniosamente simple pero su implementación correcta puede ser un verdadero desafío, lleno de matices y problemas que requieren soluciones creativas. En este artículo, desglosaremos cómo funciona esta técnica, desde su algoritmo básico hasta los métodos avanzados para lograr resultados de alta calidad.
¿En qué consiste el Shadow Mapping?
La idea central del shadow mapping es sorprendentemente intuitiva. Imagina que te sitúas en la misma posición que una fuente de luz. Todo lo que puedas ver desde ese punto estará iluminado. Por el contrario, cualquier cosa que quede oculta detrás de otro objeto estará en sombra. Este es exactamente el principio que utiliza el shadow mapping.
La técnica consiste en renderizar la escena dos veces. En la primera pasada, se genera una imagen desde el punto de vista de la luz. Sin embargo, en lugar de guardar información de color, lo que se almacena es la profundidad de cada objeto con respecto a la luz. Este mapa de profundidad, conocido como el mapa de sombras (shadow map), es esencialmente una textura que nos dice qué tan cerca está el objeto más próximo a la luz en cada dirección. En la segunda pasada, se renderiza la escena desde la perspectiva de la cámara del jugador. Para cada píxel que se va a dibujar, se calcula su distancia a la fuente de luz y se compara con el valor de profundidad almacenado en el mapa de sombras. Si la distancia del píxel actual es mayor que la guardada en el mapa, significa que hay otro objeto más cerca de la luz bloqueando el paso, y por lo tanto, ese píxel está en sombra.
El Algoritmo: Un Proceso de Dos Pasos
Para entender mejor el proceso, dividámoslo en las dos fases principales que componen el algoritmo de shadow mapping.
Paso 1: La Creación del Mapa de Sombras
Esta es la primera pasada de renderizado. El objetivo es crear esa textura de profundidad desde la perspectiva de la luz.
- Punto de Vista: La escena se renderiza desde la posición y dirección de la fuente de luz que proyectará la sombra. La matriz de proyección utilizada depende del tipo de luz. Para una luz direccional (como el sol), se usa una proyección ortográfica, ya que los rayos de luz son paralelos. Para luces de foco (spotlights) o puntuales (point lights), se usa una proyección en perspectiva.
- Almacenamiento de Profundidad: Durante este renderizado, se desactivan todos los cálculos de color, texturizado e iluminación compleja. Lo único que nos interesa es el búfer de profundidad (z-buffer). El contenido de este búfer se guarda en una textura especial, que es nuestro mapa de sombras. Esta optimización hace que esta pasada sea significativamente más rápida que un renderizado normal.
- Actualización: Este mapa de sombras debe regenerarse cada vez que la luz o algún objeto que proyecta sombras se mueve. Si solo la cámara del jugador se mueve, el mapa de sombras puede reutilizarse, ahorrando un valioso tiempo de cómputo.
Paso 2: El Sombreado de la Escena Final
Una vez que tenemos nuestro mapa de sombras, realizamos la segunda pasada de renderizado, esta vez desde la perspectiva de la cámara del jugador.
- Transformación al Espacio de la Luz: Para cada fragmento (o píxel) de la escena, su posición en el mundo 3D se transforma a las coordenadas que tendría si se viera desde la luz. Esto se hace utilizando la misma matriz de vista y proyección que se usó en el primer paso.
- La Comparación de Profundidad: Con las coordenadas en el espacio de la luz, se utiliza la posición X e Y para buscar el valor de profundidad correspondiente en la textura del mapa de sombras. Luego, se compara este valor almacenado con la profundidad Z del fragmento actual (también en el espacio de la luz).
- Decisión de Sombra: Si la profundidad del fragmento actual es mayor que la profundidad guardada en el mapa, el fragmento está en sombra. De lo contrario, está iluminado. En función de este resultado, el shader aplica el cálculo de iluminación completo o solo una luz ambiental tenue para simular la oscuridad.
Desafíos Comunes y sus Soluciones
Aunque el concepto es simple, la implementación del shadow mapping básico presenta varios artefactos visuales que pueden arruinar la calidad de la imagen. Afortunadamente, existen soluciones bien conocidas para estos problemas.
Acné de Sombra (Shadow Acne)
Este es el problema más común. Se manifiesta como patrones de rayas o muaré en superficies que deberían estar completamente iluminadas. Ocurre debido a imprecisiones de punto flotante y a que la superficie que proyecta la sombra está compitiendo consigo misma en el mapa de sombras. La solución más simple es aplicar un pequeño bias (sesgo) al comparar las profundidades. Es decir, restamos un valor muy pequeño a la profundidad del fragmento actual antes de la comparación. Esto "empuja" la superficie ligeramente lejos de la luz en el test, evitando que se auto-sombree. Un bias más avanzado puede ajustarse según la pendiente de la superficie, aplicando un sesgo mayor en polígonos que están casi paralelos a la dirección de la luz.

Efecto Peter Panning
Este artefacto, llamado así porque los objetos parecen volar como Peter Pan, ocurre cuando el bias es demasiado grande. La sombra aparece desconectada de su objeto, creando un espacio vacío entre ellos. La solución es encontrar un equilibrio cuidadoso para el valor del bias o utilizar técnicas más robustas como el bias basado en la pendiente. Otra solución es asegurarse de que la geometría no sea excesivamente delgada.
Aliasing y Bordes Dentados
Dado que el mapa de sombras es una textura, tiene una resolución finita. Esto provoca que los bordes de las sombras se vean pixelados y dentados, un efecto conocido como aliasing. Aumentar la resolución del mapa de sombras ayuda, pero consume más memoria y rendimiento. La solución más efectiva es aplicar técnicas de filtrado.
Mejorando la Calidad: Técnicas de Suavizado
Para combatir el aliasing y lograr sombras con bordes suaves y realistas, se han desarrollado múltiples técnicas de filtrado.
PCF (Percentage-Closer Filtering)
En lugar de tomar una sola muestra del mapa de sombras, PCF toma varias muestras de los píxeles vecinos. Para cada muestra, realiza la comparación de profundidad. El resultado final no es un simple "en sombra o no", sino un promedio de los resultados de las comparaciones. Por ejemplo, si 2 de 4 muestras están en sombra, el píxel recibirá un 50% de sombra. Esto crea una transición suave y difuminada en los bordes de la sombra, eliminando el aspecto dentado.
Muestreo Poisson y Variantes
Para un suavizado aún mejor, se pueden tomar múltiples muestras en un patrón pseudoaleatorio (como un disco de Poisson) alrededor de la coordenada original. Esto distribuye el error de muestreo como un ruido de alta frecuencia, que es mucho menos perceptible para el ojo humano que los patrones de aliasing. El resultado es una penumbra mucho más natural y suave.
Tabla Comparativa de Técnicas de Sombreado
Para resumir, aquí hay una comparación de algunas técnicas clave:
| Técnica | Ventaja Principal | Desventaja Principal | Ideal para |
|---|---|---|---|
| Shadow Mapping Básico | Rápido y fácil de implementar. | Sufre de aliasing severo y otros artefactos. | Prototipos o juegos con estilos gráficos simples. |
| PCF (Percentage-Closer Filtering) | Produce bordes de sombra suaves. | Mayor coste computacional debido a las múltiples muestras de textura. | La mayoría de los juegos modernos como estándar de calidad. |
| CSM (Cascaded Shadow Maps) | Alta calidad de sombras en escenas grandes y abiertas. | Complejidad de implementación y gestión de múltiples mapas de sombras. | Juegos de mundo abierto con luces direccionales (sol). |
Preguntas Frecuentes (FAQ)
¿Por qué mis sombras se ven pixeladas o en bloques?
Eso es el aliasing, causado por una resolución insuficiente del mapa de sombras. Puedes solucionarlo aumentando la resolución de la textura del mapa de sombras en la configuración de calidad de tu juego o motor gráfico, o implementando técnicas de filtrado como PCF para suavizar los bordes.
¿El Shadow Mapping consume muchos recursos?
Sí, puede ser costoso. Requiere al menos una pasada de renderizado adicional de la geometría que proyecta sombras por cada luz. El coste aumenta con la complejidad de la escena, la resolución del mapa de sombras y el número de muestras utilizadas en el filtrado. Por eso, los desarrolladores a menudo limitan el número de luces que pueden proyectar sombras dinámicas en una escena.
¿Cuál es la diferencia entre Shadow Mapping y las sombras de Ray Tracing?
El shadow mapping es una técnica de rasterización que funciona proyectando la geometría sobre una textura de profundidad. Es rápida pero propensa a artefactos. El Ray Tracing (trazado de rayos), por otro lado, simula el camino real de los rayos de luz. Para determinar si un punto está en sombra, lanza un rayo desde ese punto hacia la fuente de luz para ver si algo lo bloquea. Esto produce sombras perfectamente nítidas y físicamente correctas (incluyendo penumbras suaves), pero es computacionalmente mucho más intensivo.
Si quieres conocer otros artículos parecidos a Shadow Mapping: El Arte de las Sombras en 3D puedes visitar la categoría Juegos.
