Lighting and Shadows
DirectionalLight3D, OmniLight3D, SpotLight3D, lightmaps, and SDFGI.
Light nodes
Three built-in light types (plus the upcoming AreaLight3D in 4.7):
- DirectionalLight3D — the sun. Parallel rays, infinitely far away. Usually one per scene.
- OmniLight3D — point light (Unity’s Point Light). Emits from a point in all directions with an attenuation radius.
- SpotLight3D — a cone from a point with an angle and a radius.
- AreaLight3D — an area light (since 4.7). A rectangular/disc source.
$DirectionalLight3D.light_energy = 1.5
$DirectionalLight3D.light_color = Color(1.0, 0.95, 0.85) # warm morning
$DirectionalLight3D.shadow_enabled = true
Key properties of each:
light_energy— brightness.light_color— color.light_indirect_energy— a multiplier for indirect light from this source (in GI).shadow_enabled— draw shadows.shadow_bias,shadow_normal_bias— shadow artifact settings.light_bake_mode—Light3D.BAKE_DISABLED/BAKE_STATIC(baked) /BAKE_DYNAMIC(real-time GI). In the Inspector it’s shown as Disabled/Static/Dynamic, but in code it has theBAKE_prefix.
Realtime, baked, mixed
As in Unity, there are three usage modes:
| Bake Mode | Where it’s computed | Use case |
|---|---|---|
| DISABLED | Realtime, every frame | Dynamic sources (an explosion, a rocket) |
| STATIC | Baked once | Static architecture |
| DYNAMIC | Realtime + participates in GI (SDFGI/VoxelGI) | The main scene light, doesn’t move |
Baking GI
Godot has three global illumination systems, with different costs:
1. LightmapGI — baked lightmaps
The most efficient at runtime, but requires baking. For static geometry.
- Mark objects as “static” (via the
gi_mode = STATICflag in the Inspector on MeshInstance3D). - Add a LightmapGI node to the scene.
- Bake Lightmaps with the button in the editor.
For dynamic objects within the lightmap area, use LightmapProbe (like Unity Light Probes).
2. VoxelGI — voxel-based realtime GI
Divides the scene into a 3D voxel grid and computes GI in realtime. Expensive, but beautiful. The VoxelGI node; the Bake button creates the initial data. Suitable for interiors.
3. SDFGI — Signed Distance Field GI
The most powerful — dynamic GI without baking. Enabled in the Environment resource:
env.sdfgi_enabled = true
env.sdfgi_cascades = 6
env.sdfgi_min_cell_size = 0.5
Downsides: Forward+ only, expensive, and a noticeable “haze” near the cascade boundaries.
Forward+ desktop: the main light is a DirectionalLight3D in DYNAMIC bake mode, with a sky/world environment using SDFGI or LightmapGI. Mobile: LightmapGI + DirectionalLight3D in STATIC.
Shadows — cascades for DirectionalLight3D
A DirectionalLight (the sun) draws shadows via shadow cascades — several shadow-map resolutions at different distances:
directional_shadow_mode—ORTHOGONAL/PARALLEL_2_SPLITS/PARALLEL_4_SPLITS.directional_shadow_max_distance— the distance up to which shadows are drawn.directional_shadow_split_1/2/3— the cascade proportions.
The more cascades, the smoother the transition, but the more expensive it is. PARALLEL_4_SPLITS is the standard.
Skybox and Environment
WorldEnvironment + the Environment resource are the scene’s global settings. Environment.background_mode
accepts values with the BG_ prefix:
Environment.BG_CLEAR_COLOR— one color.Environment.BG_COLOR— another color.Environment.BG_SKY— a Sky resource (procedural or panorama HDR).Environment.BG_CANVAS— a 2D background.Environment.BG_KEEP— don’t clear (for split-screen).Environment.BG_CAMERA_FEED— AR / the device camera.
For HDRI:
var sky_mat = PanoramaSkyMaterial.new()
sky_mat.panorama = preload("res://hdri/sunset_4k.exr")
var sky = Sky.new()
sky.sky_material = sky_mat
env.sky = sky
env.background_mode = Environment.BG_SKY
env.ambient_light_source = Environment.AMBIENT_SOURCE_SKY
Panorama (equirectangular) HDR works out of the box — grab one from PolyHaven, drop it in, and the lighting gets “soaked” in that sky.
Reflection Probes
The ReflectionProbe node is a spherical environment map for reflections in a material. Place it in the center of a room:
box_projection— project the reflection onto a box so reflections don’t “drift” in corners.update_mode—ONCE(a single baked one) /ALWAYS(every frame, expensive).
For metallic materials this is critical — without a probe they only reflect the sky.
What usually breaks for beginners
- All objects are dynamic, GI doesn’t work. Mark
gi_mode = STATICon non-moving geometry before baking. - Too many realtime shadow-casting lights. An OmniLight3D with shadows in Forward is expensive. Limit it to 4–6 visible at once.
- The Compatibility renderer with SDFGI / VoxelGI. They don’t work together — use LightmapGI.
- Forgetting WorldEnvironment. Without it, the scene renders with the default environment (often a black background, no ambient).
In the next chapter — animation.