强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

Godot 4 GDScript 教程 / 光照与环境

光照与环境

概述

Godot 4 的光照系统基于 Vulkan 渲染器,支持实时光照和多种全局光照(GI)方案。环境系统(Environment)统一管理天空、雾、色调映射和后处理效果。

光照节点说明
DirectionalLight3D方向光(太阳光)
OmniLight3D点光源(灯泡)
SpotLight3D聚光灯(手电筒)
GI 节点说明
VoxelGI体素全局光照
LightmapGI光照贴图烘焙
LightmapProbe光照探针
ReflectionProbe反射探针

DirectionalLight3D(方向光)

方向光模拟无限远处的光源(如太阳),所有光线平行。

extends DirectionalLight3D

func _ready():
    # 基本设置
    light_color = Color(1.0, 0.95, 0.9)  # 暖白色
    light_energy = 1.0
    shadow_enabled = true

    # 方向光特有属性
    # 光照角度(通过旋转设置)
    rotation_degrees = Vector3(-45, 30, 0)

    # 阴影模式
    directional_shadow_mode = DirectionalLight3D.SHADOW_PARALLEL_4_SPLITS

    # 阴影参数
    directional_shadow_max_distance = 100.0
    directional_shadow_split_1 = 0.1
    directional_shadow_split_2 = 0.2
    directional_shadow_split_3 = 0.5

    # 阴影模糊
    directional_shadow_blur = 1.0

    # 光源范围
    # 方向光影响整个场景

阴影分片模式

模式说明适用场景
SHADOW_ORTHOGONAL正交阴影大型场景
SHADOW_PARALLEL_2_SPLITS2 分区级联中型场景
SHADOW_PARALLEL_4_SPLITS4 分区级联大型场景精度高

OmniLight3D(点光源)

点光源从一个点向所有方向发射光线。

extends OmniLight3D

func _ready():
    # 基本参数
    light_color = Color(1, 0.8, 0.5)  # 暖色光
    light_energy = 2.0
    shadow_enabled = true

    # 点光源特有
    omni_range = 10.0       # 影响范围
    omni_attenuation = 1.0  # 衰减系数

    # 衰减公式:attenuation = 1 - (distance / range) ^ attenuation_exp
    # omni_attenuation 越大,光线衰减越快

衰减参数对比

attenuation效果
0.0无衰减(不推荐)
1.0线性衰减
2.0二次衰减(最接近物理)

SpotLight3D(聚光灯)

聚光灯从一个点向特定方向发射锥形光线。

extends SpotLight3D

func _ready():
    light_color = Color(1, 1, 0.8)
    light_energy = 3.0
    shadow_enabled = true

    # 聚光灯特有
    spot_range = 15.0          # 照射距离
    spot_attenuation = 1.0     # 衰减
    spot_angle = 30.0          # 锥角(度)
    spot_angle_attenuation = 1.0  # 边缘衰减

    # spot_angle_attenuation 越大,边缘越硬

💡 提示spot_angle 控制锥角大小,spot_angle_attenuation 控制边缘柔和度。值越大边缘越锐利。


GI 全局光照

VoxelGI(体素全局光照)

实时计算间接光照,适合室内场景和动态光源。

extends Node3D

func setup_voxel_gi():
    var voxel_gi = VoxelGI.new()
    # 设置覆盖范围
    voxel_gi.size = Vector3(20, 10, 20)
    # 体素细分(越大精度越高,性能越差)
    voxel_gi.subdiv = VoxelGI.SUBDIV_128
    add_child(voxel_gi)
    # 需要在编辑器中烘焙
细分级别体素数内存精度
SUBDIV_1616³
SUBDIV_3232³中低中低
SUBDIV_6464³
SUBDIV_128128³
SUBDIV_256256³很高很高
SUBDIV_512512³极高极高

VoxelGI 烘焙流程

  1. 在场景中添加 VoxelGI 节点
  2. 设置 size 覆盖需要 GI 的区域
  3. 确保 MeshInstance3D 启用 Use In Baked Light(全局光照属性)
  4. 选中 VoxelGI 节点 → 点击编辑器中的 “Bake VoxelGI” 按钮

⚠️ 注意:VoxelGI 仅对启用 global_transform 的静态网格生效。动态物体(RigidBody)可接收 GI,但不贡献 GI。

LightmapGI(光照贴图)

预烘焙光照到纹理,运行时零计算开销,适合室外大型场景。

extends Node3D

