Up to date

This page is up to date for Godot 4.2. If you still find outdated information, please open an issue.

Luces 2D y sombras

Introducción

Por defecto, las escenas 2D en Godot no poseen sombreado, sin luces ni sombras visibles. Mientras que esto es más rápido de renderizar, las escenas sin sombreado pueden lucir sosas. Godot nos brinda la habilidad para usar en luces y sombras 2D en tiempo real, las que pueden mejorar considerablemente la sensación de profundidad en su proyecto.

Sin luces o sombras 2D, la escena no posee sombreado

Sin luces o sombras 2D, la escena no posee sombreado

Luces 2D habilitadas (sin sombras)

Luces 2D habilitadas (sin sombras)

Luces y sombras 2D habilitadadas

Luces y sombras 2D habilitadadas

Nodos

Existen varios nodos involucrados en una configuración de iluminación 2D completa:

CanvasModulate es utilizado para oscurecer la escena al especificar un color que actuará como el color "ambiental" base. Este es el color de iluminación final para áreas que no son alcanzadas por ninguna luz 2D. Sin un nodo CanvasModulate, la escena final luciría demasiado brillante, debido a que las luces 2D sólo abrillantarían la apariencia sin sombreado existente (que ya aparece completamente iluminada).

Los Sprite2Ds son usados para mostrar las texturas de los puntos de luz, el fondo y los generadores de sombra.

Los PointLight2Ds son usados para iluminar la escena. El modo en que una luz funciona es sumando la textura seleccionada al resto de la escena para simular la iluminación.

Los LightOccluder2D se utilizan para decirle al shader qué parte de la escena debe producir sombra. Estos elementos pueden ubicarse como nodos independientes o ser parte de un nodo TileMap.

La sombra aparece sólo en áreas cubiertas por el PointLight2D y su dirección está basada en el centro del nodo Light.

Nota

El color de fondo no recibe iluminación. Si desea que la luz sea proyectada en el fondo, necesita añadir una representación visual para el fondo, como un Sprite2D.

La propiedad Region de Sprite2D puede ser útil para crear rápidamente una textura de fondo repetitiva, pero recuerde también configurar Texture > Repeat a Enabled en las propiedades de Sprite2D.

Luces puntuales

Las luces puntuales (también llamadas luces posicionales) son el elemento más común en iluminación 2D. Las luces puntuales pueden ser usadas para representar luz proveniente de antorchas, fuego, proyectiles, etc.

PointLight2D ofrece las siguientes propiedades para modificar en el inspector:

  • Texture: La textura a utilizar como fuente de luz. El tamaño de la textura determina el tamaño de la luz. La textura puede tener un canal alfa, el que es útil al utilizar el modo de fusión Mix de Light2D, pero no es requerido si se utilizan los modos de fusión Add (por defecto) o Subtract.

  • Offset: El offset para la textura con iluminación. A diferencia de cuando mueve el nodo de luz, cambiar el offset no provoca que las sombras se muevan.

  • Texture Scale: El multiplicador para el tamaño de las luces. Valores más altor harán que la luz se extienda más lejos. Luces de mayor tamaño tendrán un mayor coste de rendimiento puesto que afectan más pixeles en la pantalla, así que considere esto antes de incrementar el tamaño de una luz.

  • Height: La altura virtual de una luz con respecto al mapeo normal. Por defecto, la luz se encuentra muy cerca de superficies que reciben luces. Esto hará que la iluminación sea difícilmente visible si se está utilizando mapeo normal, así que considere incrementar este valor. Ajustar la altura de una luz solo provoca una diferencia visible en superficies que utilizan mapeo normal.

Si no tiene una textura prefabricada para usar en una luz, puede usar esta textura de luz puntual "neutral" (clic derecho > Guardar Imagen Como…):

Textura neutral de luz puntual

Textura neutral de luz puntual

Si necesita una difuminación diferente, puede crear proceduralmente una textura al asignar New GradientTexture2D en la propiedad Texture de la luz. Después de crear el recurso, expanda su sección Fill y configure el modo de llenado a Radial. Luego tendrá que ajustar la gradiente misma para que empiece desde blanco opaco hasta blanco transparente, y mover su posición de inicio para que esté en el centro.

