godot-3d-lighting

安装量: 60
排名: #12445

安装

npx skills add https://github.com/thedivergentai/gd-agentic-skills --skill godot-3d-lighting
3D Lighting
Expert guidance for realistic 3D lighting with shadows and global illumination.
NEVER Do
NEVER use VoxelGI without setting a proper extents
— Unbound VoxelGI tanks performance. Always set
size
to tightly fit your scene.
NEVER enable shadows on every light
— Each shadow-casting light is expensive. Use shadows sparingly: 1-2 DirectionalLights, ~3-5 OmniLights max.
NEVER forget directional_shadow_mode
— Default is ORTHOGONAL. For large outdoor scenes, use PARALLEL_4_SPLITS for better shadow quality at distance.
NEVER use LightmapGI for fully dynamic scenes
— Lightmaps are baked. Moving geometry won't receive updated lighting. Use VoxelGI or SDFGI instead.
NEVER set omni_range too large
— Light attenuation is quadratic. A range of 500 affects 785,000 sq units. Keep range as small as visually acceptable.
Available Scripts
MANDATORY
Read the appropriate script before implementing the corresponding pattern. day_night_cycle.gd Dynamic sun position and color based on time-of-day. Handles DirectionalLight3D rotation, color temperature, and intensity curves. Use for outdoor day/night systems. light_probe_manager.gd VoxelGI and SDFGI management for global illumination setup. lighting_manager.gd Dynamic light pooling and LOD. Manages light culling and shadow toggling based on camera distance. Use for performance optimization with many lights. volumetric_fx.gd Volumetric fog and god ray configuration. Runtime fog density/color adjustments and light shaft setup. Use for atmospheric effects. DirectionalLight3D (Sun/Moon) Shadow Cascades

For outdoor scenes with camera moving from near to far

extends DirectionalLight3D func _ready ( ) -> void : shadow_enabled = true directional_shadow_mode = SHADOW_PARALLEL_4_SPLITS

Split distances (in meters from camera)

directional_shadow_split_1

10.0

First cascade: 0-10m

directional_shadow_split_2

50.0

Second: 10-50m

directional_shadow_split_3

200.0

Third: 50-200m

Fourth cascade: 200m - max shadow distance

directional_shadow_max_distance

500.0

Quality vs performance

directional_shadow_blend_splits

true

Smooth transitions

Day/Night Cycle

sun_controller.gd

extends DirectionalLight3D @ export var time_of_day := 12.0

0-24 hours

@ export var rotation_speed := 0.1

Hours per second

func _process ( delta : float ) -> void : time_of_day += rotation_speed * delta if time_of_day

= 24.0 : time_of_day -= 24.0

Rotate sun (0° = noon, 180° = midnight)

var angle := ( time_of_day - 12.0 ) * 15.0

15° per hour

rotation_degrees . x = - angle

Adjust intensity

if time_of_day < 6.0 or time_of_day

18.0 : light_energy = 0.0

Night

elif time_of_day < 7.0 : light_energy = remap ( time_of_day , 6.0 , 7.0 , 0.0 , 1.0 )

Sunrise

elif time_of_day

17.0 : light_energy = remap ( time_of_day , 17.0 , 18.0 , 1.0 , 0.0 )

Sunset

else : light_energy = 1.0

Day

Color shift

if time_of_day < 8.0 or time_of_day

16.0 : light_color = Color ( 1.0 , 0.7 , 0.4 )

Orange (dawn/dusk)

else : light_color = Color ( 1.0 , 1.0 , 0.9 )

Neutral white

OmniLight3D (Point Light) Attenuation Tuning

torch.gd

extends OmniLight3D func _ready ( ) -> void : omni_range = 10.0

Maximum reach

omni_attenuation

2.0

Falloff curve (1.0 = linear, 2.0 = quadratic/realistic)

For "magical" lights, reduce attenuation

omni_attenuation

0.5

Flatter falloff, reaches farther

Flickering Effect

campfire.gd

extends OmniLight3D @ export var base_energy := 1.0 @ export var flicker_strength := 0.3 @ export var flicker_speed := 5.0 func _process ( delta : float ) -> void : var flicker := sin ( Time . get_ticks_msec ( ) * 0.001 * flicker_speed ) * flicker_strength light_energy = base_energy + flicker SpotLight3D (Flashlight/Headlights) Setup

flashlight.gd

extends SpotLight3D func _ready ( ) -> void : spot_range = 20.0 spot_angle = 45.0

Cone angle (degrees)

spot_angle_attenuation

2.0

Edge softness

shadow_enabled

true

Projector texture (optional - cookie/gobo)

