Environment
最后同步日期:2026-04-15 | Godot 官方原文 — Environment
Environment
定义
Environment 是 Godot 中用于控制场景全局视觉效果的资源。它就像场景的"天气和氛围系统"——天空长什么样、有没有雾、光照多亮、物体有没有反光、画面色调偏冷还是偏暖,都由它说了算。
一个 Environment 资源通常挂载在 WorldEnvironment 节点上(这个节点是场景中环境效果的"总开关")。你可以把它理解为"整个世界的滤镜和灯光设置表"——修改里面的参数就能改变整个场景的视觉风格,从阳光明媚到阴雨绵绵,只需调整几个数值。
常用属性和方法
| 方法 / 属性 | 返回值 / 类型 | 说明 |
|---|---|---|
Background | 枚举(BGMode) | 背景类型(天空盒、纯色、图片等) |
Sky | Sky 资源 | 天空资源,配合 BGMode.Sky 使用 |
AmbientLightSource | 枚举 | 环境光来源(背景色、天空、固定值) |
AmbientLightColor | Color | 环境光颜色 |
AmbientLightEnergy | float | 环境光强度 |
FogEnabled | bool | 是否启用雾效果 |
FogLightColor | Color | 雾的颜色 |
FogDepthBegin | float | 雾开始出现的距离 |
FogDepthEnd | float | 雾完全遮蔽的最远距离 |
TonemapMode | 枚举(ToneMapper) | 色调映射模式 |
TonemapExposure | float | 曝光度 |
SsaoEnabled | bool | 是否启用屏幕空间环境光遮蔽(SSAO) |
SsrEnabled | bool | 是否启用屏幕空间反射(SSR) |
GlowEnabled | bool | 是否启用泛光效果 |
AdjustmentBrightness | float | 画面整体亮度 |
AdjustmentContrast | float | 画面整体对比度 |
AdjustmentSaturation | float | 画面整体饱和度 |
代码示例
基础用法:创建并应用环境效果
using Godot;
/// <summary>
/// 演示如何通过代码创建 Environment 并应用到 WorldEnvironment 节点。
/// </summary>
public partial class BasicEnvironmentDemo : Node3D
{
private WorldEnvironment _worldEnv;
public override void _Ready()
{
// 1. 创建 WorldEnvironment 节点
_worldEnv = new WorldEnvironment();
AddChild(_worldEnv);
// 2. 创建 Environment 资源
var env = new Environment();
// 3. 设置背景为天空
env.Background = Environment.BGMode.Sky;
var sky = new Sky();
sky.SkyMaterial = new ProceduralSkyMaterial();
env.Sky = sky;
// 4. 设置环境光
env.AmbientLightSource = Environment.AmbientSource.Sky;
env.AmbientLightColor = new Color(0.6f, 0.7f, 0.9f);
env.AmbientLightEnergy = 0.5f;
// 5. 设置色调映射
env.TonemapMode = Environment.ToneMapper.Filmic;
env.TonemapExposure = 1.0f;
// 6. 应用
_worldEnv.Environment = env;
GD.Print("环境已设置:蓝天 + 环境光 + Filmic 色调映射");
// 运行结果: 环境已设置:蓝天 + 环境光 + Filmic 色调映射
}
}extends Node3D
## 演示如何通过代码创建 Environment 并应用到 WorldEnvironment 节点。
var _world_env: WorldEnvironment
func _ready():
# 1. 创建 WorldEnvironment 节点
_world_env = WorldEnvironment.new()
add_child(_world_env)
# 2. 创建 Environment 资源
var env = Environment.new()
# 3. 设置背景为天空
env.background_mode = Environment.BG_SKY
var sky = Sky.new()
sky.sky_material = ProceduralSkyMaterial.new()
env.sky = sky
# 4. 设置环境光
env.ambient_light_source = Environment.AMBIENT_SOURCE_SKY
env.ambient_light_color = Color(0.6, 0.7, 0.9)
env.ambient_light_energy = 0.5
# 5. 设置色调映射
env.tonemap_mode = Environment.TONE_MAPPER_FILMIC
env.tonemap_exposure = 1.0
# 6. 应用
_world_env.environment = env
print("环境已设置:蓝天 + 环境光 + Filmic 色调映射")
# 运行结果: 环境已设置:蓝天 + 环境光 + Filmic 色调映射实际场景:日夜循环系统
using Godot;
/// <summary>
/// 日夜循环系统:通过平滑修改 Environment 参数,
/// 实现白天到黑夜的渐变过渡。
/// </summary>
public partial class DayNightCycle : Node3D
{
[Export] public WorldEnvironment ExWorldEnv { get; set; }
[Export] public DirectionalLight3D ExSunLight { get; set; }
[Export] public float ExDayDuration = 60f; // 一个完整日夜循环的秒数
private Environment _env;
private float _timeOfDay = 0.25f; // 0=午夜, 0.25=日出, 0.5=正午, 0.75=日落
public override void _Ready()
{
if (ExWorldEnv != null)
{
_env = ExWorldEnv.Environment;
}
}
public override void _Process(double delta)
{
if (_env == null) return;
// 推进时间
_timeOfDay += (float)delta / ExDayDuration;
if (_timeOfDay >= 1f) _timeOfDay -= 1f;
// 根据时间计算"太阳高度"(0=地平线, 1=天顶)
float sunHeight = Mathf.Sin(_timeOfDay * Mathf.Tau);
float daylight = Mathf.Clamp(sunHeight, 0f, 1f);
// ---- 环境光 ----
_env.AmbientLightEnergy = Mathf.Lerp(0.05f, 0.6f, daylight);
var dayColor = new Color(0.7f, 0.8f, 1.0f);
var nightColor = new Color(0.05f, 0.05f, 0.15f);
_env.AmbientLightColor = dayColor.Lerp(nightColor, 1f - daylight);
// ---- 雾效果 ----
_env.FogEnabled = true;
_env.FogLightColor = dayColor.Lerp(nightColor, 1f - daylight);
_env.FogDepthBegin = Mathf.Lerp(10f, 5f, daylight);
_env.FogDepthEnd = Mathf.Lerp(80f, 40f, daylight);
// ---- 曝光 ----
_env.TonemapExposure = Mathf.Lerp(0.3f, 1.0f, daylight);
// ---- 太阳光 ----
if (ExSunLight != null)
{
// 旋转太阳方向
float sunAngle = _timeOfDay * 360f;
ExSunLight.RotationDegrees = new Vector3(sunAngle - 90f, 0f, 0f);
ExSunLight.LightEnergy = Mathf.Lerp(0f, 1.2f, daylight);
// 日出/日落时偏暖色
var sunColor = new Color(1f, 1f, 0.9f).Lerp(
new Color(1f, 0.6f, 0.3f),
1f - Mathf.Abs(daylight - 0.5f) * 2f
);
ExSunLight.LightColor = sunColor;
}
}
/// <summary>
/// 获取当前时间描述
/// </summary>
public string GetTimeDescription()
{
if (_timeOfDay < 0.2f) return "深夜";
if (_timeOfDay < 0.3f) return "日出";
if (_timeOfDay < 0.45f) return "上午";
if (_timeOfDay < 0.55f) return "正午";
if (_timeOfDay < 0.7f) return "下午";
if (_timeOfDay < 0.8f) return "日落";
return "夜晚";
}
}extends Node3D
## 日夜循环系统:通过平滑修改 Environment 参数,
## 实现白天到黑夜的渐变过渡。
@export var world_env: WorldEnvironment
@export var sun_light: DirectionalLight3D
@export var day_duration: float = 60.0 # 一个完整日夜循环的秒数
var _env: Environment
var _time_of_day: float = 0.25 # 0=午夜, 0.25=日出, 0.5=正午, 0.75=日落
func _ready():
if world_env:
_env = world_env.environment
func _process(delta: float) -> void:
if _env == null:
return
# 推进时间
_time_of_day += delta / day_duration
if _time_of_day >= 1.0:
_time_of_day -= 1.0
# 根据时间计算"太阳高度"(0=地平线, 1=天顶)
var sun_height: float = sin(_time_of_day * TAU)
var daylight: float = clampf(sun_height, 0.0, 1.0)
# ---- 环境光 ----
_env.ambient_light_energy = lerpf(0.05, 0.6, daylight)
var day_color = Color(0.7, 0.8, 1.0)
var night_color = Color(0.05, 0.05, 0.15)
_env.ambient_light_color = day_color.lerp(night_color, 1.0 - daylight)
# ---- 雾效果 ----
_env.fog_enabled = true
_env.fog_light_color = day_color.lerp(night_color, 1.0 - daylight)
_env.fog_depth_begin = lerpf(10.0, 5.0, daylight)
_env.fog_depth_end = lerpf(80.0, 40.0, daylight)
# ---- 曝光 ----
_env.tonemap_exposure = lerpf(0.3, 1.0, daylight)
# ---- 太阳光 ----
if sun_light:
var sun_angle: float = _time_of_day * 360.0
sun_light.rotation_degrees = Vector3(sun_angle - 90.0, 0.0, 0.0)
sun_light.light_energy = lerpf(0.0, 1.2, daylight)
# 日出/日落时偏暖色
var sun_color = Color(1.0, 1.0, 0.9).lerp(
Color(1.0, 0.6, 0.3),
1.0 - abs(daylight - 0.5) * 2.0
)
sun_light.light_color = sun_color
## 获取当前时间描述
func get_time_description() -> String:
if _time_of_day < 0.2: return "深夜"
if _time_of_day < 0.3: return "日出"
if _time_of_day < 0.45: return "上午"
if _time_of_day < 0.55: return "正午"
if _time_of_day < 0.7: return "下午"
if _time_of_day < 0.8: return "日落"
return "夜晚"进阶用法:动态切换场景风格(室内/室外/战斗)
using Godot;
/// <summary>
/// 根据游戏状态动态切换 Environment 风格。
/// 三种预设:正常室外、温暖室内、激烈战斗。
/// </summary>
public partial class EnvironmentSwitcher : Node
{
public enum EnumSceneStyle { Outdoor, Indoor, Combat }
[Export] public WorldEnvironment ExWorldEnv { get; set; }
private Environment _env;
private EnumSceneStyle _currentStyle = EnumSceneStyle.Outdoor;
// 预设参数
private static readonly Color OutdoorAmbient = new(0.6f, 0.75f, 0.95f);
private static readonly Color IndoorAmbient = new(1f, 0.85f, 0.6f);
private static readonly Color CombatAmbient = new(0.8f, 0.2f, 0.15f);
public override void _Ready()
{
if (ExWorldEnv != null)
{
_env = ExWorldEnv.Environment;
if (_env == null)
{
_env = new Environment();
ExWorldEnv.Environment = _env;
}
ApplyStyle(EnumSceneStyle.Outdoor);
}
}
public void SwitchStyle(EnumSceneStyle style)
{
if (_env == null) return;
ApplyStyle(style);
_currentStyle = style;
GD.Print($"场景风格切换为: {style}");
// 运行结果: 场景风格切换为: Combat
}
private void ApplyStyle(EnumSceneStyle style)
{
switch (style)
{
case EnumSceneStyle.Outdoor:
_env.Background = Environment.BGMode.Sky;
_env.AmbientLightSource = Environment.AmbientSource.Sky;
_env.AmbientLightColor = OutdoorAmbient;
_env.AmbientLightEnergy = 0.5f;
_env.TonemapMode = Environment.ToneMapper.Filmic;
_env.TonemapExposure = 1.0f;
_env.FogEnabled = true;
_env.FogLightColor = new Color(0.8f, 0.85f, 0.95f);
_env.FogDepthBegin = 20f;
_env.FogDepthEnd = 100f;
_env.GlowEnabled = true;
_env.SsaoEnabled = true;
_env.AdjustmentSaturation = 1.0f;
_env.AdjustmentBrightness = 1.0f;
break;
case EnumSceneStyle.Indoor:
_env.Background = Environment.BGMode.Color;
_env.BackgroundColor = new Color(0.1f, 0.08f, 0.06f);
_env.AmbientLightSource = Environment.AmbientSource.Color;
_env.AmbientLightColor = IndoorAmbient;
_env.AmbientLightEnergy = 0.3f;
_env.TonemapExposure = 0.8f;
_env.FogEnabled = false;
_env.GlowEnabled = false;
_env.SsaoEnabled = true;
_env.AdjustmentSaturation = 0.9f;
_env.AdjustmentBrightness = 0.9f;
break;
case EnumSceneStyle.Combat:
_env.Background = Environment.BGMode.Sky;
_env.AmbientLightSource = Environment.AmbientSource.Color;
_env.AmbientLightColor = CombatAmbient;
_env.AmbientLightEnergy = 0.4f;
_env.TonemapExposure = 1.3f;
_env.FogEnabled = true;
_env.FogLightColor = new Color(0.5f, 0.15f, 0.1f);
_env.FogDepthBegin = 15f;
_env.FogDepthEnd = 60f;
_env.GlowEnabled = true;
_env.GlowIntensity = 0.8f;
_env.SsaoEnabled = false;
_env.AdjustmentSaturation = 1.3f;
_env.AdjustmentContrast = 1.2f;
break;
}
}
}extends Node
## 根据游戏状态动态切换 Environment 风格。
## 三种预设:正常室外、温暖室内、激烈战斗。
enum SceneStyle { OUTDOOR, INDOOR, COMBAT }
@export var world_env: WorldEnvironment
var _env: Environment
var _current_style: SceneStyle = SceneStyle.OUTDOOR
# 预设参数
const OUTDOOR_AMBIENT := Color(0.6, 0.75, 0.95)
const INDOOR_AMBIENT := Color(1.0, 0.85, 0.6)
const COMBAT_AMBIENT := Color(0.8, 0.2, 0.15)
func _ready():
if world_env:
_env = world_env.environment
if _env == null:
_env = Environment.new()
world_env.environment = _env
_apply_style(SceneStyle.OUTDOOR)
func switch_style(style: SceneStyle) -> void:
if _env == null:
return
_apply_style(style)
_current_style = style
print("场景风格切换为: %s" % SceneStyle.keys()[style])
# 运行结果: 场景风格切换为: COMBAT
func _apply_style(style: SceneStyle) -> void:
match style:
SceneStyle.OUTDOOR:
_env.background_mode = Environment.BG_SKY
_env.ambient_light_source = Environment.AMBIENT_SOURCE_SKY
_env.ambient_light_color = OUTDOOR_AMBIENT
_env.ambient_light_energy = 0.5
_env.tonemap_mode = Environment.TONE_MAPPER_FILMIC
_env.tonemap_exposure = 1.0
_env.fog_enabled = true
_env.fog_light_color = Color(0.8, 0.85, 0.95)
_env.fog_depth_begin = 20.0
_env.fog_depth_end = 100.0
_env.glow_enabled = true
_env.ssao_enabled = true
_env.adjustment_saturation = 1.0
_env.adjustment_brightness = 1.0
SceneStyle.INDOOR:
_env.background_mode = Environment.BG_COLOR
_env.background_color = Color(0.1, 0.08, 0.06)
_env.ambient_light_source = Environment.AMBIENT_SOURCE_COLOR
_env.ambient_light_color = INDOOR_AMBIENT
_env.ambient_light_energy = 0.3
_env.tonemap_exposure = 0.8
_env.fog_enabled = false
_env.glow_enabled = false
_env.ssao_enabled = true
_env.adjustment_saturation = 0.9
_env.adjustment_brightness = 0.9
SceneStyle.COMBAT:
_env.background_mode = Environment.BG_SKY
_env.ambient_light_source = Environment.AMBIENT_SOURCE_COLOR
_env.ambient_light_color = COMBAT_AMBIENT
_env.ambient_light_energy = 0.4
_env.tonemap_exposure = 1.3
_env.fog_enabled = true
_env.fog_light_color = Color(0.5, 0.15, 0.1)
_env.fog_depth_begin = 15.0
_env.fog_depth_end = 60.0
_env.glow_enabled = true
_env.glow_intensity = 0.8
_env.ssao_enabled = false
_env.adjustment_saturation = 1.3
_env.adjustment_contrast = 1.2注意事项
每个场景只能有一个 WorldEnvironment:Godot 会自动合并多个
WorldEnvironment节点,但建议每个场景只保留一个,避免混淆。WorldEnvironment节点相当于场景中 Environment 效果的"总管理器"。Environment 是资源(Resource):它继承自
Resource,意味着可以在多个场景之间共享同一个 Environment 实例。但如果你需要不同场景有不同的效果,应该为每个场景创建独立的 Environment。修改会立即生效:所有对 Environment 属性的修改都会实时反映在画面上,不需要额外的"刷新"操作。这在制作日夜循环、动态天气等效果时非常方便。
部分效果依赖渲染器:SSAO(屏幕空间环境光遮蔽)、SSR(屏幕空间反射)、Glow(泛光)等高级效果仅在 Forward+ 渲染器下完全可用。Mobile 和 Compatibility 渲染器可能不支持全部功能。
性能开销:启用的效果越多,渲染开销越大。SSAO 和 SSR 尤其消耗性能,在移动端应谨慎使用。建议在设置面板中提供效果开关,让低端设备的玩家可以关闭这些效果。
