Unity 透明物体显示问题

总结一下 Shader 开启透明渲染后的一些显示问题的解决方案,考虑 ZWrite,ZTest,Queue 这三个属性的设置问题。

首先需要记住的是:

  • 对于不透明物体,渲染的正确顺序是从前往后(距离摄像机的距离由近到远排序);
  • 对于半透明物体,渲染的顺序是从后往前。
    这样才能实现正确的渲染输出。

注意:Alpha Test,Alpha to Coverage 不在讨论之列。这里涉及到的是使用 Alpha Blend 的物体。

其次是,Unity Shader中需要注意的三个属性。

  • ZWrite:是否开启深度缓存,默认为 On。
  • ZTest:深度测试的模式,默认为 LEqual(小于等于)。
  • Queue:渲染队列,默认为 Geometry。

常规来说:

  • 对于不透明物体,默认的设置为 ZWrite On,ZTest LEqual,Queue=“Geometry”。
  • 对于半透明物体,默认的设置为 ZWrite Off,ZTest LEqual,Queue=“Transparent”。
    对于半透明物体,这样的设置在一般的情况下是没有问题的,但是在某些情况下会出现问题。

先解释一下相关的概念:
Queue:最好理解,也就是物体的在渲染队列中的顺序。
ZWrite On:会开启深度缓存和深度测试,即在绘制物体表面上的一个像素时,会对像素的深度值和深度缓存中对应点的值进行比较,如果该像素的深度值小于或等于(ZTest LEqual)深度缓存中的值,就用该像素的颜色和深度替换掉原有的像素。
ZWrite 开启之后,图形渲染将按照深度测试的结果来进行,不会因为渲染顺序不一致而导致前面的物体被后面的物体覆盖的问题。
半透明物体关闭了 ZWrite,这时候渲染队列对于正确的显示就十分重要了。必须严格的按照后面的先渲染,前面的后渲染的顺序,否则会出现不正确的遮挡关系。

那么回到上面的问题,什么情况下半透明物体的默认设置表现不正确?
举个简单的例子,十字交叉的面片草渲染,通常情况下会使用 Alpha Test 的 Shader。但是 Alpha Test 并不支持抗锯齿,所以有时候考虑到锯齿问题 OR 性能问题使用 Alpha Blend。
如果使用默认设置,那么会观察到交叉的重叠效果不正确。这是因为 ZWrite Off,两个面片按照先后顺序分别渲染,导致错误的重叠效果。
相反,如果开启了 ZWrite,则会发现,由于开启了深度缓存测试,前面的透明像素成功的替换掉后面的不透明像素。导致前面面片的透明像素没有与后面的不透明像素混合,而是直接显示了背景像素。
对于 UI 之上有模型使用半透明材质,导致与场景进行半透明混合而不是与 UI 进行半透明混合的解决方案则是:使用脚本调整模型的 Sorting Order,使其略大于 UI 组件 Canvas 的 Sorting Order 即可。

除了 Shader 层面的解决方式,半透明还可以通过修改顶点 ID 的方式来进行渲染顺序的修改,这里的具体方式不详细说明。

本文来自:https://blog.csdn.net/wotingdaonile/article/details/109355594