mcpField
G
godot-3d-lighting

godot-3d-lighting

github.com/thedivergentai创意与媒体907444 次安装2 周前更新
代码仓库

关于 godot-3d-lighting

面向 Godot 的 3D 灯光技能,涵盖真实感照明、阴影与全局光照。它按场景类型提供配置路线,并通过脚本说明常见效果与性能取舍。

主要功能

  1. 01按场景选择照明路线
  2. 02阴影级联与偏移调节
  3. 03全局光照配置模式
  4. 04灯光与阴影性能预算
  5. 05雾效、环境与反射效果

适用场景

  1. 01配置室内或户外场景照明
  2. 02为移动或动态场景选择全局光照
  3. 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.md
gi-and-bake-recipes.md
migration-notes.md
scripts/
day_night_cycle.gd
environment_blender.gd
fake_gi_bounce.gd
light_lod_optimizer.gd
light_probe_manager.gd
light_volume_trigger.gd
lighting_manager.gd
lighting_quality_manager.gd
lightmap_bake_helper.gd
reflection_probe_manager.gd
sdfgi_probe_manager.gd
shadow_bias_tuner.gd
shadow_cascade_tuner.gd
spotlight_projector_setup.gd
volumetric_fog_zones.gd
volumetric_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,用于局部密度)纯光源预算 / 阴影图集调优任务
纯光源预算 / 阴影 LODlight_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.gdLightmapGI + 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 负责跨领域光照问题时,请从此处开始。

评论

支持 Markdown