Parte: 2 — Desarrollo 3D: motores, escenas y transformaciones · Fuente: Godot Engine 4 — Documentación oficial: Lights and shadows ⏱️ Duración estimada: 60 min · Nivel: Intermedio
Iluminar una escena 3D en Godot 4 combinando los tres tipos de luz —DirectionalLight3D, OmniLight3D y SpotLight3D— y activar sombras de calidad, aprendiendo a ajustar energía, color y el parámetro bias para eliminar el acné de sombra sin sacrificar el rendimiento.
Al finalizar, el alumno podrá:
light_energy y light_color para dar carácter a una escena.shadow_enabled y ajustar su calidad.| # | Tema | Por qué importa |
|---|---|---|
| 1 | DirectionalLight3D | Simula el sol; ilumina toda la escena en paralelo. |
| 2 | OmniLight3D | Bombilla que irradia en todas direcciones con alcance. |
| 3 | SpotLight3D | Foco cónico dirigido, como una linterna. |
| 4 | Energía y color | Definen intensidad y temperatura de la luz. |
| 5 | Sombras (shadow_enabled) | Dan profundidad y anclan objetos al suelo. |
| 6 | Bias y acné de sombra | Evitan patrones de moiré en superficies iluminadas. |
| 7 | Rango y atenuación | Controlan hasta dónde alcanza omni/spot. |
| 8 | Coste y rendimiento | Cada sombra dinámica cuesta; hay que dosificarlas. |
omni_range. Clave: ideal para bombillas y antorchas.spot_range y spot_angle. Clave: simula focos y linternas.Usa Godot 4.x con una escena que tenga suelo y varios objetos con relieve (esferas, cajas, una rampa) para apreciar las sombras. Conviene tener un WorldEnvironment con luz ambiental baja para que las sombras sean visibles. Consulta la guía de luces y sombras en https://docs.godotengine.org/en/stable/tutorials/3d/lights_and_shadows.html y la API de Light3D en https://docs.godotengine.org/en/stable/classes/class_light3d.html. Motor: https://godotengine.org/download.
Node3D con un suelo (MeshInstance3D plano) y coloca 4-5 esferas y cajas encima a distintas alturas.DirectionalLight3D y rótalo con rotation_degrees = Vector3(-50, -30, 0) para simular un sol de tarde.OmniLight3D sobre una caja (por ejemplo position = Vector3(2, 3, 0)) y un SpotLight3D apuntando hacia el suelo desde arriba.extends Node3D
@onready var sol: DirectionalLight3D = $DirectionalLight3D
@onready var bombilla: OmniLight3D = $OmniLight3D
@onready var foco: SpotLight3D = $SpotLight3D
func _ready() -> void:
# Sol cálido con sombras.
sol.light_color = Color(1.0, 0.95, 0.85)
sol.light_energy = 1.2
sol.shadow_enabled = true
sol.shadow_bias = 0.03
# Bombilla puntual con alcance limitado.
bombilla.light_color = Color(1.0, 0.7, 0.4)
bombilla.light_energy = 3.0
bombilla.omni_range = 8.0
bombilla.shadow_enabled = true
# Foco dirigido.
foco.light_color = Color(0.8, 0.9, 1.0)
foco.light_energy = 4.0
foco.spot_range = 12.0
foco.spot_angle = 30.0
foco.shadow_enabled = true
func _process(_delta: float) -> void:
# Ajustar el bias del sol en vivo para observar el acné de sombra.
if Input.is_action_pressed("ui_up"):
sol.shadow_bias = clamp(sol.shadow_bias + 0.05 * _delta, 0.0, 0.5)
if Input.is_action_pressed("ui_down"):
sol.shadow_bias = clamp(sol.shadow_bias - 0.05 * _delta, 0.0, 0.5)
# Rotar el sol para ver cómo se mueven las sombras.
sol.rotate_y(0.3 * _delta)
shadow_bias cercano a 0 con la flecha abajo: aparecerán rayas de acné en las superficies. Súbelo con la flecha arriba hasta que desaparezcan sin que las sombras se despeguen del objeto.shadow_enabled del foco y compara el coste de render (usa el monitor de FPS del editor).light_color del sol a un tono azulado y describe la atmósfera resultante.omni_range a 3 y observa cómo se recorta el alcance de la luz.spot_angle entre 10 y 60 grados y documenta el cambio en el haz.Ilumina una habitación cerrada (cuatro paredes y suelo) usando un OmniLight3D central con sombras activas, más un SpotLight3D como lámpara de escritorio. El DirectionalLight3D debe estar apagado (energía 0). Corrige cualquier acné de sombra ajustando el bias.
Criterio de aceptación: la escena se ve iluminada solo por las luces puntuales, las sombras se proyectan correctamente sin rayas de acné y no hay errores en consola.
| Síntoma | Causa y arreglo |
|---|---|
| Rayas oscuras sobre superficies iluminadas | Acné de sombra por bias bajo; sube shadow_bias gradualmente. |
| La sombra se despega del objeto | Peter-panning por bias excesivo; baja shadow_bias. |
| Omni/Spot no proyectan sombra | shadow_enabled está en false; actívalo en cada luz. |
| La escena está totalmente negra | No hay luz ni ambiente; añade una luz o sube la luz ambiental. |
| Caída brusca de FPS | Demasiadas luces con sombras; limita cuáles usan sombra. |
| La bombilla no ilumina de lejos | omni_range demasiado corto; auméntalo. |
❓ ¿Por qué la luz direccional no tiene posición? Simula una fuente infinitamente lejana (el sol), así que solo importa su ángulo, no dónde esté el nodo.
❓ ¿Cuántas luces con sombra puedo usar? Depende del hardware; en general limita las sombras dinámicas a las luces clave y deja las secundarias sin sombra.
❓ ¿El bias es lo mismo en todas las luces? El concepto es igual, pero cada luz tiene su propio shadow_bias a ajustar según su geometría.
❓ ¿Necesito luz ambiental además de estas? Sí; sin algo de ambiente, las zonas no iluminadas quedan totalmente negras. Se configura en el WorldEnvironment (próxima clase).
Clase 051 - Cámaras 3D: perspectiva, FOV y Camera3D