【Unity Shader入门精要 第8章】透明效果(一)

1. 深度缓冲

之前我们并没有提到过渲染顺序的问题,也就是当场景中有多个物体时,需要先渲染哪个后渲染哪个。实际上,对于不透明物体,先渲染谁后渲染谁都是一样的,都可以得到正确的渲染结果,这是由于深度缓冲(Z-Buffer)的存在。

在实时渲染中,深度缓冲用于解决可见性的问题,它可以决定哪个物体的哪些部分会被渲染在前面,哪些部分会被其他物体挡住。

其基本思想是,根据深度缓冲中的值来判断片元距离摄像机的距离。当渲染一个片元时,将它的深度值与深度缓冲中存在的值进行比较(当开启了深度测试时),如果片元的深度值大于深度缓冲中的值,代表当前片元距离摄像机更远,会被深度缓冲中记录的物体挡住,此时该片元不应该被渲染到屏幕上,于是该片元被丢弃。如果片元的深度值小于深度缓冲中的值,代表当前片元距离摄像机更近,应该被渲染到屏幕上,并且,如果开启了深度写入,则需要将当前片元的深度值写入深度缓冲,更新深度缓冲中的深度值。

因此,对于不透明的两个物体A和B,由于深度缓冲的存在,先渲染A和先渲染B的结果是一样的,并且这个过程要依赖深度缓冲中值的正确性,或者说,要依赖深度写入的正确性。

对于半透物体,通常需要关闭深度写入,这是因为从正确的渲染效果来看,我们可以透过半透物体看到后边被其遮挡的物体,如果先渲染了某个半透物体A,并且该物体开启了深度写入,其深度值就会被写入深度缓冲中,此时再对其后的某个物体B进行渲染时,B会无法通过深度测试,导致物体B被遮挡无法显示出来。

2. 渲染顺序对结果的影响

即使关闭了深度写入,渲染顺序对于半透物体的渲染结果依然有很重要的影响。

2.1 不透明物体与半透物体

在这里插入图片描述
图中A为半透物体,B为不透明物体。

当先渲染B后渲染A时:

  1. B先进行深度测试,此时深度缓冲中没有值
  2. B通过深度测试,将深度值写入深度缓冲
  3. 将B的颜色值写入颜色缓冲
  4. A再进行深度测试,此时深度缓冲中记录的是B的深度值,该值大于A的深度值
  5. A通过深度测试,由于半透物体A关闭了深度写入,不更新深度缓冲,此时深度缓冲中记录的仍为B的深度值
  6. 此时颜色缓冲中的值为B的颜色,将A的颜色值与颜色缓冲中的值进行混合,将结果写入颜色缓冲中
  7. 最终渲染结果正确

当先渲染A后渲染B:

  1. A先进行深度测试,此时深度缓冲中没有值
  2. A通过深度测试,由于半透物体A关闭了深度写入,不更新深度缓冲,此时深度缓冲中仍然没有值
  3. 将A的颜色值与颜色缓冲中的颜色值进行混合,此时颜色缓冲中没有值,于是将A的值写入颜色缓冲
  4. B再进行深度测试,此时深度缓冲中仍然没有值
  5. B通过深度测试,将B的深度写入深度缓冲
  6. B为不透明物体,B的颜色值会直接覆盖颜色缓冲中的值,于是颜色缓冲中的值变为B的颜色值
  7. 最终渲染结果变成B遮挡A,渲染错误

2.2 半透物体与半透物体

在这里插入图片描述
同理,对于两个均为半透的物体A和B:

  • 当先渲染B后渲染A时,B的颜色值会先写入颜色缓冲,最终为用A的颜色值与B的颜色值进行混合,效果为透过A看到B,渲染结果正确。
  • 当先渲染A后渲染B时,A的颜色值会先写入颜色缓冲,最终为用B的颜色值与A的颜色值进行混合,效果为透过B看到A,渲染结果错误。

基于以上两点,引擎在渲染时通常会:

  • 将物体进行排序
  • 先渲染不透明物体,所有不透明物体开启深度测试和深度写入,从近到远进行渲染
  • 后渲染半透明物体,开启深度测试,并关闭深度写入,从远到近进行渲染

3. 渲染队列

Unity提供了渲染队列(Render Queue)这一解决方案。渲染队列决定了物体渲染的先后顺序,我们在SubShader的 Tags{} 中设置的 “Queue” 标签就是为物体指定其所属的渲染队列。

Unity定义了5个渲染队列:

Queue队列索引描述
Background1000最先进行渲染的队列,可以用来渲染那些完全作为背景的物体(比如只会远远做展示用,不会参与到正常的游戏交互中的物体)
Geometry2000第二个进行渲染的队列,不透明物体队列,由于游戏中大部分物体都为正常的不透明物体,因此该队列也是默认的渲染队列
AlphaTest2500需要进行透明度测试的物体的渲染队列,将透明度测试的物体单独拆分成一个渲染队列,可以提高渲染效率
Transparent3000半透物体的渲染队列,也就是需要进行透明度混合的队列
Overlay4000最后一个进行渲染的队列,用于实现一些叠加的表现效果
  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值