Directional light (Luz direccional)

Algo nuevo en Godot 4.0 es la capacidad de tener iluminación direccional en 2D. La iluminación direccional se utiliza para representar la luz del sol o la luz de la luna. Los rayos de luz se proyectan paralelos entre sí, como si el sol o la luna estuvieran infinitamente lejos de la superficie que recibe la luz.

DirectionalLight2D tiene las siguientes propiedades:

  • Height: La altura virtual de una luz con respecto al mapeo normal (0.0 = paralelo a las superficies, 1.0 = perpendicular a las superficies). Por defecto, la luz se encuentra completamente paralela con las superficies que reciben luces. Esto hará que la iluminación sea difícilmente visible si se está utilizando mapeo normal, así que considere incrementar este valor. Ajustar la altura de una luz solo provoca una diferencia visible en superficies que utilizan mapeo normal. Height no afecta la apariencia de las sombras.

  • Max Distance: La máxima distancia desde el centro de la cámara hasta los objetos antes que sus sombras se eliminen (en píxeles). Bajar este valor puede prevenir que objetos ubicados fuera de la cámara proyecten sombras (tambien mejorando el rendimiento). El zoom de Camera2D no se toma en cuenta por Max Distance, lo que significa que a mayor zoom las sombras se verán desaparacer antes al acercar el zoom a un cierto punto.

Nota

Las sombras direccionales siempre parecerán ser infinitamente largas, sin importar el tamaño del valor de la propiedad Height. Esto es una limitación del renderizado de sombras usado por las luces 2D en Godot.

Para tener sombras direccionales que no son infinitamente largas, deberías desabilitar sombras en el DirectionalLight2D y usar un shader personalizado que lee desde el campo de distancia firmado 2D en su lugar. Este campo de distancia es automáticamente generado desde los nodos LightOccluder2D presentes en la escena.

Propiedades comunes de luces

Ambos, PointLight2D y DirectionalLight2D, ofrecen propiedades en común que son parte de la clase base de Light2D:

  • Habilitada: Permite cambiar la visibilidad de la luz. Deshabilitar esta propiedad no oculta las luces generadas, a diferencia de ocultar el nodo de luz.

  • Editor Only: Si está habilitado, la luz solo será visible en el editor. Estará deshabilitado automáticamente al ejecutar el proyecto actual.

  • Color: El color de la luz.

  • Energía: El multiplicador de la intensidad de la luz. Valores más altos resultará en una luz más brillante.

  • Blend Mode: La fórmula de mezcla utilizada para los cálculos de luz. Por lo general Add (suma) cubre la mayoría de casos. Subtract (resta) puede usarse para luces negativas, las cuales no son precisas pero pueden usarse para efectos especiales. El modo de mezcla Mix (mezcla) combina el valor de los píxeles correspondientes a la textura de la luz con los valores de los píxeles debajo de estos usando una interpolación lineal.

  • Range > Z Min: El valor de índice en Z más bajo afectado por la luz.

  • Range > Z Max: El valor de índice en Z más alto afectado por la luz.

  • Rango > Capa Mín: La capa visual más baja afectada por la luz.

  • Rango > Capa Máx: La capa visual más alta afectada por la luz.

  • Range > Item Cull Mask: Controla qué nodos recibirán luz de este nodo, dependiendo de las Occluder Light Mask (máscaras de iluminación) habilitadas. Esto puede utilizarse para evitar que ciertos objetos reciban luz.

Configurando sombras

No habrá ningún cambio visual en un nodo PointLight2D o DirectionalLight2D después de habilitar la propiedad Shadow > Enabled. Esto es debido a que no hay nodos en tu escena que tengan algún occluder todavía, los cuales son usados como base para proyectar sombras.

Para que las sombras aparezcan en la escena, los nodos LightOcclured2D deben estar en la escena. Estos nodos también deben tener polígonos bloqueadores de luz que estén diseñados para coincidir con el borde del sprite.

