Luces y sombras

Introducción

Las luces emiten luz que se mezcla con los materiales produciendo un resultado visible. La luz puede proceder de varias fuentes en una escena:

  • Desde el Material mismo en la forma de color de emisión (aunque esto no afecta a los objetos cercanos, salvo que la luz sea pre-calculada).
  • Nodos de luz: Directional, Omni y Spot.
  • Luz Ambiental en Environment.
  • Baked Light (read Baked lightmaps).

El color de emisión es una propiedad del material. Puedes leer más sobre ello en el tutorial Material Spatial.

Nodos de luz

Existen tres tipos de nodos de luz: Directional light, Omni light and Spot light. Cada uno tiene diferentes usos y se describirán en detalle a continuación, pero primero echemos un vistazo a los parámetros comunes para las luces:

../../_images/light_params.png

Cada uno tiene una función específica:

  • Color: Color base para la luz emitida.
  • Energy: Multiplicador de energía. Resulta útil para saturar luces o para trabajar con Light transport in game engines.
  • Indirect Energy: Multiplicador secundario utilizado con luz indirecta (rebote de luz). Esto funciona en luz bakeada o GIProbe.
  • Negative: La luz se vuelve sustractiva en lugar de aditiva. A veces es útil compensar manualmente algunas esquinas oscuras.
  • Specular: Afecta la intensidad del specular blob en los objetos afectados por esta luz. A cero, esta luz se convierte en una luz pura y difusa.
  • Bake Mode: Establece el modo de «bake» para la luz. Para más información vea Baked lightmaps
  • Cull Mask: Los objetos que se encuentren en las capas seleccionadas abajo serán afectadas por esta luz.

Shadow Mapping (Mapeo de sombras)

Las luces opcionalmente pueden proyectar sombras. Esto les da mayor realismo (la luz no llega a las zonas ocluidas), pero puede incurrir en un mayor coste de rendimiento. Hay una lista de parámetros de sombra genéricos, cada uno también tiene una función específica:

  • Enabled: Activa el mapeo de sombras con esta luz.
  • Color: Las áreas ocluidas son multiplicadas por este color. Por defecto es negro, pero puede ser cambiado para tintar las sombras.
  • Bias: Cuando este parámetro es muy pequeño, ocurre el auto sombreado. Cuando es muy largo, las sombras se separan de sus emisores. Ajústalo a lo que mejor funcione para ti.
  • Contact: Realiza un raycast corto en el espacio de la pantalla para reducir el hueco generado por el Bias. Esto sólo está disponible cuando se usa el backend GLES3.
  • Reverse Cull Faces: Algunas escenas funcionan mejor cuando el mapeo de sombras se representa con el face-culling invertido.

A continuación se muestra una imagen de cómo se ve el ajuste de bias. Los valores predeterminados funcionan para la mayoría de los casos, pero en general depende del tamaño y la complejidad de la geometría.

../../_images/shadow_bias.png

Finalmente, si las grietas no se pueden solucionar, la opción Contact puede ayudar:

../../_images/shadow_contact.png

Cualquier problema producido por el bias puede ser arreglado incrementando la resolución del mapa de sombras, aunque esto puede producir una pérdida de rendimiento en hardware de gama baja.

Directional light (Luz direccional)

Este es el tipo de luz más común y representa una fuente de luz muy lejana (como el sol). También es la luz menos costosa de calcular y debería utilizarse siempre que sea posible (aunque no es el mapa de sombras menos costoso de calcular, pero eso se explicará más adelante).

La luz direccional modela un número infinito de rayos de luz paralelos que cubren la escena completa. El nodo de luz direccional es representado por una gran flecha que indica la dirección de los rayos de luz. Sin embargo, la posición del nodo no afecta al comportamiento de luz y puede ser colocado en cualquier lugar de la escena.

../../_images/light_directional.png

