Introduction to 3D Lighting
Lighting is crucial for creating atmosphere and visual depth in 3D scenes. Godot provides three main light types and advanced global illumination techniques to achieve realistic and performant lighting.
All light nodes inherit from the base Light3D class (doc/classes/Light3D.xml:2).
Light Types
DirectionalLight3D Simulates distant light sources like the sun
OmniLight3D Point light radiating in all directions
SpotLight3D Cone-shaped light like a flashlight
DirectionalLight3D
Models infinite parallel rays from a distant source, typically used for sunlight or moonlight.
Basic Setup
var sun = DirectionalLight3D . new ()
add_child ( sun )
# Position doesn't matter - only rotation affects direction
sun . rotation_degrees = Vector3 ( - 45 , 30 , 0 )
# Configure light properties
sun . light_color = Color ( 1.0 , 0.95 , 0.8 ) # Warm sunlight
sun . light_energy = 1.0
See doc/classes/DirectionalLight3D.xml:7-8
Light is emitted in the -Z direction of the node’s global basis. For an unrotated light, this means light travels forward.
Shadow Configuration
# Enable shadows
sun . shadow_enabled = true
# Shadow quality modes
sun . directional_shadow_mode = DirectionalLight3D . SHADOW_PARALLEL_4_SPLITS
# Shadow distance
sun . directional_shadow_max_distance = 200.0
sun . directional_shadow_fade_start = 0.8
See doc/classes/DirectionalLight3D.xml:24, 21-22
Shadow Split Configuration
For better shadow quality, directional lights use cascaded shadow maps:
2 Splits
4 Splits
Orthogonal
sun . directional_shadow_mode = DirectionalLight3D . SHADOW_PARALLEL_2_SPLITS
sun . directional_shadow_split_1 = 0.1 # 10% of max distance
Good balance between quality and performance. sun . directional_shadow_mode = DirectionalLight3D . SHADOW_PARALLEL_4_SPLITS
sun . directional_shadow_split_1 = 0.05
sun . directional_shadow_split_2 = 0.15
sun . directional_shadow_split_3 = 0.5
Best quality but higher performance cost. sun . directional_shadow_mode = DirectionalLight3D . SHADOW_ORTHOGONAL
Fastest but may produce blurrier shadows.
See doc/classes/DirectionalLight3D.xml:30-37
Sky Mode
# Control if light affects scene, sky, or both
sun . sky_mode = DirectionalLight3D . SKY_MODE_LIGHT_AND_SKY
SKY_MODE_LIGHT_AND_SKY: Affects both scene and sky (default)
SKY_MODE_LIGHT_ONLY: Only lights the scene
SKY_MODE_SKY_ONLY: Only affects sky shader
See doc/classes/DirectionalLight3D.xml:39-40
OmniLight3D
Emits light in all directions from a point, like a light bulb or candle.
Basic Setup
var bulb = OmniLight3D . new ()
add_child ( bulb )
bulb . position = Vector3 ( 0 , 3 , 0 )
# Configure range and attenuation
bulb . omni_range = 10.0
bulb . omni_attenuation = 2.0 # Physically accurate inverse square
# Light properties
bulb . light_color = Color ( 1.0 , 0.8 , 0.6 ) # Warm white
bulb . light_energy = 1.5
See doc/classes/OmniLight3D.xml:23-25
Only 8 omni lights can affect each mesh in Mobile/Compatibility rendering methods. Exceeding this limit causes flickering.
Attenuation
Controls how light fades with distance:
# Linear falloff (constant brightness, smooth edge)
bulb . omni_attenuation = 0.0
# Realistic inverse square (physically accurate)
bulb . omni_attenuation = 2.0
# Custom curve
bulb . omni_attenuation = 1.5
See doc/classes/OmniLight3D.xml:17-21
Shadow Modes
# Enable shadows
bulb . shadow_enabled = true
# Shadow quality
bulb . omni_shadow_mode = OmniLight3D . SHADOW_CUBE # Higher quality
# or
bulb . omni_shadow_mode = OmniLight3D . SHADOW_DUAL_PARABOLOID # Faster
See doc/classes/OmniLight3D.xml:27-28, 32-37
SpotLight3D
Cone-shaped light emission, useful for flashlights, car headlights, or stage lights.
Basic Setup
var spotlight = SpotLight3D . new ()
add_child ( spotlight )
spotlight . position = Vector3 ( 0 , 5 , 0 )
spotlight . rotation_degrees = Vector3 ( - 90 , 0 , 0 ) # Point down
# Cone configuration
spotlight . spot_angle = 45.0 # Angular radius in degrees
spotlight . spot_range = 15.0
spotlight . spot_attenuation = 1.0
spotlight . spot_angle_attenuation = 1.0
See doc/classes/SpotLight3D.xml:21-23, 34-36
Light is emitted in the -Z direction . The spot_angle is the angular radius (from center to edge), so a 45° angle creates a 90° cone.
Angle and Range
# Wide cone (like a lantern)
spotlight . spot_angle = 60.0
# Narrow cone (like a laser pointer)
spotlight . spot_angle = 15.0
# Adjust range
spotlight . spot_range = 20.0
Attenuation Curves
# Distance attenuation (how light fades with distance)
spotlight . spot_attenuation = 2.0 # Inverse square
# Angular attenuation (how light fades toward cone edge)
spotlight . spot_angle_attenuation = 1.0 # Linear falloff
See doc/classes/SpotLight3D.xml:25-26, 28-32
Common Light Parameters
All light types share these properties from the Light3D base class:
Energy and Color
# Light intensity multiplier
light . light_energy = 1.0
# Light color in sRGB
light . light_color = Color ( 1.0 , 1.0 , 1.0 )
# Specular contribution (shiny highlights)
light . light_specular = 1.0
See doc/classes/Light3D.xml:66-67, 73-74, 102-103
Physical Light Units
For realistic lighting, enable physical units in Project Settings:
# For DirectionalLight3D (Lux)
sun . light_intensity_lux = 100000 # Clear sunny day
# For OmniLight3D and SpotLight3D (Lumens)
bulb . light_intensity_lumens = 800 # ~60W light bulb
See doc/classes/Light3D.xml:85-87, 80-83
Color Temperature
# Simulate real-world light temperatures (Kelvin)
light . light_temperature = 6500 # Daylight
light . light_temperature = 2700 # Warm incandescent
light . light_temperature = 5500 # Camera flash
See doc/classes/Light3D.xml:105-107
Negative Lights
Create areas of darkness:
light . light_negative = true
light . light_energy = 0.5 # Darkness intensity
See doc/classes/Light3D.xml:89-90
Indirect Lighting
Control contribution to global illumination:
# Secondary multiplier for GI
light . light_indirect_energy = 1.0
# Volumetric fog contribution
light . light_volumetric_fog_energy = 1.0
See doc/classes/Light3D.xml:76-78, 109-111
Shadows
Enabling Shadows
light . shadow_enabled = true
See doc/classes/Light3D.xml:122-123
Shadows have significant performance cost. Use them judiciously and enable distance_fade_enabled for distant lights.
Shadow Quality Parameters
# Reduce shadow acne (self-shadowing artifacts)
light . shadow_bias = 0.1
# Reduce peter-panning (shadows separated from casters)
light . shadow_normal_bias = 2.0
# Shadow softness
light . shadow_blur = 1.0
# Shadow opacity
light . shadow_opacity = 1.0
See doc/classes/Light3D.xml:113-114, 125-126, 116-117, 128-129
Percentage-Closer Soft Shadows (PCSS)
Create realistic soft shadows:
# For DirectionalLight3D
sun . light_angular_distance = 0.5 # Sun's angular size
# For OmniLight3D and SpotLight3D
bulb . light_size = 0.2 # Light source size in Godot units
See doc/classes/Light3D.xml:57-60, 97-100
PCSS is only supported in Forward+ rendering (not Mobile or Compatibility).
Shadow Cull Mask
# Only cast shadows from specific layers
light . shadow_caster_mask = 0b00000001 # Only layer 1
See doc/classes/Light3D.xml:119-120
Distance Fade (LOD)
Optimize performance by fading distant lights:
light . distance_fade_enabled = true
light . distance_fade_begin = 40.0
light . distance_fade_length = 10.0
light . distance_fade_shadow = 50.0
See doc/classes/Light3D.xml:38-53
Light Projectors (Cookies/Gobos)
Project textures through lights:
light . light_projector = preload ( "res://textures/window_gobo.png" )
light . shadow_enabled = true # Required for projectors
See doc/classes/Light3D.xml:92-95
Light projectors are only supported in Forward+ and Mobile rendering methods.
Global Illumination (GI)
Godot offers multiple GI techniques:
Bake Modes
# Light doesn't affect GI (fastest)
light . light_bake_mode = Light3D . BAKE_DISABLED
# Static GI (baked, no real-time updates)
light . light_bake_mode = Light3D . BAKE_STATIC
# Dynamic GI (real-time updates)
light . light_bake_mode = Light3D . BAKE_DYNAMIC
See doc/classes/Light3D.xml:62-64, 204-214
LightmapGI
Bake static lighting for best performance:
Add LightmapGI Node
Add a LightmapGI node to your scene.
Configure Lights
Set lights to BAKE_STATIC mode: sun . light_bake_mode = Light3D . BAKE_STATIC
Bake Lightmaps
Select the LightmapGI node and click “Bake Lightmaps” in the toolbar.
Use Baked Result
Lightmaps are automatically applied to static meshes.
VoxelGI
Real-time voxel-based global illumination:
var voxel_gi = VoxelGI . new ()
add_child ( voxel_gi )
voxel_gi . extents = Vector3 ( 20 , 10 , 20 )
# Bake the GI volume
voxel_gi . bake ()
# Set light to dynamic mode for real-time updates
sun . light_bake_mode = Light3D . BAKE_DYNAMIC
SDFGI (Signed Distance Field GI)
Enable in WorldEnvironment for large open worlds:
var env = Environment . new ()
env . sdfgi_enabled = true
world_environment . environment = env
# Lights contribute automatically if bake mode allows
sun . light_bake_mode = Light3D . BAKE_DYNAMIC
Lighting Best Practices
Use Directional Light for Sun
Always use DirectionalLight3D for primary outdoor lighting: var sun = DirectionalLight3D . new ()
sun . light_energy = 1.0
sun . light_color = Color ( 1.0 , 0.95 , 0.8 )
sun . rotation_degrees = Vector3 ( - 45 , 30 , 0 )
Too many lights hurt performance. Use distance fade: light . distance_fade_enabled = true
light . distance_fade_begin = 30.0
light . distance_fade_length = 10.0
For static scenes, use LightmapGI: light . light_bake_mode = Light3D . BAKE_STATIC
Don’t render shadows too far away: sun . directional_shadow_max_distance = 100.0
sun . directional_shadow_fade_start = 0.8
Exclude unnecessary objects from lighting: light . light_cull_mask = 0b00000011 # Only layers 1 and 2
Common Lighting Scenarios
Outdoor Daytime
var sun = DirectionalLight3D . new ()
sun . light_color = Color ( 1.0 , 0.98 , 0.95 )
sun . light_energy = 1.0
sun . rotation_degrees = Vector3 ( - 50 , 20 , 0 )
sun . shadow_enabled = true
sun . directional_shadow_mode = DirectionalLight3D . SHADOW_PARALLEL_4_SPLITS
Indoor Room with Window
# Sunlight through window
var sun = DirectionalLight3D . new ()
sun . light_energy = 0.3 # Dimmer indoors
sun . light_color = Color ( 1.0 , 0.95 , 0.9 )
# Ceiling light
var ceiling_light = OmniLight3D . new ()
ceiling_light . position = Vector3 ( 0 , 3 , 0 )
ceiling_light . omni_range = 8.0
ceiling_light . light_energy = 2.0
ceiling_light . light_color = Color ( 1.0 , 0.9 , 0.8 )
Night Scene with Moonlight
var moon = DirectionalLight3D . new ()
moon . light_color = Color ( 0.7 , 0.8 , 1.0 ) # Cool blue tint
moon . light_energy = 0.2 # Dim
moon . rotation_degrees = Vector3 ( - 60 , 0 , 0 )
moon . shadow_enabled = true
Torch/Flashlight
var torch = SpotLight3D . new ()
torch . spot_angle = 30.0
torch . spot_range = 10.0
torch . spot_attenuation = 2.0
torch . light_color = Color ( 1.0 , 0.7 , 0.4 ) # Warm fire glow
torch . light_energy = 3.0
Debugging Lights
# Check if light is in the tree
if light . is_inside_tree ():
print ( "Light active" )
# Print light properties
print ( "Energy: " , light . light_energy )
print ( "Color: " , light . light_color )
print ( "Shadows: " , light . shadow_enabled )
# Editor-only lights
light . editor_only = true # Not visible at runtime
See doc/classes/Light3D.xml:54-55
# Disable lights that are too far
func _process ( _delta ):
var camera_pos = get_viewport (). get_camera_3d (). global_position
var distance = global_position . distance_to ( camera_pos )
if distance > 50.0 :
visible = false
else :
visible = true
3D Overview 3D fundamentals and transforms
Meshes and Materials How materials interact with lighting
Environment Sky, fog, and ambient lighting
Shaders Custom lighting in shaders
Resources