func setup_lightmap():
    var lightmap = LightmapGI.new()
    # 烘焙质量
    lightmap.quality = LightmapGI.QUALITY_HIGH
    # 光线弹射次数
    lightmap.bounces = 3
    # 生成探针
    lightmap.generate_probes = LightmapGI.GENERATE_PROBES_SUBDIV_8
    # 分辨率
    lightmap.environment_custom_sky = preload("res://sky.tres")
    add_child(lightmap)

LightmapGI 烘焙流程

  1. 场景中添加 LightmapGI 节点
  2. MeshInstance3D 导入时启用 “Generate Lightmap UV”
  3. 确保所有静态网格启用 Use In Baked Light
  4. 选中 LightmapGI → “Bake Lightmaps”
  5. 烘焙完成后保存 .lmbake 文件
质量设置说明
QUALITY_LOW快速烘焙,低质量
QUALITY_MEDIUM平衡
QUALITY_HIGH高质量
QUALITY_ULTRA最高质量,烘焙慢

SDFGI(SDF 全局光照)

Godot 4 的 SDFGI 是一种无需烘焙的全局光照方案,适合大型开放世界。

extends WorldEnvironment

func _ready():
    var env = Environment.new()

    # 启用 SDFGI
    env.sdfgi_enabled = true
    # SDFGI 参数
    env.sdfgi_use_occlusion = true  # 遮挡剔除
    env.sdfgi_cascade0_distance = 12.8  # 近处精度
    env.sdfgi_num_cascades = 8          # 级联数量(2~8)
    env.sdfgi_energy = 1.0
    env.sdfgi_normal_bias = 1.0
    env.sdfgi_probe_bias = 1.0

    environment = env

💡 提示:SDFGI 无需烘焙,但 GPU 开销较大。适合室外开放世界,室内效果不如 VoxelGI/LightmapGI。


ReflectionProbe(反射探针)

extends ReflectionProbe

func _ready():
    # 反射探针覆盖区域
    size = Vector3(10, 6, 10)

    # 反射更新模式
    update_mode = ReflectionProbe.UPDATE_ONCE  # 静态环境
    # update_mode = ReflectionProbe.UPDATE_ALWAYS  # 动态环境(性能高)

    # 混合距离(边缘过渡)
    blend_distance = 1.0

    # 环境模式
    ambient_mode = ReflectionProbe.AMBIENT_ENVIRONMENT
    ambient_color = Color(0.1, 0.1, 0.1)
    ambient_color_energy = 0.5

    # 是否覆盖天空
    box_projection = true  # 适合室内
    interior = true        # 室内模式,忽略天空

Environment 环境设置

天空设置

extends WorldEnvironment

func _ready():
    var env = Environment.new()

    # 程序化天空
    var sky = Sky.new()
    var sky_mat = ProceduralSkyMaterial.new()
    sky_mat.sky_top_color = Color(0.3, 0.5, 0.8)
    sky_mat.sky_horizon_color = Color(0.6, 0.7, 0.9)
    sky_mat.ground_bottom_color = Color(0.1, 0.07, 0.05)
    sky_mat.ground_horizon_color = Color(0.6, 0.7, 0.9)
    sky_mat.sun_angle_max = 30.0
    sky_mat.sun_longitude = 120.0
    sky.sky_material = sky_mat
    env.sky = sky
    env.background_mode = Environment.BG_SKY

    environment = env

雾效

func setup_fog(env: Environment):
    env.fog_enabled = true
    env.fog_light_color = Color(0.7, 0.8, 0.9)
    env.fog_light_energy = 1.0
    env.fog_density = 0.01
    env.fog_aerial_perspective = 0.5  # 空气透视
    env.fog_height = -10.0            # 雾高度
    env.fog_height_density = 0.2      # 高度雾密度

    # 体积雾(Volumetric Fog)
    env.volumetric_fog_enabled = true
    env.volumetric_fog_density = 0.03
    env.volumetric_fog_albedo = Color(0.9, 0.9, 0.9)
    env.volumetric_fog_emission = Color(0, 0, 0)
    env.volumetric_fog_gi_inject = 0.5
    env.volumetric_fog_anisotropy = 0.8
    env.volumetric_fog_length = 128.0

色调映射

func setup_tonemap(env: Environment):
    # 色调映射模式
    env.tonemap_mode = Environment.TONE_MAP_ACES
    env.tonemap_exposure = 1.0
    env.tonemap_white = 6.0

    # 对比度和饱和度
    env.adjustment_enabled = true
    env.adjustment_brightness = 1.0
    env.adjustment_contrast = 1.0
    env.adjustment_saturation = 1.1  # 轻微增加饱和度

色调映射模式

模式特点适用场景
TONE_MAP_LINEAR线性映射无特殊需求
TONE_MAP_REINHARD经典算法通用
TONE_MAP_FILMIC电影风格电影感
TONE_MAP_ACESACES 标准推荐默认
TONE_MAP_AGXAgX 新算法高保真