Cada cara, cuyo lado frontal es golpeado por los rayos de luz se ilumina, mientras las otras permanecen oscuras. La mayoría de los tipos de luces tienen parámetros específicos, pero las luces direccionales son de naturaleza bastante simple y no los tienen.

Mapeo de sombras direccional

Para calcular mapas de sombra, la escena es renderizada (sólo profundidad) desde un punto de vista ortogonal que cubre toda la pantalla (o hasta la distancia máxima). Hay, sin embargo, un problema con este enfoque porque los objetos más cercanos a la cámara reciben sombras en bloque.

../../_images/shadow_blocky.png

Para solucionarlo, se utiliza una técnica llamada «Parallel Split Shadow Maps» (o PSSM). Esto divide el campo de visión en 2 o 4 áreas. Cada área tiene su propio mapa de sombras. Esto permite que áreas pequeñas cercanas al espectador tengan la misma resolución de sombra que un área enorme y lejana.

../../_images/pssm_explained.png

Con esto, las sombras se vuelven más detalladas:

../../_images/shadow_pssm.png

Para controlar PSSM, se exponen varios parámetros:

../../_images/directional_shadow_params.png

Cada distancia dividida se controla con respecto a la cámara o con el parámetro Max Distance (que establece una distancia máxima de sombreado), si es mayor que cero, por lo que 0.0 es la posición del ojo y 1.0 es donde la sombra termina a una distancia. Las divisiones están en el medio. Los valores predeterminados generalmente funcionan bien, pero ajustar la primera división un poco es común para dar más detalles a los objetos cercanos (como un personaje en un juego en tercera persona).

Asegúrate de indicar una Max Distance de sombra de acuerdo con las necesidades de la escena. Una distancia máxima baja obtendrá mejor calidad de sombras.

A veces, la transición entre una división y la siguiente puede verse mal. Para solucionar esto se puede activar la opción «Blend Splits», la que sacrifica detalles a cambio de transiciones más suaves:

../../_images/blend_splits.png

El parámetro «Normal Bias» se puede usar para corregir casos especiales de autosombreado cuando los objetos son perpendiculares a la luz. El único inconveniente es que hace que la sombra sea un poco más delgada.

../../_images/normal_bias.png

El parámetro «Bias Split Scale» puede controlar la inclinación adicional para las divisiones que están muy lejos. Si el sombreado automático ocurre solo en las divisiones lejanas, este valor puede corregirlas.

Por último, el «Depth Range» tiene dos ajustes:

  • Stable: Mantiene la sombra estable mientras la cámara se mueve, y los bloques que aparecen en el contorno cuando están cerca de los bordes sombreados permanecen en su lugar. Este es el valor predeterminado y generalmente deseado, pero reduce la resolución de sombra efectiva.
  • Optimized: Intenta alcanzar la resolución máxima disponible en un momento dado. Esto puede provocar un efecto de «sierra en movimiento» en los bordes sombreados, pero al mismo tiempo la sombra se ve más detallada (por lo que este efecto puede ser lo suficientemente sutil como para ser perdonado).

Solo experimenta qué configuración funciona mejor en tu escena.

El tamaño del mapa de sombras para luces direccionales puede ser cambiado en Project Settings -> Rendering -> Quality:

../../_images/project_setting_shadow.png

Aumentarlo puede solucionar problemas generados por el bias pero reduce el rendimiento. Ajustar el mapeo de sombras es un arte.

Omni light (luz omnidireccional)

Omni light es un punto que emite luz esféricamente en todas las direcciones hasta un radio dado.

../../_images/light_omni.png

En la vida real, la atenuación de la luz es una función inversa, lo que significa que las luces omnidireccionales no tienen radio. Esto es un problema porque calcular un gran número de este tipo de luces se volvería costoso.

Para resolver esto, se introduce un Rango (Range) junto con una función de atenuación (Attenuation).

../../_images/light_omni_params.png

Estos dos parámetros permiten ajustar cómo funciona esto visualmente para encontrar resultados estéticamente agradables.