light_projector

load ( "res://textures/flashlight_mask.png" ) Follow Camera

player_flashlight.gd

extends SpotLight3D @ onready var camera : Camera3D = get_viewport ( ) . get_camera_3d ( ) func _process ( delta : float ) -> void : if camera : global_transform = camera . global_transform Global Illumination: VoxelGI vs SDFGI Decision Matrix Feature VoxelGI SDFGI Setup Manual bounds per room Automatic, scene-wide Dynamic objects Fully supported Partially supported Performance Moderate Higher cost Use case Indoor, small-medium scenes Large outdoor scenes Godot version 4.0+ 4.0+ VoxelGI Setup

room_gi.gd - Place one VoxelGI per room/area

extends VoxelGI func _ready ( ) -> void :

Tightly fit the room

size

Vector3 ( 20 , 10 , 20 )

Quality settings

subdiv

VoxelGI . SUBDIV_128

Higher = better quality, slower

Bake GI data

bake ( ) SDFGI Setup

world_environment.gd

extends WorldEnvironment func _ready ( ) -> void : var env := environment

Enable SDFGI

env . sdfgi_enabled = true env . sdfgi_use_occlusion = true env . sdfgi_read_sky_light = true

Cascades (auto-scale based on camera)

env . sdfgi_min_cell_size = 0.2

Detail level

env . sdfgi_max_distance = 200.0 LightmapGI (Baked Static Lighting) When to Use Static architecture (buildings, dungeons) Mobile/low-end targets No dynamic geometry Setup

Scene structure:

- LightmapGI node

- StaticBody3D meshes with GeometryInstance3D.gi_mode = STATIC

lightmap_baker.gd

extends LightmapGI func _ready ( ) -> void :

Quality settings

quality

LightmapGI . BAKE_QUALITY_HIGH bounces = 3

Indirect light bounces

Bake (editor only, not runtime)

Click "Bake Lightmaps" button in editor

Environment & Sky HDR Skybox

world_env.gd

extends WorldEnvironment func _ready ( ) -> void : var env := environment env . background_mode = Environment . BG_SKY var sky := Sky . new ( ) var sky_material := PanoramaSkyMaterial . new ( ) sky_material . panorama = load ( "res://hdri/sky.hdr" ) sky . sky_material = sky_material env . sky = sky

Sky contribution to GI

env . ambient_light_source = Environment . AMBIENT_SOURCE_SKY env . ambient_light_sky_contribution = 1.0 Volumetric Fog extends WorldEnvironment func _ready ( ) -> void : var env := environment env . volumetric_fog_enabled = true env . volumetric_fog_density = 0.01 env . volumetric_fog_albedo = Color ( 0.9 , 0.9 , 1.0 )

Blueish

env . volumetric_fog_emission = Color . BLACK ReflectionProbe For localized reflections (mirrors, shiny floors):

reflection_probe.gd

extends ReflectionProbe func _ready ( ) -> void :

Capture area

size

Vector3 ( 10 , 5 , 10 )

Quality

resolution

ReflectionProbe . RESOLUTION_512

Update mode

update_mode

ReflectionProbe . UPDATE_ONCE

Bake once

or UPDATE_ALWAYS for dynamic reflections (expensive)

Performance Optimization Light Budgets

Recommended limits:

- DirectionalLight3D with shadows: 1-2

- OmniLight3D with shadows: 3-5

- SpotLight3D with shadows: 2-4

- OmniLight3D without shadows: 20-30

- SpotLight3D without shadows: 15-20

Disable shadows on minor lights

@ onready var candle_lights : Array = [ $Candle1 , $Candle2 , $Candle3 ] func _ready ( ) -> void : for light in candle_lights : light . shadow_enabled = false

Save performance

Per-Light Shadow Distance

Disable shadows for distant lights

extends OmniLight3D @ export var shadow_max_distance := 50.0 func _process ( delta : float ) -> void : var camera := get_viewport ( ) . get_camera_3d ( ) if camera : var dist := global_position . distance_to ( camera . global_position ) shadow_enabled = ( dist < shadow_max_distance ) Edge Cases Shadows Through Floors

Problem: Thin floors let shadows through

Solution: Increase shadow bias

extends DirectionalLight3D func _ready ( ) -> void : shadow_enabled = true shadow_bias = 0.1

Increase if shadows bleed through

shadow_normal_bias

2.0 Light Leaking in Indoor Scenes

Problem: VoxelGI light bleeds through walls

Solution: Place VoxelGI nodes per-room, don't overlap

Also: Ensure walls have proper thickness (not paper-thin)

Reference Master Skill: godot-master

返回排行榜