- 文档
- 教程
- 游戏开发
【免费下载链接】godot-docs
Godot Engine official documentation
DirectionalLight2D 是 Godot 中模拟太阳光、月光的核心 2D 光照节点:它以覆盖全场景的无限平行光线为特征,光源位置不影响光照结果,只有旋转角度决定光线的方向。本文将以 Godot 官方文档(classes/class_directionallight2d.rst)为骨架,结合 2D 光照与阴影教程、Light2D 基类文档 及 CanvasItem 着色器参考,系统讲解该节点的光照方向语义、height 与 max_distance 两个专属属性、继承自 Light2D 的通用光照/阴影参数,以及在实际 2D 场景(横版平台游戏、俯视角游戏)中的完整配置流程。读完你将能够独立搭建一套带法线贴图与软阴影的 2D 日光照明系统,并理解其底层渲染原理。
DirectionalLight2D 是什么
DirectionalLight2D 是一种 Light2D 节点,它模拟的是来自无穷远处的无限平行光线,覆盖整个 2D 场景。这类光适用于强度高、距离场景极远的照明源——最典型的用途就是模拟太阳光或月光。
其完整继承链为:
DirectionalLight2D → Light2D → Node2D → CanvasItem → Node → Object与同属 Light2D 子类的 PointLight2D(点光源/位置光)不同,方向光的特征在于:
- 光线彼此平行,如同太阳或月亮距离受光面无穷远;
- 节点位置被忽略,只有旋转(basis)决定光线方向;
- 因此在场景中移动 DirectionalLight2D 节点不会改变光照效果,旋转它才会。
光照方向语义:+Y 轴与全局基
官方文档明确规定了方向光的发射语义:
光线沿节点全局基(global basis)的+Y 方向发射。对于未旋转的光源,这意味着光线向下发射。节点的位置被忽略,只有基用于确定光的方向。
这是 2D 光照方向与 3D 的一个关键差异。在 Godot 2D 坐标系中,Y 轴向下为正,因此:
- 默认(不旋转)的 DirectionalLight2D 发出向下的光,适合"天光从画面顶部照向地面"的常规场景;
- 通过
rotation_degrees或rotation调整节点角度,即可让光线从任意斜向照射——例如清晨(低角度斜光)或傍晚(另一侧斜光),只需要旋转 DirectionalLight2D 节点即可,无需移动它。
从底层实现看,RenderingServer 中通过枚举CANVAS_LIGHT_MODE_DIRECTIONAL = 1标记 2D 方向光(sun/moon light),并在 CanvasItem 着色器中通过内置变量区分方向光与点光:LIGHT_POSITION对 DirectionalLight2D 恒为(0.0, 0.0, 0.0),而LIGHT_IS_DIRECTIONAL为true(详见 canvas_item_shader.rst)。这意味着在自定义 2D 着色器里,可以依据LIGHT_IS_DIRECTIONAL分支编写专属于方向光的着色逻辑。
专属属性详解
DirectionalLight2D 在 Light2D 基类之上只新增了两个专属属性:
height(高度,默认0.0)
用于2D 法线贴图(normal mapping)的光源虚拟高度,取值范围从0(与受光面平行)到1(与受光面垂直)。默认值0.0表示光线与表面完全平行,此时若使用法线贴图,光照几乎不可见——因此官方建议在启用法线贴图后适当增大 height(例如 0.5~1.0 之间的数值),并在启用法线贴图后略微提升 Energy 以补偿观感上的变暗。
需要特别强调的是:height 只影响法线贴图表面的视觉表现,不影响阴影的外观(详见 2D 光照教程)。这与法线贴图的工作原理一致——法线贴图以逐像素方式记录表面朝向,光源高度决定入射角,从而改变光照强度分布。
对应的 setter/getter 为set_height(value)/get_height(),该对方法实际继承自 Light2D 基类(见 class_light2d.rst),在 PointLight2D 与 DirectionalLight2D 上共用。
max_distance(最大距离,默认10000.0)
物体与摄像机中心的距离超过该值(以像素计)时,其阴影会被裁剪(cull)。减小此值可以防止摄像机视野之外的物体投射阴影,同时提升渲染性能。
需要注意Camera2D.zoom不会被max_distance考虑在内,这意味着缩放(zoom)越大,阴影会显得越早淡出。理解这一点对制作镜头缩放的横版游戏尤为重要:如果场景中的物体在远摄视角下阴影异常消失,优先检查 max_distance 与当前 Camera2D 的 zoom 组合。
在实战中,max_distance 是方向光性能调优的核心旋钮之一:方向光阴影作用于整幅场景,若不裁剪远处物体的阴影,渲染负担会显著增加。配合将场景边界外的 LightOccluder2D 排除在外,可获得明显的性能收益。
继承自 Light2D 的通用属性
DirectionalLight2D 与 PointLight2D 共享 Light2D 基类提供的光照与阴影参数(完整列表见 Light2D 属性表),在 Inspector 中表现为以下项目:
| 属性 | 默认值 | 说明 |
|---|---|---|
| Enabled | true | 是否发光。与隐藏节点不同,禁用此属性不会隐藏光的子节点 |
| Editor Only | false | 仅在编辑器内可见,运行时自动禁用,便于编辑辅助 |
| Color | Color(1, 1, 1, 1) | 光颜色,可做日出/日落的暖色、月光冷色等艺术化处理 |
| Energy | 1.0 | 强度倍率,越大越亮 |
| Blend Mode | 0(Add) | 混合模式:BLEND_MODE_ADD=0加法(默认,最常用)、BLEND_MODE_SUB=1减法(负光,用于特效)、BLEND_MODE_MIX=2线性插值混合 |
| Range > Z Min / Z Max | -1024/1024 | 受光物体的 z 索引范围 |
| Range > Layer Min / Max | 0/0 | 受光物体的视觉层范围 |
| Range > Item Cull Mask | 1 | 控制哪些节点接收光照(依据对方 CanvasItem 的 light_mask) |
| Shadow > Enabled | false | 是否投射阴影 |
| Shadow > Color | Color(0,0,0,0) | 阴影颜色,alpha 控制阴影着色程度,默认纯黑 |
| Shadow > Filter | 0(None) | 阴影过滤:SHADOW_FILTER_NONE=0(硬边,最快)、SHADOW_FILTER_PCF5=1(5 采样 PCF)、SHADOW_FILTER_PCF13=2(13 采样,最软但最慢) |
| Shadow > Filter Smooth | 0.0 | 仅在 Filter 为 PCF5/PCF13 时生效,值越高阴影越软,但可能产生可见的带状伪影 |
| Shadow > Item Cull Mask | 1 | 控制哪些 LightOccluder2D投射阴影 |
关键差异:光照剔除掩码(light cull mask)对 DirectionalLight2D 无效,但阴影剔除掩码(shadow cull mask)有效。
DirectionalLight2D 会无条件照亮所有 2D 节点,无论对方的 CanvasItem.light_mask 设置为何值。因此:
- 想用"某些物体不被方向光照亮"的方式做分层/混合,是行不通的;
- 想让某些遮挡物不投射方向光阴影,则可以在方向光的Shadow > Item Cull Mask与遮挡物的Occluder Light Mask上做位掩码匹配(详见 class_light2d.rst 的 Note 说明)。
这一行为也体现在 Inspector 中:方向光的 Range > Item Cull Mask 在运行时会被忽略。
实战:搭建一套日光/月光照明
以下是官方教程推荐的完整 2D 照明节点组合(2D 光照与阴影教程):
- CanvasModulate—— 设置场景基础"环境色",代表没有任何 2D 光照射区域最终的照明颜色。没有它,2D 光只会叠加在原本"全亮"的画面之上,最终场景过亮。
- DirectionalLight2D—— 太阳光或月光。
- PointLight2D—— 火炬、篝火、弹丸等局部光源(可选用)。
- LightOccluder2D—— 定义阴影投射体,可独立放置,也可作为 TileMapLayer 的一部分。
- 接收光照的普通 2D 节点(Sprite2D、TileMapLayer 等)。
创建方向光并开启阴影的步骤:
- 在场景中新建DirectionalLight2D节点;
- 调整
rotation(如 45°)获得斜向日光,或保持 0° 获得垂直向下光; - 在 Inspector 中设置Shadow > Enabled为
true; - 为需要投射阴影的 Sprite2D 创建LightOccluder2D:选中 Sprite2D,点击 2D 编辑器顶部的Sprite2D菜单,选择Create LightOccluder2D Sibling自动生成;若轮廓不贴合,可调整对话框中的Grow (pixels)/Shrink (pixels)后点击Update Preview反复校正(详见 阴影设置章节)。也可以手动新建 LightOccluder2D,用 2D 编辑器顶部的 "+" 按钮绘制遮挡多边形。
启用阴影后若没有视觉差异,原因几乎总是:场景中还没有任何遮挡体(occluder)。阴影必须以 LightOccluder2D 的遮挡多边形为投射基础。
注意:背景颜色不接收任何光照。若想让光照作用于背景,需要为背景添加可视表示(如 Sprite2D),并使用其Region属性配合Texture > Repeat = Enabled制作平铺背景。
阴影外观调优
- 硬阴影:Shadow > Filter 保持None,渲染最快,适合像素风("块状"视觉);
- 软阴影:设为PCF5可获得柔和阴影;PCF13更软但渲染开销最高,官方建议全场景同时使用的数量要克制;
- Filter Smooth:控制 PCF5/PCF13 下的软化程度,过高会出现带状条纹伪影(尤其 PCF5);
- Shadow > Color的 alpha 通道控制阴影着色强度,可做艺术化调整。
已知限制:方向光阴影永远表现为无限长,无论 height 属性如何设置——这是 Godot 2D 光照阴影渲染方法本身的局限(教程原文)。若需要"有限长"的方向光阴影,官方给出的方案是:关闭 DirectionalLight2D 的阴影,改用自定义着色器读取由场景中 LightOccluder2D 自动生成的2D 有向距离场(signed distance field, SDF)。
像素风游戏的阴影像素化
Godot 在视口像素分辨率上计算 2D 光照与阴影,而非源纹理的 texel 分辨率,因此最近邻纹理过滤并不会让光照/阴影变成像素风。要实现与像素美术风格匹配的块状光照阴影,需在 CanvasItem 着色器中把LIGHT_VERTEX与SHADOW_VERTEX对齐到像素网格(示例见 2D 光照教程):
shader_type canvas_item; uniform float pixel_size = 4.0; void fragment() { // 将光照与阴影对齐到像素网格。 LIGHT_VERTEX.xy = floor(LIGHT_VERTEX.xy / pixel_size) * pixel_size; SHADOW_VERTEX = floor(SHADOW_VERTEX / pixel_size) * pixel_size; // 正常渲染。 COLOR = texture(TEXTURE, UV); }其原理是先用pixel_size除以坐标转换到网格空间,再用floor()向下取整到最近网格点,最后乘回以还原到屏幕空间,从而强制引擎从离散网格位置采样光照。
法线贴图与 specular 贴图下的方向光
DirectionalLight2D 与 PointLight2D 均支持法线贴图与高光(specular)贴图,二者可赋予任意继承 Node2D 或 Control 的 2D 元素。配置方式是在 Sprite2D 等节点的纹理属性上创建CanvasTexture资源,然后分别指定:
- Diffuse > Texture:基础颜色纹理;
- Normal Map > Texture:法线贴图(从高度图生成,可用 Laigter 等工具辅助制作);
- Specular > Texture:高光贴图,控制每个像素的反射强度,通常为灰度图;
- Specular > Color:高光反射的颜色倍率;
- Specular > Shininess:高光指数,值越低反射越亮越弥散,越高越集中(适合潮湿表面)。
启用法线贴图后,方向光看起来会明显变弱——此时应提高 DirectionalLight2D 的 Height 属性(默认 0.0 与表面平行,几乎不出效果),并可小幅提升Energy来接近启用法线贴图前的观感(官方说明)。
性能与工程建议
- max_distance 是最重要的方向光性能开关:场景较大时,将其从默认的
10000.0调低到与摄像机视野匹配的数值,可裁剪视野外物体的阴影投射; - 方向光阴影在整幅视口内计算,若画面中有大量遮挡物,优先使用Shadow > Item Cull Mask与遮挡物 Occluder Light Mask 的位掩码组合,将不必要的投射体排除;
- 对于短生命周期动态特效(子弹、爆炸),可以用加法混合的 Sprite2D替代真正的 2D 光以换取性能(无需进入单独渲染管线,也支持 AnimatedSprite2D 动画化);但要注意其混合公式不够精确、不能投射阴影、忽略法线贴图与高光贴图这三项代价(官方对比);
- 在自定义着色器中区分方向光:
LIGHT_IS_DIRECTIONAL为true且LIGHT_POSITION恒为(0,0,0),据此可编写全局方向光专用的光照响应逻辑。
参考资源
- DirectionalLight2D 类文档(本文主体)
- 2D 光照与阴影完整教程(含点光、阴影设置、法线贴图、像素化技巧)
- Light2D 基类文档(共享属性、BlendMode 与 ShadowFilter 枚举)
- CanvasItem 类文档(light_mask、z_index 等接收光照相关属性)
- CanvasItem 着色器参考(LIGHT_IS_DIRECTIONAL、LIGHT_POSITION 等内置光照变量)
- RenderingServer 文档(CANVAS_LIGHT_MODE_DIRECTIONAL 底层枚举)
- 文档
- 教程
- 游戏开发
【免费下载链接】godot-docs
Godot Engine official documentation
相关推荐
Argo CD 差异计算策略深度解析:Legacy 与 Server-Side Diff 的实现原理与实战配置
Argo CD 差异计算策略深度解析:Legacy 与 Server Side Diff 的实现原理与实战配置 Argo CD 通过对比「期望状态(Git 仓库
示例工程Godot 4 AreaLight3D 面光源完全指南:属性、软阴影、纹理光照与性能优化
Godot 4 AreaLight3D 面光源完全指南:属性、软阴影、纹理光照与性能优化 AreaLight3D 是 Godot 引擎中一种从二维矩形平面发射光
文档教程游戏开发OpenMontage 的 Three.js 光照完全指南:光源类型、阴影系统与环境光照实战
OpenMontage 的 Three.js 光照完全指南:光源类型、阴影系统与环境光照实战 本篇技术指南以 .agents/skills/threejs li
人工智能AI Agent音视频媒体生成工作流自动化
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考