../../_images/light_attenuation.png

Mapeo de sombras omnidireccional

El mapeo de sombras para una Omni light es relativamente sencillo. Lo principal a considerar es el algoritmo que se utilizará para renderizarlo.

Las sombras omnidireccionales pueden ser renderizadas utilizando «Dual Paraboloid» o «Cube Mapped «. El primero se renderiza rápidamente, pero puede causar deformaciones, mientras que el segundo es más correcto, pero más costoso.

../../_images/shadow_omni_dp_cm.png

Si los objetos que se renderizan son en su mayoría irregulares, Dual Paraboloid suele ser suficiente. En cualquier caso, como estas sombras se almacenan en caché en un atlas de sombra (más sobre eso al final), puede que no signifique una diferencia en el rendimiento para la mayoría de las escenas.

Spot light (luz focal)

Las luces focales (o puntuales) son similares a las omnidireccionales (omni lights), excepto porque emiten luz solamente en un cono (o «corte»). Son útiles para simular linternas, luces de coche, reflectores, focos, etc. Este tipo de luz además se atenúa en la dirección opuesta a la que apunta.

../../_images/light_spot.png

Las luces focales comparten los mismos parámetros Range y Attenuation con OmniLight, y añade dos más:

  • Angle: El ángulo de apertura de la luz
  • Angle Attenuation: La atenuación del cono, que ayuda a suavizar los bordes del cono.

Mapeo de sombras focal

Las luces focales no necesitan ningún parámetro para el mapeo de sombras. Ten en cuenta que, para ángulos de apertura mayores de 80 grados, las sombras dejan de funcionar y resulta más conveniente utilizar luces omnidireccionales.

Shadow atlas (atlas de sombra)

A diferencia de las luces direccionales, que tienen su propia textura de sombra, las luces omnidireccionales y focales se asignan a espacios de un atlas de sombra. Este atlas se puede configurar en Project Settings -> Rendering -> Quality -> Shadow Atlas.

../../_images/shadow_atlas.png

La resolución se aplica a todo el Atlas de las Sombras. Este atlas se divide en cuatro cuadrantes:

../../_images/shadow_quadrants.png

Cada cuadrante se puede subdividir para asignar cualquier número de mapas de sombras; la siguiente es la subdivisión predeterminada:

../../_images/shadow_quadrants2.png

La lógica de asignación es simple. El tamaño de mapa de sombras más grande (cuando no se utiliza ninguna subdivisión) representa una luz del tamaño de la pantalla (o mayor). Las subdivisiones (mapas más pequeños) representan sombras para las luces que están más lejos de la vista y proporcionalmente más pequeñas.

En Cada fotograma, se realiza el siguiente procedimiento para todas las luces:

  1. Se comprueba si la luz está en un espacio del tamaño correcto. Si no es así, se vuelve a renderizar y se mueve a un espacio más grande o más pequeño.
  2. Se comprueba si ha cambiado algún objeto que afecte al mapa de sombras. Si esto sucedió, se renderiza de nuevo la luz.
  3. Si no ha ocurrido nada de lo anterior, no se hace nada, y la sombra queda intacta.

Si los espacios de un cuadrante están llenos, las luces son devueltas a espacios más pequeños, dependiendo del tamaño y la distancia.

Esta estrategia de asignación funciona para la mayoría de los juegos, pero es posible que desee utilizar una diferente en algunos casos (por ejemplo, un juego top-down donde todas las luces tienen más o menos el mismo tamaño y todos los cuadrantes pueden tener la misma subdivisión).

Calidad del filtro de sombras

La calidad del filtro de las sombras se puede ajustar. Esto se puede encontrar en Project Settings -> Rendering -> Quality -> Shadows. Godot soporta los filtros PCF5, PCF13, y también permite no filtrar.

../../_images/shadow_pcf1.png

Esto influye en el efecto de pixelado del borde de la sombra:

../../_images/shadow_pcf2.png