2D 灯光和阴影
前言
灯与影 演示项目解释了2D灯光的工作原理. 本节首先简要介绍了最终demo所使用的资源, 然后介绍了如何逐步实现类似demo的场景. 官方演示存储库 中找到. 我建议您在开始之前下载它. 或者, 也可以在项目管理器中下载. 在启动Godot时在顶部栏中选择 “模板(Templates)” 选项卡并搜索 “2D Lights and Shadows Demo”.
场景布置
对于这个演示, 我们使用四种纹理: 两种用于灯光, 一种用于那些会产生阴影的物品, 一种用于背景. 如果想单独下载它们, 我在这里列出了所有链接. bg.png ). 你不一定需要背景, 但我们还是在演示中用了一个. caster.png ) . 对跳跃游戏, 它可能是墙或任何其他投射阴影的物体. light.png ) . 如果单击该链接, 您会注意到它有多大. 用于灯光的图像应覆盖您希望灯光覆盖的区域. 此图像为1024x1024像素, 因此您应该使用它来覆盖游戏中的1024x1024像素. spot.png ) . 该演示使用灯泡来显示灯光的位置, 使用较大的灯光图片来显示灯光对场景其余部分的影响.
节点
该演示使用了四个不同类型的节点:
- CanvasModulate
- Sprite
- Light2D
- LightOccluder2D
CanvasModulate 用于使场景变暗.
Sprites 用于显示灯泡, 背景和产生阴影的物体的纹理.
Light2Ds 用于点亮场景. 光通常的工作方式是在场景的其余部分添加选定的纹理以模拟光照. 但它可以以其他方式使用, 例如屏蔽部分场景.
LightOccluder2Ds 用于告诉着色器, 场景的哪些部分投射阴影. 阴影仅出现在 Light2D 所覆盖的区域, 它们的方向基于 Light 的中心.
灯光
Lights 覆盖各自纹理的整个范围. 它们使用Additive Blending将其纹理颜色添加到场景中. Lights 有四个模式:add,sub,mix, 和mask.Add将光纹理的颜色添加到场景中. 它会照亮灯光下的区域.Sub从场景中减去光的颜色. 它使灯光下的区域变暗.Mix混合了灯光的颜色和底层场景. 产生的亮度介于灯光颜色和下方颜色之间.Mask用于遮盖灯光覆盖的区域. 根据光的颜色隐藏或显示遮盖区域. Light 本身(这是灯光的效果), 和 Sprite 灯泡(一个显示光源位置的图片). 子节点 Sprite 不是让 Light 工作的必要条件.阴影
Light 与 LightOccluder2D 的范围相交来制作的. Light 并在Shadows部分下面选中启用. Sprite 来制作 “投射影子的物体”, 但实际上您只需要几个 LightOccluder2Ds . LightOccluder2D 本身看起来像一个黑点, 在这个演示中 Sprite 只是一个黑色方块.渐进式教程
既然我们已经介绍了需用到的节点的基础知识, 那就可以开始逐步实现demo中的场景了. Sprite 并将其纹理设置为 背景图片 . 在你的游戏中这可以是你选择的任何背景. 对于我们这种风格的阴影, 这张图最可能是地板的纹理. Light2D’s 并将它们的纹理设置为 light image . 你可以在上面的栏目中更改颜色. 默认情况下, 阴影关闭并且mode设置为add. 这意味着每个灯光都会将自己的颜色添加到下面的任何颜色中. Light 节点添加一个 Sprite 子节点, 并将 Sprite’s 纹理设置为 blob image . 他们都应该保持在 Light 节点的中心.blob是灯本身的图像, 而 Light 显示灯光对场景的影响. LightOccluder2D’s 会将光的位置视为 Light 节点的中心, 这就是为什么我们希望blob位于父节点 Light 的中心. 注解 动画功能介绍 。 CanvasModulate 的原因. CanvasModulate 将整个视区乘以特定颜色. CanvasModulate 并将其颜色设置为rgb(70, 70, 70). 这将使场景足够暗, 以清楚地看到灯光的效果. 现在, 我们来添加会投射阴影的物体. Node 来组织投射阴影的物体. 在场景中添加 Node2D . 它会被用来把所有投射阴影的物体变成一个大组. 这样我们就可以同时显示和隐藏它们. LightOccluder2D 子节点的 Sprite 组成. 在演示中, Sprite 的纹理设置为 caster image . 子节点 LightOccluder2D 是所有神奇的事情发生的地方. 在游戏中 Sprite 可能不仅仅是一个黑色的方块; 它可以是任何可以投射阴影的物体的图片: 一面墙, 一个宝箱或其他任何东西. LightOccluder2Ds 告诉游戏Occluder(遮光物)是什么形状.Occluder是一个多边形的容器 OccluderPolygon2D . 对于这个演示, 由于我们的墙是正方形, 我们将Polygon设置为正方形. 其他设置保持为默认.Closed可以是on或off。 闭合的多边形遮挡来自所有方向的光线。 开放多边形仅遮挡来自一个方向的光线。Cull Mode让您选择剔除的方向. 默认值为 “已禁用”, 这意味着无论灯光在哪一侧, 遮挡物都会投射阴影. 另外两个设置Clockwise和Counter-Clockwise指的是多边形顶点的弯曲顺序. 弯曲顺序用于确定光线的哪一侧在多边形内. 只有朝外的光线才投下阴影. LightOccluder2D 的Closed设置为off的 OccluderPolygon2D . 这是为了可以看到多边形的轮廓: 注解Cull Mode设置为Disabled. 全部三条轮廓线都投下阴影. 注解Cull Mode设置为Clockwise. 只有顶部和右侧线条投射阴影. 注解Cull Mode设置为Counter-Clockwise. 只有底部的轮廓线投下阴影. 如果Closed设置为on, 左边会有一条额外的垂直轮廓线也会投射阴影. LightOccluder2Ds 时, 阴影仍不会出现. 你需要回到 Light2Ds 并在Shadow部分下设置Enable为on. 这将打开带有硬边缘的阴影, 如下图所示.filter,filter smooth和gradient length. Godot支持 Percentage Closer Filtering (PCF) , 它在像素周围提取阴影贴图的多个样本, 并模糊它们以创建平滑的阴影效果. 样本数越多, 阴影看起来越平滑但运行速度越慢. 这就是为什么Godot默认提供3-13个样本并让你可以自己选择用几个样本. 该演示使用PCF7. 注解gradient length设置为1.3,filter smooth设置成11.1,filter设置为PCF7. 注解filter设置为PCF13. 注意这里阴影变宽了, 这是因为样本之间的距离是依赖于变量filter smooth的.filter smooth变量. 这决定了样品之间的距离. 如果您想让柔软区域延伸很远, 您可以增加filter smooth的大小. 然而, 在低样品和大过滤平滑的情况下, 你会看到样本之间形成的线条. 注解filter smooth设置为30. Light 节点使用不同的filter smooth值. 玩玩它, 看看你喜欢什么样的. 注解filter smooth设置为0.gradient length. 对于一些平滑阴影, 最好不要在对象上立即开始阴影, 因为这会产生硬边. Gradient length(渐变长度)变量让阴影刚开始的时候平滑渐变, 以减少硬边缘的影响. 注解gradient length设置为0. 注解gradient length设置为10.filter值越高, 阴影的计算成本也越高就行了.
