关于 godot-3d-lighting
面向 Godot 的 3D 灯光技能,涵盖真实感照明、阴影与全局光照。它按场景类型提供配置路线,并通过脚本说明常见效果与性能取舍。
主要功能
- 01按场景选择照明路线
- 02阴影级联与偏移调节
- 03全局光照配置模式
- 04灯光与阴影性能预算
- 05雾效、环境与反射效果
适用场景
- 01配置室内或户外场景照明
- 02为移动或动态场景选择全局光照
- 03降低阴影与聚类灯光开销
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ thedivergentai/ game-dev-agentic-skills --skill godot-3d-lighting安装后在 Claude Code 中输入/godot-3d-lighting确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/environment-and-fog.mdgi-and-bake-recipes.mdmigration-notes.mdscripts/day_night_cycle.gdenvironment_blender.gdfake_gi_bounce.gdlight_lod_optimizer.gdlight_probe_manager.gdlight_volume_trigger.gdlighting_manager.gdlighting_quality_manager.gdlightmap_bake_helper.gdreflection_probe_manager.gdsdfgi_probe_manager.gdshadow_bias_tuner.gdshadow_cascade_tuner.gdspotlight_projector_setup.gdvolumetric_fog_zones.gdvolumetric_fx.gd详细介绍
3D 光照
为逼真的 3D 光照、阴影和全局光照提供专家指导。
绝对不要
- 绝对不要在未设置合适范围的情况下使用 VoxelGI — 未限定范围的 VoxelGI 会严重拖累性能。始终设置
size,使其紧密贴合场景。 - 绝对不要给每盏灯都启用阴影 — 每个投射阴影的灯都会带来高昂开销。请谨慎使用阴影:最多使用 1-2 个 DirectionalLights、约 3-5 个 OmniLights。
- 绝对不要忘记 directional_shadow_mode — 默认值为 ORTHOGONAL。对于大型室外场景,请使用 PARALLEL_4_SPLITS,以改善远处的阴影质量。
- 绝对不要在完全动态的场景中使用 LightmapGI — 光照贴图是烘焙的。移动的几何体不会获得更新后的光照。请改用 VoxelGI 或 SDFGI。
- 绝对不要将 omni_range 设得过大 — 光照衰减是二次方的。范围为 500 时会影响 785,000 平方单位。请将范围保持在视觉上可接受的最小值。
- 绝对不要使用 Visible 属性隐藏 Light 节点,以便在 Lightmap 烘焙时排除它 — 隐藏灯光不会对烘焙器产生任何影响。你必须将灯光的 Bake Mode 改为 Disabled。
- 绝对不要在薄如纸的墙体上使用 VoxelGI — VoxelGI 使用 3D 网格计算光照。薄墙(厚度不到一个体素)会造成严重的漏光。请封闭几何体,或在外部周围放置隐藏的厚 MeshInstance3D 方块。
- 绝对不要让级联阴影继续使用默认偏差值 — 默认偏差值经常会在分割交界处造成 Peter Panning 或漏光。请根据场景比例逐灯调整偏差值。
- 绝对不要在没有降噪器的情况下烘焙 LightmapGI — Godot 烘焙的光照贴图默认会有噪点。请在 Project Settings 中使用 OIDN 或 JNLM,以获得专业效果。
- 绝对不要在 Mobile/Compatibility 渲染器上使用实时 SDFGI — 这项功能仅适用于 Forward+。对于低端平台,请使用模拟 GI 的补光灯。
- 绝对不要为了性能而在 ReflectionProbes 中使用 'Update Continuity' — 将 ReflectionProbes 保持为 'Update Once',只在必要时触发手动更新。
- 绝对不要让聚类阴影图集溢出 — 原因:Forward+ 会将 Omni/Spot 阴影打包到共享图集中。过多的投射阴影点光源 → 图集抖动、闪烁或画质无声下降。将投射阴影的 Omni 限制在约 3–5 个,Spot 限制在约 2–4 个;在增大图集尺寸之前,先使用
light_lod_optimizer.gd/ 距离淡出。 - 绝对不要在同一个聚类单元中堆叠数十个彼此重叠且投射阴影的 Omni/Spot — 原因:聚类光照迭代成本会随每个图块中重叠灯光的数量而增长。优先使用不投射阴影的补光灯、更小的
omni_range/spot_range,以及distance_fade_*,让远处的灯光退出聚类。
可用脚本
必读:实现相应模式前,先阅读适用的脚本。
Golden path(任选一种 — Do NOT Load peers)
| 场景 | 加载 | 不要加载 |
|---|---|---|
| 室外 Forward+ | shadow_cascade_tuner.gd + sdfgi_probe_manager.gd(+ day_night_cycle.gd,用于昼夜循环) | fake_gi_bounce.gd、室内 VoxelGI 烘焙(混合模式除外);除非任务涉及大气效果,否则不要加载 environment_blender.gd / 雾效 |
| 室内 封闭几何体 | 必须使用 VoxelGI,通过 light_probe_manager.gd + lighting_manager.gd + ReflectionProbes 实现 | 小型室内场景中的 SDFGI;除非目标平台为 Mobile,否则不要使用 Mobile 假 GI;除非需要区域混合,否则不要加载天空/雾效脚本 |
| Mobile / Compatibility | 必须使用 fake_gi_bounce.gd + light_lod_optimizer.gd 中的光源预算 | 实时 SDFGI(仅限 Forward+);HDR 天空/体积光照方案 |
| 光照贴图烘焙 / 混合静态模式 | 必须使用 lightmap_bake_helper.gd(+ 室外场景使用 Shadowmasking) | 用运行时 SDFGI 代替烘焙;通过 Visible 禁用光源 |
| 仅天空 / 环境混合 | environment_blender.gd | 仅更改色调映射/环境光/天空时,不要加载级联/GI 管理器 |
| 体积雾 / 光束 | volumetric_fx.gd(+ volumetric_fog_zones.gd,用于局部密度) | 纯光源预算 / 阴影图集调优任务 |
| 纯光源预算 / 阴影 LOD | light_lod_optimizer.gd、shadow_bias_tuner.gd | 不要加载 environment_blender.gd、volumetric_fx.gd、昼夜循环脚本,除非确有需要 |
day_night_cycle.gd
根据一天中的时间动态调整太阳位置和颜色。处理 DirectionalLight3D 旋转、色温和强度曲线。适用于室外昼夜系统。
light_probe_manager.gd
用于全局光照设置的 VoxelGI 和 SDFGI 管理。
lighting_manager.gd
动态光源池化和 LOD。根据摄像机距离管理光源剔除和阴影开关。适用于多光源场景的性能优化。
volumetric_fx.gd
体积雾和上帝光束配置。运行时调整雾的密度/颜色并设置光束。适用于大气效果。
shadow_cascade_tuner.gd
根据太阳角度和摄像机倾斜度动态调整 DirectionalLight3D 阴影分割距离的专业逻辑。
lightmap_bake_helper.gd
使用 Shadowmasking 模式设置 LightmapGI 的高级配置方案,用于混合静态/动态阴影。
sdfgi_probe_manager.gd
实时全局光照(SDFGI)的动态质量缩放器。调整单元格大小和遮挡,以权衡性能与质量。
volumetric_fog_zones.gd
使用 Tweens 和 Area3D 触发器,为洞穴入口或林间空地平滑过渡局部雾密度。
fake_gi_bounce.gd
高效的“Mobile-GI”方案。使用不投射阴影的方向性补光模拟地面反射光。
environment_blender.gd
用于在游戏过程中转换 WorldEnvironment 参数(Sky、Ambient、Tonemap)的架构方案。
shadow_bias_tuner.gd
用于修正高保真方向光“彼得潘现象”和“阴影痤疮”的优化脚本。
light_lod_optimizer.gd
针对密集环境中的 OmniLight3D 节点,按距离剔除阴影和可见性。
reflection_probe_manager.gd
注重性能的 ReflectionProbe 管理方案,在大型环境发生变化时手动触发“Update Once”。
spotlight_projector_setup.gd
使用 Projector 纹理模拟复杂阴影图案(格栅、玻璃波纹),实现高细节光照。
light_volume_trigger.gd
由 Area3D 驱动的摄像机 Environment 混合,用于洞穴/沙漠过渡(复制环境资源;对曝光/环境光进行渐变)。
lighting_quality_manager.gd
运行时 RenderingServer 配置:半分辨率 SDFGI、阴影图集大小、体积雾密度。
DirectionalLight3D(太阳/月亮)
阴影级联
# 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.gd — 不要在此处重新内嵌太阳能量/颜色配置。
OmniLight3D(点光源)
保持 omni_range 范围较小;优先使用二次衰减。闪烁/篝火循环应放在场景脚本中,而不是此正文中。带阴影的 Omni 数量有严格上限(参见“绝不”)。
SpotLight3D(手电筒/车头灯)
必须使用 spotlight_projector_setup.gd 配置范围/角度/投影贴花及跟随摄像机的手电筒。不要在此处粘贴 Spot 配置。
全局光照(脚本优先)
使用上方的黄金路径表。仅在正文中作出以下选择:
| 路径 | 脚本 | 适用场景 |
|---|---|---|
| 室内/封闭空间 | 必须使用 light_probe_manager.gd(+ lighting_manager.gd) | 每个房间使用紧凑的 VoxelGI 范围;墙壁绝不能薄如纸片 |
| 室外 Forward+ | 必须使用 sdfgi_probe_manager.gd | 实时 GI;移动端/兼容模式下不要加载 |
| 静态/移动端烘焙 | 必须使用 lightmap_bake_helper.gd | LightmapGI + Shadowmasking;烘焙模式 ≠ 隐藏可见对象 |
| 无 GI 预算 | 必须使用 fake_gi_bounce.gd | 仅使用补光 |
不要在此处重新内嵌 VoxelGI/SDFGI/Lightmap 属性配置。
环境与天空
天空/环境光/色调映射过渡 → 必须使用 environment_blender.gd。体积雾/光束 → 必须使用 volumetric_fx.gd(洞穴/森林还需使用 volumetric_fog_zones.gd)。
纯粹进行光照预算/阴影图集/级联调优时不要加载这些内容 — 使用 light_lod_optimizer.gd/shadow_cascade_tuner.gd。
ReflectionProbe
用于局部反射(镜子、光亮地板):
# 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)
性能优化
光源预算
# 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
单光源阴影距离
# 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)
边缘情况
阴影穿透地板
# 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
室内场景漏光
# Problem: VoxelGI light bleeds through walls
# Solution: Place VoxelGI nodes per-room, don't overlap
# Also: Ensure walls have proper thickness (not paper-thin)
专家技巧与优化
1. 大型室外场景的 Shadowmasking
为远处物体渲染实时阴影的开销过高。烘焙 LightmapGI 时,将 DirectionalLight3D 的烘焙模式设为 Dynamic,使用 Shadowmasking。这会将远处阴影烘焙到纹理中,同时允许动态物体在近处投射实时阴影,从而避免“双重阴影”伪影。
2. 伪全局光照
如果完全无法承担 GI 的开销(例如移动端限制严格),可以模拟 GI!复制主 DirectionalLight3D,将其旋转 180 度(从地面朝上),关闭阴影,将 Specular 设为 0.0,并将能量降低至 10-40%。这样可以低成本模拟地面反弹光照。
3. 模拟 PCSS(接触硬化阴影)
Godot 的 OmniLight3D 缩放可以模拟百分比渐进软阴影(Percentage-Closer Soft Shadows,离投射物越远,阴影越模糊)。
extends OmniLight3D
func _ready() -> void:
# Simulates area lights and Percentage-Closer Soft Shadows (PCSS).
# Note: High performance cost. Keep the number of lights with light_size > 0.0 low.
light_size = 0.5
shadow_enabled = true
# Distance fade culls the light and shadow completely when out of range,
# preventing the clustered renderer from choking on too many overlapping PCSS lights.
distance_fade_enabled = true
distance_fade_begin = 20.0
distance_fade_length = 5.0
专家模式:光照体积触发器
使用 Area3D 触发器和由 Tween 驱动的 Camera3D 覆盖设置,在不同光照环境之间平滑过渡(例如从明亮的沙漠进入昏暗的洞穴)。
class_name LightVolumeTrigger extends Area3D
@export var interior_environment: Environment
@export var transition_duration: float = 2.0
func _ready() -> void:
body_entered.connect(_on_body_entered)
body_exited.connect(_on_body_exited)
func _on_body_entered(body: Node3D) -> void:
if body.is_in_group("player"):
var camera := get_viewport().get_camera_3d()
# Duplicate to avoid modifying the original resource
if not camera.environment:
camera.environment = interior_environment.duplicate()
var tween := create_tween().set_parallel(true)
# Interpolate key properties for visual adaptation
tween.tween_property(camera.environment, "tonemap_exposure", interior_environment.tonemap_exposure, transition_duration)
tween.tween_property(camera.environment, "ambient_light_energy", interior_environment.ambient_light_energy, transition_duration)
func _on_body_exited(body: Node3D) -> void:
if not body.is_in_group("player"):
return
var camera := get_viewport().get_camera_3d()
if camera == null or camera.environment == null:
return
var world_env := get_tree().get_first_node_in_group("world_environment") as WorldEnvironment
var target := world_env.environment if world_env and world_env.environment else Environment.new()
var tween := create_tween().set_parallel(true)
tween.tween_property(camera.environment, "tonemap_exposure", target.tonemap_exposure, transition_duration)
tween.tween_property(camera.environment, "ambient_light_energy", target.ambient_light_energy, transition_duration)
tween.chain().tween_callback(func():
# Return to WorldEnvironment ownership when blend completes
camera.environment = null
)
提示
在室内放置一个
ReflectionProbe,并设置interior = true。玩家过渡时,Godot 会自动将其与室外环境混合。
专家模式:Interior-Mapping(Fake-Rooms)
窗户四边形上的伪室内深度是一项自定义空间着色器专长——请在项目着色器中实现,或转至 godot-shaders-basics。不要在此技能正文中保留不完整的射线盒存根。
专家模式:Lighting-Quality-Settings
使用 RenderingServer API 在运行时管理复杂的光照功能(阴影、SDFGI、雾),以直接控制引擎。
class_name LightingQualityManager extends Node
func apply_low_quality_profile(env_rid: RID) -> void:
# 1. SDFGI Optimization
# Huge performance gain: Render GI buffers at half resolution
RenderingServer.gi_set_use_half_resolution(true)
RenderingServer.environment_set_sdfgi_ray_count(RenderingServer.ENV_SDFGI_RAY_COUNT_4)
RenderingServer.environment_set_sdfgi_frames_to_converge(RenderingServer.ENV_SDFGI_CONVERGE_IN_30_FRAMES)
# 2. Shadow Optimization
# Reduce global directional shadow atlas
RenderingServer.directional_shadow_atlas_set_size(2048, true)
RenderingServer.directional_soft_shadow_filter_set_quality(RenderingServer.SHADOW_QUALITY_SOFT_VERY_LOW)
# Reduce positional (Omni/Spot) shadows for current viewport
get_viewport().positional_shadow_atlas_size = 1024
# 3. Volumetric Fog
# Disable or heavily reduce fog detail
RenderingServer.environment_set_volumetric_fog(env_rid, false, 0.01, Color.WHITE, Color.BLACK, 0.0, 0.2, 64.0, 2.0, 1.0, true, 0.9, 0.0, 1.0)
深入指南(按需阅读)
| 主题 | 参考资料 / 脚本 |
|---|---|
| VoxelGI / SDFGI / LightmapGI 设置 | gi-and-bake-recipes.md |
| 天空 / 雾 / HDR 环境 | environment-and-fog.md |
参考资料
渐进式披露:仅在研究特定 API 时打开官方文档链接;在转至相关领域时加载相关技能——不要预加载整个技能网络。
官方文档
- 灯光与阴影简介 — Directional/Omni/Spot 的作用、阴影图集预算、级联、投影器和偏差取舍。
- 全局光照简介 — 在承担烘焙或运行时成本之前,比较 LightmapGI、VoxelGI、SDFGI 和探针的决策矩阵。
- 使用 SDFGI — 仅限 Forward+ 的实时 GI 级联、遮挡和适用于室外/开放场景的质量参数。
- 使用 VoxelGI — 有界室内 GI、细分、漏光原因(薄墙)以及逐房间烘焙工作流。
- 使用 LightmapGI — 静态烘焙模式、降噪器、阴影遮罩,以及烘焙光照无法用于动态几何体的情况。
- 反射探针 — 局部镜面反射采集、Update Once 与 Always,以及与环境的室内混合。
- 模拟全局光照 — 在 SDFGI 不可用时,适用于 Mobile 和 Compatibility 的补光/反弹光近似方案。
- 环境与后期处理 — 用于光照区域过渡的 WorldEnvironment 天空、环境光、色调映射和摄像机覆盖设置。
- 体积雾与雾体积 — 全局体积雾,以及用于光束和局部氛围的 FogVolume 密度区域。
- 物理光照与摄像机单位 — 匹配真实世界昼夜变化和曝光链时使用的 Lux/EV 式能量单位。
- 优化 3D 性能 — 本地 LOD 和级联调优后仍无法满足帧时间时,检查阴影/GI/灯光数量预算。
- AreaLight3D — 用于面板/屏幕的矩形柔和面光源,可替代仅使用自发光材质的伪效果(Forward+)。
相关技能
前置条件
- godot-project-foundations — 渲染器选择(Forward+/Mobile/Compatibility)、阴影图集和 GI 项目设置决定了哪些光照功能可用。
- godot-3d-materials — Albedo/roughness/metallic/emission 和
gi_mode决定表面如何接收反弹光和烘焙光。 - godot-gdscript-mastery — 管理器和环境混合中使用的类型化节点脚本、Tweens 和 Resource 所有权模式。
配套技能
- godot-shaders-basics — 自定义空间/雾效/天空着色器和室内映射技巧,可扩展 Environment 光照而无需增加更多实时光源。
- godot-camera-systems — 用于洞穴/室内光照体积过渡的摄像机
environment覆盖和曝光配对。 - godot-3d-world-building — 场景比例、封闭室内空间以及 GridMap/静态布局,让 VoxelGI/LightmapGI 能够顺利烘焙。
- godot-particles — 只有共同设计雾密度和光照能量,尘埃/烟雾/余烬才能呈现正确效果。
- godot-tweening — 平滑过渡 Environment、雾效和光照能量,避免在 Area3D 边界处突然切换。
- godot-physics-3d — 由 Area3D 主体进入/离开触发器驱动光照体积和雾区混合。
- godot-adapt-desktop-to-mobile — 面向 Mobile/Compatibility 时移除 SDFGI/重型阴影,并改用伪反弹 GI。
下游 / 使用方
- godot-performance-optimization — 当级联分割、探针数量或体积雾仍占用大量分析器资源时,转至此处。
- godot-monte-carlo-balancer — 当光照变化影响战斗、潜行或恐怖难度时,模拟昼夜或黑暗预算下的可见性/可读性。
- godot-genre-horror — 利用稀疏光源、雾效和 ReflectionProbe 室内环境营造以紧张感为先的氛围。
- godot-debugging-profiling — 使用调试器/监视器视图确认阴影图集和 GI 的开销,再决定是否删减功能,避免盲目操作。
主技能
- godot-master — 技能库路由器和镜像模块入口;需要了解哪个 Domain Skill 负责跨领域光照问题时,请从此处开始。