了解如何使用 Unity 2022 LTS 中的 通用渲染管线 (URP) 创建 Happy Harvest 演示中的灯光和阴影。
Happy Harvest 是一款 2D 自上而下的农业模拟游戏。电子书《 面向艺术家的 2D 游戏艺术、动画和灯光》详细介绍了本文中的技术以及其他更多技术。
阅读本系列的其他文章,了解如何复制 《Happy Harvest》中的效果和视觉效果:
- 如何在 Unity 2022 LTS 中为 2D 角色制作动画
- 如何利用 2D 瓷砖地图创建艺术和游戏玩法
- 使用 VFX Graph 和 Shader Graph 实现 2D 特效(即将推出)
立即从 Unity Asset Store下载Happy Harvest。
2D 灯光 是带有 Light 2D 组件的游戏对象。它们与 Sprite Renderer、Sprite Shape Renderer和 Tilemap Renderer一起工作。他们还使用排序层,并且每个灯光能够影响一个或多个层。您可以在目标排序图层下拉列表中选择将受影响的图层。
2D 光源有 四种不同类型 :
自由形式: 它们可以形成像 n 边多边形。您可以在非有机或风格化的环境中使用这种类型的光。对于有效照亮大部分环境(例如熔岩池)、模拟光形(例如从天花板开口射出的圣光)或符合光线投射的窗户形状而言,它都是不错的选择。
雪碧: 这种形状使您可以使用任何精灵作为光的纹理。如果您想要一种其他灯光类型无法实现的特殊形状,那么这会非常有用。可能的纹理示例包括镜头光晕、眩光、光饼干、光形投影(例如迪斯科球灯)或在墙上投射星星的灯。
点: 该光可以是圆形或扇形。它适用于聚光灯,或用火炬、蜡烛、车灯、手电筒、体积光等照亮特定点。
全球的: 这种光没有形状,而是照亮目标排序层上的所有物体。每个混合样式 (光线和精灵之间的交互方式) 和每个排序层只能使用一个全局光。首先使用它来添加基础环境光。
每种灯光类型都有以下 设置 :
混合风格: 混合风格决定了特定光线与场景中的精灵交互的方式。场景中的所有灯光必须具有四种可用的混合样式或模式之一:加法、调制、减法和自定义。每种模式控制精灵被光照亮的方式。
轻顺序和重叠操作:这些使您能够控制当多盏灯影响相同像素时发生的情况。
阴影:当你启用此选项时,具有阴影投射器的游戏对象将从该光源投射阴影。
体积:这使您可以控制投射阴影的亮度和暗度衰减。
法线贴图:启用后,精灵上的法线贴图信息将用于根据像素方向计算光量。
您可以通过 “Sprite Editor”>“Secondary Textures”为 2D 项目中的每个精灵资产分配可选的 辅助纹理 。二次纹理有两种类型:法线贴图和蒙版贴图。在 《Happy Harvest》中, 从角色到图块地图和道具的所有元素都使用了法线贴图和遮罩贴图,从而可以创建高质量的实时光照和阴影效果。
法线贴图
《Happy Harvest》 中使用了灯光和法线贴图来营造体积感,让演示版本具有独特的外观和感觉。您可以将法线贴图与聚光灯、点灯和自由形式灯光一起使用。
法线贴图的制作方式可以成就或破坏精灵的 3D 幻觉。法线贴图中的每个像素都存储了有关主纹理角度的数据。红、绿、蓝 (RGB) 通道存储 X、Y 和 Z 坐标的角度数据。每个使用法线贴图的光源都有一个方向,带有法线贴图的纹理上的像素会根据这个方向以及像素的方向进行着色。这模仿了光在现实生活中的工作方式——如果像素朝向光的方向,它将被点亮,如果背对光,它将不会接收任何光。
遮罩贴图
面具控制灯光对精灵的影响。有四个通道可供选择作为掩码通道:红色、蓝色、绿色和 Alpha。遮罩最大值表示全光,最小值表示无光。
遮罩图可让您为视觉效果添加细节,从而帮助您完善游戏。它们也被 2D 灯光混合样式所使用。
混合样式采用给定像素处的光值,并将该值乘以同一像素处的蒙版。然后根据选择的混合样式,将得到的蒙版光值与该像素的颜色相加、相减或相乘。
用于边缘光的遮罩贴图
为了便于阅读,角色在移动时通常会在其轮廓周围有一圈边缘光。边缘照明是一种用于突出人物轮廓的效果。它模拟来自物体后面的光和光散射的自然特性。这也称为菲涅尔效应。在横向卷轴 2D 游戏中,地面和背景有助于放大角色的轮廓。在自上而下的游戏中,轮廓更多地嵌入环境中,因此需要清晰的边缘光来区分其形状。
《Happy Harvest》 中的主角和道具包含用于边缘光效果的遮罩贴图。对于主角,光亮区域绘制在R通道中,而道具则使用G通道。这样做的原因是为了以不同于普通道具的方式照亮角色的轮廓(使用不同的灯光组,这些灯光仅影响混合样式通道中的 R 通道)。
请记住,法线贴图应在 Unity 中作为法线贴图 (Normal Map) 导入,而蒙版贴图应作为纹理类型 默认 (Default) 导入。这样可以确保在使用 Sprite Atlas打包纹理时,每个纹理仅打包在其正确的图集中,以避免重复。
在已经绘制了阴影的精灵上,2D 光照看起来不太好。您最终还会做双倍的工作量,因为您将在法线贴图中“绘制”灯光。如果您绘制无方向性的阴影,只要您避免任何方向性的光线(例如阳光),您的精灵就会看起来更好。
为每个精灵、图块或精灵形状制作法线贴图可能非常耗时。考虑结合不同的生成技术,在真正重要的手动工作上投入时间,并实现背景道具的自动化流程。请注意,如果您从 3D 建模软件(如 Blender 或 3ds Max)生成 2D 精灵,则该纹理应该很容易生成。
让我们看一些例子:
- 变形现有的法线贴图以使其适应手头的 2D 对象。例如,戒指或宝石可以使用图像中的示例法线贴图。
- 使用法线贴图生成器工具,例如 SpriteIlluminator、NormalPainter、Krita 的 Tangent Normal Brush 或 Laigter。
- 生成器应用程序不会考虑精灵的角度,因此请避免在整个精灵上使用它们。他们也无法辨认这些物体。相反,他们根据精灵颜色来估计形状,或者通过添加类似于图像编辑应用程序中的斜面或浮雕的通用过滤器来估计形状。
- 他们无法识别脸部的角度,但会试图猜测哪里应该改变角度。尽管存在此限制,它们仍然可用于生成斜面精灵部分的法线贴图,如链条、电缆或龙尾,以及砖块、石头、木头等的表面法线。
- Unity 提供了一种从灰度高度图生成法线贴图的方法。这是一种纹理,其中黑色代表最小表面高度,白色代表最大高度。将图像导入为法线贴图并选中 “从灰度创建” 选项。此技术非常方便,无需离开引擎即可快速生成法线贴图。
- 从样本图像中取样颜色。首先,获取一个法线贴图调色板(您可以在网上找到一些),以便您可以对用于表示表面角度的颜色进行采样。您只需将调色板复制到您最喜欢的绘画应用程序中,然后使用颜色选择器选择要在法线贴图上绘制的颜色。
- 角度颜色不需要 100% 准确。然而,一定要确保精灵的整体形状可信。如果使用在上下文中没有意义的角颜色,则形状在点亮时将会崩溃。
- 绘制法线贴图最初可能比较棘手,因为它需要良好的空间想象力。尝试从一些简单的东西开始,例如头部的基准平面。这里使用的示例是一个具有低多边形外观的简化人体头部模型。
- 绘制法线贴图时,尝试想象精灵的各个部分的基本 3D 形状,然后想象每个部分的角度。如果您知道角度,您就会知道从调色板精灵的哪个部分采样颜色。
- 此处显示的示例图像是在平面上绘制的,但使用更软的画笔绘画时过程类似。您可以混合硬边缘以获得更自然的外观。
- 从三个不同的角度手动绘制物体上的灯光和阴影(每个 RGB 通道一个),并组合颜色通道。来自顶部的光线应该使用 G 通道,来自右侧的光线应该使用 R 通道,来自中心的光线应该使用 B 通道。请注意,B 通道是可选的,因此您可以减少工作量,同时仍然获得可信的外观。
全局光影响整个场景,从而轻松改变气氛。它们在演示(称为环境光的游戏对象)中用于应用一般色调并避免暗区。
每个新场景都会默认添加一个 2D 全局光。它们不需要是白色,也不需要改变颜色、强度或受影响的图层来为场景应用统一的色调。
场景中应该只有一个全局光。通过操纵其参数,您可以轻松模拟不同的环境条件,例如夜间,通过降低强度并对场景应用紫色色调。在演示中,颜色会根据一天中的时间而变化,这是由 DayCycleHandler 脚本管理的效果,稍后会进行解释。
《Happy Harvest》 使用大型聚光灯作为主光。它附在相机上,因此始终位于屏幕上,并随着模拟太阳运动的脚本旋转。
2D 场景没有像 3D 场景那样的方向光。但是,您可以使用从 X 和 Y 位置照亮精灵的光源。这使得你能够创建像太阳随着一天的推移而移动的效果,这在自上而下和模拟游戏中非常重要。还值得注意的是,如果您针对低端平台,使用大灯需要付出代价。请查看本文末尾的性能提示部分。
在演示中,查找名为 LightsRotator的子游戏对象,它带有四个灯:
小夜灯:模拟月光方向
日光:模拟阳光方向(与夜灯的位置相反)
夜光边缘: 类似于 NightLight 月亮方向灯,但仅适用于角色和道具边缘灯
日光边缘: 类似于 DayLight 阳光方向光,但仅适用于角色和道具边缘光
控制这些灯移动的脚本也控制全天的颜色变化。渐变会在特定时间为每盏灯选择颜色。您可以在附加到 DayCycleHandlerGameObject 的 DayCycleHandler 脚本中看到这些渐变。
《Happy Harvest》 中随处都使用灯光和法线贴图来营造体积感。您可以将法线贴图与聚光灯、点灯和自由形式灯光一起使用。请记住,您需要在灯光对象中启用法线贴图才能在精灵中使用它们。有两种质量设置可供选择:快速且准确。
您可以看到当启用法线贴图时灌木丛如何根据光线位置模拟体积。路灯和其他道具照亮了感兴趣的区域并帮助玩家找到路径。
通过将 Shadow Caster 2D 组件附加到任何精灵或动画角色,2D 对象可以投射无限的阴影。
当光照区域有限或者有强烈而集中的光源(如路灯或壁炉)时,无限阴影会产生很好的效果。
请记住在灯光对象中启用法线贴图,以便在精灵中使用该纹理,并激活阴影选项。
此外,角色的轮廓不应该投射阴影,因为对于自上而下的游戏来说这看起来不真实。Shadow Caster 2D 组件仅影响脚部,因为它附着在角色 GameObject 内的脚骨骼上(Visual > Prefab_character_base > root_bone > … > foot_r_bone 和 foot_l_bone)。
在自上而下的游戏中,来自阳光的无尽阴影投射看起来很奇怪。《Happy Harvest》 采用的一种技术是在树木和灌木丛上使用斑点阴影,并根据一天中的时间旋转和拉伸。结果是阴影更加柔和,更好地符合艺术指导。
脚本中的 UpdateShadow 函数旋转这个阴影。与其他斑点阴影一样,这是一个基于精灵的光。您可以通过检查父 GameObject 内名为 Trees的任何 GameObject 来检查这一点。在名为 RotationHandle的游戏对象 (GameObject) 中查找名为 ShadowLong 的 子游戏对象 (GameObject)。Shadow Instance 脚本将 RotationHandle 添加到 UpdateShadow 脚本。然后,该脚本充当管理器,使用函数来更新阴影的大小和旋转。
斑点阴影非常适合较小或平坦的物体,例如广告牌或树木。然而,具有深度和清晰形状的大型建筑物需要投射精确的阴影。在 《Happy Harvest》中,自由形式的灯光创造了这些阴影。它们模仿建筑物在地面上产生的投影,这是一个必要的近似值,因为二维中没有深度信息。
定义清晰的阴影的挑战在于如何让它们与昼夜循环相协调。为了使阴影对太阳的不同位置做出反应, 光插值器 脚本将自由形式光的矢量点置于不同的参考阴影之间。
在演示的层次结构中,找到名为 Light_2D_Warehouse的游戏对象。它上面连接着四个自由形式的灯,模仿太阳在建筑物的上空、下空以及左右两侧投射出的阴影。该脚本创建平滑插值,使用 API 移动不同的矢量点。
首先创建顶部阴影,然后进行修改以创建其他阴影。重要的是确保每个阴影具有相同数量的点,并且在创建每个阴影时考虑这些点之间的过渡。
一旦创建了阴影,它们就会被添加到 Light Interpolator 组件脚本中,并带有一个 Normalized 参数,该参数指示一天中每个阴影的时间权重。脚本中的 预览时间 功能使您能够预先看到它们在编辑器中的外观。
DayCycleHandler 管理器是协调昼夜循环的脚本。让我们仔细看看它的一些功能。
名为 Lights Root 的游戏对象是包含用于模拟阳光和月光的聚光灯的父对象。它由 DayCycleHandler 脚本旋转。
夜光、环境光和边缘光的命名是为了传达它们的用途。渐变是每盏灯显示的色调,以营造适当的氛围。
对于 “一天持续时间(秒)” 变量,您可以定义白天的持续时间(秒数)并设置开始时间。在 测试时间中,您可以预览游戏在编辑器中不同时间的样子。
控制有限阴影效果的参数是 阴影角度 和 阴影长度。在每个字段中,动画曲线指示全天阴影的顺时针角度。长度参数定义给定时刻阴影的长度。例如,当太阳落山时,您可能需要较长的阴影,而当太阳垂直照射场景时,您可能需要较短的阴影。请注意,您可能需要移动测试时间滑块来刷新阴影角度和阴影长度设置。
使用 2D 照明时的一个常见问题,尤其是在移动平台上,是在游戏中添加灯光的成本。建议在支持的最低规格下在实际目标硬件上进行测试。您还可以应用一些常规优化来提高性能:
保持填充率尽可能低。一盏大灯的性能可能比几盏小灯的性能更差。
当可批处理时,灯光表现最佳。跨连续图层的具有相同照明设置的灯光都可以一起绘制。
保持渲染比例尽可能低。渲染比例调整渲染光照时使用的纹理大小,纹理大小越低,意味着需要渲染的像素越少。
尽量减少屏幕上投射阴影的灯光数量。切换到绘制阴影时,性能成本会大幅增加。
尽量减少屏幕上不同混合风格的数量。切换绘制混合样式时会产生很大的成本。
调整最大光照渲染纹理和最大阴影渲染的数量以满足项目需求。数字越大,性能越好(直到一定限度),但也会增加所需的内存。您需要找到正确的号码。
如果还没有,请务必下载这些涵盖 Unity 中的 2D 游戏开发和渲染(3D 和 2D)的高级电子书:
另外,请查看我们的其他 2D 演示 《The Lost Crypt》 和 《Dragon Crashers》。
您可以在 Unity 最佳实践中心找到更多针对高级程序员、艺术家、技术艺术家和设计师的资源。