欢迎大家继续学习 Unity 游戏编程进阶。
本节我们主要介绍 Unity 中与阴影有关的知识要点。
在 Unity 中,物体可以
遮挡光源发出的光线,在自身或者周围物体的表面产生阴影。
阴影能够营造空间的深度和层次感,使游戏场景更加逼真。
下面我们讲解 Unity 中与阴影渲染相关的内容。
首先是阴影的产生原理。
光线从光源出发,沿直线进行传播。
在传播过程中,光线遇到场景中的物体,在物体表面发生反射或者折射现象, 照亮了物体表面。
反射或折射发生后,如果光线改变传播方向, 无法照射后续的物体,被照射物体就在后续物体区域产生了阴影。
我们换一种方式来理解阴影,假设有一台相机,
它和光源具有相同的位置,面向场景,此时相机观察到的场景区域
就是被照亮的区域;反之,如果被相机观察到的区域就会出现阴影。
Unity 也利用这种方法来渲染阴影。
它首先在光源位置放了一台临时摄像机,渲染一遍场景,
渲染过程只计算当前视角下可见的物体的深度信息, 并以 shadowMap 的方法保存下来。
shadowMap 记录了场景中哪些物体离光源最近, 能够被光线直接照射到。
场景中不在 shadowMap 图像上的部分都是阴影区域。
最后当场景摄像机正式绘制场景时,参考这张 shadowMap 绘制出阴影。
下面我们介绍在 Unity 中开启阴影效果的方法。
首先,选中需要产生阴影的光源对象。
在它的 Light 组件中设置其 Shadow Type 属性为 Hard Shadows 或者 Soft Shadows,
其中 Hard Shadows 产生硬阴影,阴影的边缘十分锐利; Soft Shadows 产生软阴影,阴影的边缘柔和。
Shadow Type 标签下的属性中,Strength 表示阴影的强度,也就是阴影有多黑。
Resolution 表示之前提到的 ShadowMap 的分辨率。
Shadow Near Plan 表示阴影的最小距离, 任何以光源的最小距离小于这个值的物体表面上都不会产生阴影。
其次,我们需要 设置光源的 Render Mode 属性为 Auto 或者 Important。
任何设置为 Not Important 的光源 都无法产生阴影。
关于 Render Mode 属性的值我们在上一节介绍过。
接着,对于产生阴影的对象, 比如本页
PPT 左下角场景的球体,我们设置其 Mesh Renderer 组件的 Cast Shadows 为 On。
最后对于接收阴影的物体,比如场景中的地面, 我们在
Mesh Renderer 组件中,勾选 Receive Shadows 属性。
通常情况下,经过以上设置,我们就可以在场景中看到阴影。
有时,即使我们正确地设置了光源和游戏对象的相关属性, 也依然无法看到阴影。
这时,我们罗列了造成该问题的一些原因供大家检查。
第一,你的显卡可能过于古老,不支持阴影的渲染; 第二,你可能在项目质量设置中关闭了阴影;
第三,光源的 Rendering Mode 设置为 Auto, 有些情况下 Auto 光源会被
Unity 自动判定为非 Important 光源, 或者无法产生阴影。
如果你认为这个光源的阴影效果很重要, 你可以把它强制改为 Important
光源;第四,Unity 中的透明物体是无法产生阴影的; 第五,接收阴影的物体使用了
Standard Shader,并且 Rendering Mode 改为 Transparent,
这种情况下无法生成阴影;最后,如果接收阴影的 物体的材质使用了其它逐顶点的着色器,无法产生阴影。
这个列表中的部分内容还没有讲解,大家可以自行查阅相关的资料, 也可以在后续课程学习中复习本页 PPT 的内容。
日常开发过程中
开启了阴影之后,我们会发现物体表面上出现一些奇怪的条纹或者斑点, 这是由于 Unity 在计算阴影时,ShadowMap 的精度不足造成的。
我们把这种错误的条纹称为马赫带。
我们在光源对象 Light 组件中,稍微调高 Bias 属性的值,可以消除马赫带。
这里需要注意,如果 Bias 值设置过大,会导致阴影面积减小,或者消失。
下一节我们将 介绍
Unity 中全局光照的基本概念。