Junto a su recurso polígono (que debe asignarse para tener algún efecto visual), los nodos LightOccluder2D tienen 2 propiedades:

  • Colisión SDF: Si está habilitada, el bloqueador será parte del signed distance field (campo de distancia con signo) que podrá ser utilizado en shaders personalizados. Cuando se usa en shaders personalizados que lean de este SDF, habilitarlo no produce diferencias visuales ni tiene costo de rendimiento, así que por comodidad se encuentra habilitado por defecto.

  • Occluder Light Mask: Esta es usada en conjunto con la propiedad Shadow > Item Cull Mask de PointLight2D y DirectionalLight2D para controlar qué objetos producen sombras para cada luz. Esto puede utilizarse para prevenir que ciertos objetos generen sombra.

Hay dos modos de crear bloqueadores de luz:

Generando automáticamente un bloqueador de luz

Los oclusores pueden ser creados automáticamente por nodos Sprite2D seleccionando el nodo, haciendo click en el menú Sprite2D en la parte superior del editor 2D y luego eligiendo Crear hermano LightOccluder2D.

En el diálogo que aparece, un contorno rodeará los bordes de tu sprite. Si el contorno coincide de cerca con los bordes del sprite, puedes hacer click en OK. Si el contorno está muy lejos de los bordes del sprite (o se está "comiendo" los bordes del sprite), ajusta Grow (pixeles) (agrandar) y Shrink (pixeles) (contraer), entonces haz click en Actualizar Vista Previa. Repite esta operación hasta que obtengas resultados satisfactorios.

Dibujando manualmente un oclusor de luz

Crea un nodo LightOccluder2D, luego selecciona el nodo y haz clic en el botón "+" en la parte superior del editor 2D. Cuando te pida para crear un recurso polígono, elige Si. Entonces ahora podrás comenzar a dibujar el polígono bloqueador haciendo clic para crear nuevos puntos. Puedes remover puntos existentes con clic derecho en ellos y puedes crear nuevos puntos en a linea existente haciendo click en la línea y luego arrastrando.

Las siguientes propiedades pueden establecerse en luces 2D que tienen sombras habilitadas:

  • Color: El color de las áreas sombreadas. Por defecto, las áreas con sombra son completamente negras, pero esto se puede cambiar por razones artísticas. El canal alfa del color controla cuánto de la sombra entinta al color especificado.

  • Filter: El modo de filtro a usar para sombras. El valor por defecto None (ninguno) es el que renderiza más rápido y sirve bien para juegos con estética pixel art (dada su característica "cuadrada"). Si quieres una sombra suave, en su lugar utiliza PCF5. PCF13 es aún más suave pero es la que más demanda al renderizador. PCF13 debe utilizarse sólo para unas pocas luces debido a su alto costo de renderizado.

  • Filter Smooth: Controla cuánto suavizado es aplicado a las sombras cuando Filter es colocado en PCF5 o PCF13. Valores altos resultarán en sombras más suaves pero puede causar efectos de banda visibles (especialmente con PCF5).

  • Item Cull Mask: Controla cuáles nodos LightOccluder2D producen sombra, dependiendo de sus respectivas propiedades Occluder Light Mask.

Sombras duras

Sombras duras

Sombras suaves (PCF13, Filter Smooth 1.5)

Sombras suaves (PCF13, Filter Smooth 1.5)

Sombras suaves con artefactos de líneas ocasionado por un Filter Smooth muy alto (PCF5, FilterSmooth 4)

Sombras suaves con artefactos de líneas ocasionado por un Filter Smooth muy alto (PCF5, FilterSmooth 4)

Orden de dibujado de bloqueadores de luz

Los LightOccluder2D siguen el orden de dibujado 2D normal. Esto es importante para luces 2D, ya que este es el modo en que podrás controlar si el bloqueador deberá tapar el sprite mismo o no.

Item Cull Mask: Controla qué nodos LightOccluder2D poducirán sombras, dependiendo de sus respectivas propiedades Occluder Light Mask.

Si el nodo LightOccluder2D es un hijo del sprite, el bloqueador tapará el sprite mismo si Show Behind Parent (mostrar detrás del padre) está deshabilitado en el nodo LightOccluder2D (lo que es así por defecto).

Mapas normales y especulares

