【UnityShader】透明效果和渲染顺序

Unity 中实现透明效果的方法:
  1. 透明度测试;
  2. 透明度混合;
深度缓冲

深度缓冲,根据深度缓存中的值来判断该片元距离摄像机的距离,当渲染一个片元时,需要把它的深度值和已经存在于深度缓冲中的进行比较(如果开启了深度测试),如果它的值距离摄像机更远,说明这个片元不应该被渲染到屏幕上(有物体挡住了它);否则,这个片元应该覆盖掉此时颜色缓冲中的像素值,并把它的深度值更新到深度缓冲中(如果开启了深度写入)。

渲染的顺序

渲染引擎一般都会先对物体进行排序,在渲染。渲染的顺序:

  1. 先渲染所有不透明的物体,并开启它们的深度测试和深度写入。
  2. 把半透明物体按它们距离摄像机的远近进行排序,然后按照从后往前的顺序渲染这些半透明物体,并开启它们的深度测试,但是关闭深度写入。
Unity Shader的渲染顺序

Unity为了解决渲染顺序的问题提供了渲染队列。SubShader中 Queue 标签来决定我们的模型将归于哪个渲染队列,Unity在内部使用一系列整数索引表示每个渲染队列,且索引号越小表示越早被渲染。

名称 序列索引号 描述
Background 1000 这个渲染队列会在任何其他队列之前被渲染,通常使用该队列来渲染那些需要绘制在背景上的物体
Geometry 2000 默认的渲染队列,大多数物体都是用这个队列,不透明物体使用这个队列
AlphaTest 2450 需要透明度测试的物体使用这个队列
Transparent 3000 这个队列中的物体在Geometry和AlpahTest物体渲染后,再按从后往前的属性进行渲染,任何使用透明度混合的物体都应该使用该队列
Overlay 4000 该队列用于实现一些叠加效果。任何需要在最后被选入的物体都应该使用该队列
在关闭深度写入的情况下,渲染顺序变得非常重要

A(黄色)是半透明物体,B(紫色)是不透明物体

  • 如果先渲染B,由于B是不透明物体,不透明物体开启深度测试与深度写入,而此时深度缓冲中没有数据,会把B的值写入深度缓冲和颜色缓冲,然后渲染A,透明物体仍然进行深度测试,发现A距离摄像机更近,会使用A的透明度和颜色缓冲中的B的颜色进行混合,得到半透明效果。
  • 如果先渲染A,由于A是透明物体,开启深度测试但不进行深度写入,把A写入颜色缓冲,但是不写入深度缓冲。然后渲染B,B开启深度测试与深度写入,此时深度缓冲中没有数据,那么会直接用B写入深度缓冲和颜色缓冲,把A的颜色覆盖掉。从视觉上看,B出现在A的前面,这是错误的。

A和B都是半透明物体

  • 先渲染B,把B写入颜色缓冲,但是不写入深度缓冲。然后渲染A,会使用A的透明度和颜色缓冲中的B的颜色进行混合,得到正确半透明效果。
  • 先渲染A,把A写入颜色缓冲,但是不写入深度缓冲。然后渲染B,会使用B的透明度和颜色缓冲中的A的颜色进行混合,这样混合结果会完全反过来,看起来好像B在A的前面,得到错误半透明效果。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章