SSAO(屏幕空间环境光遮蔽)

func setup_ssao(env: Environment):
    env.ssao_enabled = true
    env.ssao_radius = 1.0           # 采样半径
    env.ssao_intensity = 2.0        # 强度
    env.ssao_power = 1.5            # 对比度
    env.ssao_detail = 0.5           # 细节
    env.ssao_horizon = 0.06         # 地平线剔除
    env.ssao_sharpness = 0.98       # 锐度
    env.ssao_light_affect = 0.0     # 光照影响

SSR(屏幕空间反射)

func setup_ssr(env: Environment):
    env.ssr_enabled = true
    env.ssr_max_steps = 64          # 追踪步数
    env.ssr_fade_in = 0.15          # 淡入
    env.ssr_fade_out = 2.0          # 淡出
    env.ssr_depth_tolerance = 0.2   # 深度容差
    env.ssr_roughness = true        # 粗糙反射

发光(Glow)

func setup_glow(env: Environment):
    env.glow_enabled = true
    env.glow_intensity = 0.4
    env.glow_strength = 1.0
    env.glow_bloom = 0.1
    env.glow_blend_mode = Environment.GLOW_BLEND_MODE_SOFTLIGHT
    env.glow_hdr_threshold = 1.0   # HDR 阈值
    env.glow_hdr_luminance_cap = 12.0
    env.glow_map_strength = 1.0

BOKEH(景深)

func setup_dof(env: Environment):
    env.dof_blur_far_enabled = true
    env.dof_blur_far_distance = 10.0   # 焦点距离
    env.dof_blur_far_transition = 5.0  # 过渡范围
    env.dof_blur_far_amount = 0.1      # 模糊量

    env.dof_blur_near_enabled = true
    env.dof_blur_near_distance = 2.0
    env.dof_blur_near_transition = 1.0
    env.dof_blur_near_amount = 0.1

完整环境设置示例

extends Node3D

func _ready():
    var env = Environment.new()

    # 天空
    var sky = Sky.new()
    var sky_mat = PhysicalSkyMaterial.new()
    sky_mat.rayleigh_coefficient = 2.0
    sky_mat.mie_coefficient = 0.005
    sky_mat.turbidity = 3.0
    sky.sky_material = sky_mat
    env.sky = sky
    env.background_mode = Environment.BG_SKY

    # 环境光
    env.ambient_light_source = Environment.AMBIENT_SOURCE_SKY
    env.ambient_light_energy = 0.3

    # 色调映射
    env.tonemap_mode = Environment.TONE_MAP_ACES
    env.tonemap_exposure = 1.2

    # SSAO
    env.ssao_enabled = true

    # 发光
    env.glow_enabled = true
    env.glow_intensity = 0.2

    # 雾
    env.fog_enabled = true
    env.fog_density = 0.005

    var world_env = WorldEnvironment.new()
    world_env.environment = env
    add_child(world_env)

光照性能优化策略

策略说明
使用 LightmapGI 替代实时光照烘焙后零 GPU 开销
减少阴影光源数量每个阴影光源增加 Draw Call
降低阴影分辨率Project Settings → Rendering → Lights
禁用远处阴影directional_shadow_max_distance
限制 OmniLight 范围小范围减少着色器计算
使用 LOD远处物体降低材质精度
合理选择 GI 方案室内用 VoxelGI,室外用 SDFGI/LightmapGI

实时光照 vs 烘焙选择

方案实时GPU 开销内存适用场景
实时光照动态光源
VoxelGI室内动态
LightmapGI极低室外静态
SDFGI开放世界

💡 提示:大型项目常混合使用——室内使用 LightmapGI,室外使用 SDFGI,动态物体使用实时光。


游戏开发场景

场景推荐方案
室外白天DirectionalLight + SDFGI + 雾
室内暗室OmniLight + VoxelGI + SSAO
夜景手电筒SpotLight + 体积雾
恐怖氛围低光 + 高 SSAO + 体积雾
赛博朋克发光材质 + Glow + 高对比度
怀旧风格低环境光 + 线性色调映射

⚠️ 常见陷阱

  1. 阴影光源越多性能越差,建议同时不超过 3~5 个阴影光源
  2. VoxelGI 需要烘焙,烘焙前确保场景网格启用 Use In Baked Light
  3. SDFGI 在室内效果不佳,容易漏光
  4. LightmapGI 的 UV 重叠会导致光照错误,导入时启用 Generate Lightmap UV
  5. 体积雾对性能影响大,低端设备慎用

扩展阅读