Version: Unity 6.0 (6000.0)
语言 : 中文
阴影级联的实现详细信息
反射

阴影故障排除

减少阴影闪烁

如果阴影距离摄像机较远,可能会出现闪烁。请参阅了解视锥体以了解更多信息。

如果阴影比世界空间原点更接近摄像机,请启用摄像机相对剔除。Unity 使用摄像机作为阴影计算的相对位置,而不是世界空间原点,这样可以减少闪烁。

要启用摄像机相对剔除,请执行以下步骤:

  1. 转到项目设置 (Project Settings) > 图形 (Graphics) > 剔除设置 (Culling Settings) > 摄像机相对剔除 (Camera-Relative Culling)
  2. 启用阴影 (Shadows)

阴影性能

渲染实时阴影对性能有很大的影响。任何可能投射阴影的游戏对象都必须首先渲染到阴影贴图中,然后用该贴图渲染可能接受阴影的对象。

柔和阴影比生硬阴影具有更大的渲染开销,但这仅影响 GPU,不会导致额外的 CPU 工作。

如果渲染复杂几何体的实时阴影成本太高,请考虑使用低__ LOD__见__细节级别__。
See in Glossary
网格甚至图元来投射阴影。

如果这太耗费资源,可以使用应用于角色下方简单网格或四边形的模糊纹理来伪造阴影,也可以使用自定义着色器来创建模糊阴影。

阴影暗斑

直接获得光照的表面有时看起来部分处于阴影中。之所以出现这种情况,是因为应该精确位于阴影贴图中指定距离处的像素有时被计算为更远距离(这是对阴影贴图使用阴影过滤或低分辨率图像的结果)。造成的结果是阴影中出现任意像素图案(这些像素其实应当获得光照),带来称为“阴影暗斑”(shadow acne) 的视觉效果。

阴影暗斑的出现形式是虚假的自我阴影瑕疵
阴影暗斑的出现形式是虚假的自我阴影瑕疵

调整阴影偏差设置

通过调整阴影偏差 (shadow bias) 值,可以减少或消除阴影暗斑、阴影分离(也称为彼得平移)、漏光和自我阴影等阴影瑕疵。

在内置渲染管线中,启用阴影后,可以通过光源检视面板 (Light Inspector) 窗口中的__偏差 (Bias)__ 和__法线偏差 (Normal Bias)__ 属性来设置这些值。

不要将 Bias 值设置得太高,因为游戏对象附近的阴影周围区域有时会被错误地照亮。这会导致阴影脱离游戏对象,使游戏对象看起来好像飘在地面上方。

高 Bias 值使阴影与游戏对象看起来是“脱离”的
Bias 值使阴影与游戏对象看起来是“脱离”的

同样,将 Normal Bias 值设置得太高会使阴影对于游戏对象来说太窄:

高 Normal Bias 值使阴影形状太窄
Normal Bias 值使阴影形状太窄

在某些情况下,__Normal Bias__ 会导致称为“光渗”(light bleeding) 的不良效果,这种情况下,光线从附近的几何体渗透到应该产生阴影的区域。一种可能的解决方案是打开游戏对象的网格渲染器 (Mesh Renderer),并将__投射阴影 (Cast Shadows)__ 属性更改为__双面 (Two Sided)__。这种做法有时会有所帮助,但可能会占用更多资源,并在渲染场景时增加性能开销。

光源的 Bias 值可能需要适当调整以免产生不想要的效果。通常用眼睛衡量正确值会更简单,而不是试图计算该值。

一个较低的阴影近平面偏移 (Shadow near plane offset value) 值在阴影中产生孔状外观
一个较低的阴影近平面偏移 (Shadow near plane offset value) 值在阴影中产生孔状外观
矫正阴影
矫正阴影

阴影平坠

为了进一步防止阴影暗斑,我们采用一种称为__阴影平坠 (Shadow pancaking) __的技术。该技术旨在减少沿光照方向渲染阴影贴图时使用的光照空间范围。这可以提高阴影贴图的精度,减少阴影暗斑。

显示阴影平坠原理的图形
显示阴影平坠原理的图形

在上图中:

  • 浅蓝圆圈代表阴影投射物
  • 深蓝矩形代表原始光照空间
  • 绿线代表优化的近平面(排除了在视锥体中不可见的所有阴影投射物)

将这些阴影投射物钳制在优化空间的近裁剪面(在顶点着色器中)。请注意,虽然这通常很有效,但对于穿过近裁剪面的大型三角形,这会带来瑕疵:

大三角形问题
大三角形问题

在此情况下,只有蓝色三角形的一个顶点位于近裁剪面背后并被钳制到此处。但是,这会改变三角形的形状,并可能产生不正确的阴影。

您可以从质量 (Quality) 窗口中调整__阴影近平面偏移 (Shadow Near Plane Offset)__ 属性以避免发生此问题。这将拉回近裁剪面。但是,如果将此值设置得非常高,最终会引入阴影暗斑,因为它会提高阴影贴图需要在光照方向上覆盖的范围。或者,您也可以细分有问题的阴影投射三角形。

阴影不显示

如果您发现一个或多个对象未投射阴影,则应检查以下几点:

  • 可在质量 (Quality) 窗口中彻底禁用实时阴影。确保启用了正确的质量级别并为该设置启用了阴影。

  • 场景中的所有网格渲染器 (Mesh Renderers) 都必须正确设置相应的_接受阴影 (Receive Shadows)_ 和_投射阴影 (Cast Shadows)_ 属性。默认情况下两者都已启用,但请检查确保未意外禁用它们。

  • 只有不透明对象才投射和接受阴影,因此使用内置透明着色器或粒子着色器的对象既不会投射也不会接受阴影。通常,您可以使用透明镂空 (Transparent Cutout) 着色器代替具有“间隙”的对象,例如栅栏、植被等。自定义着色器必须采用像素光照并使用几何渲染队列 (Geometry render queue)

  • 使用__顶点光照 (VertexLit)__ 着色器的对象不能接受阴影,但可投射阴影。

  • 如果游戏对象的材质具有“无光照”类型的着色器,Unity 无法为这些游戏对象计算阴影。只有当材质的着色器支持光照时,Unity 才能为材质计算阴影。

  • 在内置渲染管线中,使用前向渲染路径,有些着色器只允许最亮的方向光投射阴影(这种情况尤其发生在 Unity 4.x 版本的内置着色器中)。如果想使用多个阴影投射光,则应改用延迟着色 (Deferred Shading) 渲染路径。您可以使用 fullforwardshadows 表面着色器指令启用您自己的着色器以支持“全阴影”。

其他资源

阴影级联的实现详细信息
反射