Los mapas de normales y especulares pueden aumentar la sensación de profundidad en tu iluminación 2D. Simimlar a como esos funcionan en el renderizado 3D, los mapas de normales pueden ayudar a hacer que la iluminación se vea menos plana y que varíe la intencidad dependiendo de la dirección en que la superficie recibe luz (trabajando por pixel). Mapas especulares mejoran aún más el aspecto visual haciendo que algo de la luz se refleje al observador.

Ambas, PointLight2D y DirectionalLight2D soportan mapas de normales y especulares. Desde Godot 4.0, los mapas de normales y especulares pueden asignarse a cualquier elemento 2D, incluyendo nodos que heredan de Node2D o Control.

Un mapa de normales representa la dirección hacia la cual cada pixel "apunta". Esta información es entonces utilizada por el motor para aplicar correctamente la iluminación en superficies 2D de un modo físicamente razonable. Los mapas de normales sos típicamente creados desde mapas de altura hechos a mano, pero también pueden ser generados desde otras texturas.

Un mapa especular define cuánto de cada pixel deberá reflejar la luz (y de qué color, si el mapa especular contiene colores). Valores más brillantes resultarán en un reflejo brillante en un punto dado de la textura. Los mapas especulares son normalemente creados con edición manual utilizando la textura difusa como base.

Truco

Si no tienes un mapa de normales o especular para tus sprites, puedes generarlos usando la herramienta libre y de código abierto Laigter <https://azagaya.itch.io/laigter>.

To set up normal maps and/or specular maps on a 2D node, create a new CanvasTexture resource for the property that draws the node's texture. For example, on a Sprite2D:

Creando un recurso CanvasTexture para un nodo Sprite2D

Creando un recurso CanvasTexture para un nodo Sprite2D

Expand the newly created resource. You can find several properties you will need to adjust:

  • Diffuse > Texture: The base color texture. In this property, load the texture you're using for the sprite itself.

  • Normal Map > Texture: The normal map texture. In this property, load a normal map texture you've generated from a height map (see the tip above).

  • Specular > Texture: The specular map texture, which controls the specular intensity of each pixel on the diffuse texture. The specular map is usually grayscale, but it can also contain color to multiply the color of reflections accordingly. In this property, load a specular map texture you've created (see the tip above).

  • Specular > Color: The color multiplier for specular reflections.

  • Specular > Shininess: The specular exponent to use for reflections. Lower values will increase the brightness of reflections and make them more diffuse, while higher values will make reflections more localized. High values are more suited for wet-looking surfaces.

  • Texture > Filter: Can be set to override the texture filtering mode, regardless of what the node's property is set to (or the Rendering > Textures > Canvas Textures > Default Texture Filter project setting).

  • Texture > Repeat: Can be set to override the texture filtering mode, regardless of what the node's property is set to (or the Rendering > Textures > Canvas Textures > Default Texture Repeat project setting).

After enabling normal mapping, you may notice that your lights appear to be weaker. To resolve this, increase the Height property on your PointLight2D and DirectionalLight2D nodes. You may also want to increase the lights's Energy property slightly to get closer to how your lighting's intensity looked prior to enabling normal mapping.

Using additive sprites as a faster alternative to 2D lights

If you run into performance issues when using 2D lights, it may be worth replacing some of them with Sprite2D nodes that use additive blending. This is particularly suited for short-lived dynamic effects, such as bullets or explosions.

Additive sprites are much faster to render, since they don't need to go through a separate rendering pipeline. Additionally, it is possible to use this approach with AnimatedSprite2D (or Sprite2D + AnimationPlayer), which allows for animated 2D "lights" to be created.

However, additive sprites have a few downsides compared to 2D lights:

  • The blending formula is inaccurate compared to "actual" 2D lighting. This is usually not a problem in sufficiently lit areas, but this prevents additive sprites from correctly lighting up areas that are fully dark.

  • Additive sprites cannot cast shadows, since they are not lights.

  • Additive sprites ignore normal and specular maps used on other sprites.

To display a sprite with additive blending, create a Sprite2D node and assign a texture to it. In the inspector, scroll down to the CanvasItem > Material section, unfold it and click the dropdown next to the Material property. Choose New CanvasItemMaterial, click the newly created material to edit it, then set Blend Mode to Add.