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).
  • Light Nodes: 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.

Light nodes

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.
  • Energía: Multiplicador de energía. Resulta útil para luces saturadas 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 a la intensidad de specular blob en los objetos afectados por esta luz. A cero, esta luz se convierte en una luz pura y difusa.
  • Bake Mode: Sets the bake mode for the light. For more information see Baked lightmaps
  • Cul Mask: Los objetos que se encuentren bajo las capas seleccionadas serán afectadas por esta luz.

Shadow Mapping

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: Performs a short screen-space raycast to reduce the gap generated by the bias. Contact shadows are only available when using the GLES3 backend.
  • 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 resolver, la opción Contact puede ayudar:

../../_images/shadow_contact.png

Cualquier tipo de problema de inclinaciñon siempre se puede corregir incrementando la resolución del mapa de sombra, aunque eso puede llevar a una disminución del rendimiento en el hardware de gama baja.

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 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 la view frustum 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 son 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 sombra Max Distance 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 sombreado automático 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).

Experimenta para encontrar el que mejor funcione 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 arreglar problemas de inclinación pero reduce el rendimiento. El mapeo de sombras es un elemento que requiere mucho ajuste fino.

Omni luz

Omni light es una fuente puntual que emite luz esférica 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 junto con una función de atenuación.

../../_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

Omni shadow mapping

Omni light shadow mapping is relatively straightforward. The main issue that needs to be considered is the algorithm used to render it.

Omni Shadows can be rendered as either «Dual Paraboloid» or «Cube Mapped». The former renders quickly, but can cause deformations, while the later is more correct, but costlier.

../../_images/shadow_omni_dp_cm.png

If the objects being rendered are mostly irregular, Dual Paraboloid is usually enough. In any case, as these shadows are cached in a shadow atlas (more on that at the end), it may not make a difference in performance for most scenes.

Spot light

Spot lights are similar to omni lights, except they emit light only into a cone (or «cutoff»). They are useful to simulate flashlights, car lights, reflectors, spots, etc. This type of light is also attenuated towards the opposite direction it points to.

../../_images/light_spot.png

Spot lights share the same Range and Attenuation as OmniLight, and add two extra parameters:

  • Angle: The aperture angle of the light
  • Angle Attenuation: The cone attenuation, which helps soften the cone borders.

Spot shadow mapping

Spots don’t need any parameters for shadow mapping. Keep in mind that, at more than 89 degrees of aperture, shadows stop functioning for spots, and you should consider using an Omni light instead.

Shadow atlas

Unlike Directional lights, which have their own shadow texture, Omni and Spot lights are assigned to slots of a shadow atlas. This atlas can be configured in Project Settings -> Rendering -> Quality -> Shadow Atlas.

../../_images/shadow_atlas.png

The resolution applies to the whole Shadow Atlas. This atlas is divided into four quadrants:

../../_images/shadow_quadrants.png

Each quadrant can be subdivided to allocate any number of shadow maps; the following is the default subdivision:

../../_images/shadow_quadrants2.png

The allocation logic is simple. The biggest shadow map size (when no subdivision is used) represents a light the size of the screen (or bigger). Subdivisions (smaller maps) represent shadows for lights that are further away from view and proportionally smaller.

Every frame, the following procedure is performed for all lights:

  1. Check if the light is on a slot of the right size. If not, re-render it and move it to a larger/smaller slot.
  2. Check if any object affecting the shadow map has changed. If it did, re-render the light.
  3. If neither of the above has happened, nothing is done, and the shadow is left untouched.

If the slots in a quadrant are full, lights are pushed back to smaller slots, depending on size and distance.

This allocation strategy works for most games, but you may want to use a separate one in some cases (for example, a top-down game where all lights are around the same size and quadrants may all have the same subdivision).

Shadow filter quality

The filter quality of shadows can be tweaked. This can be found in Project Settings -> Rendering -> Quality -> Shadows. Godot supports no filter, PCF5 and PCF13.

../../_images/shadow_pcf1.png

It affects the blockyness of the shadow outline:

../../_images/shadow_pcf2.png