【Unity Shaders】Alpha Test和Alpha Blending

写在前面关于alpha的问题一直是个比较容易摸不清头脑的事情,尤其是涉及到半透明问题的时候,总是不知道为什么A就遮挡了B,而B明明在A前面。这篇文章就总结一下我现在的认识~Alpha Test和Alpha Blending是两种处理透明的方法。Alpha Test采用一种很霸道极端的机制,只要一个像素的alpha不满足条件,那么它就会被fragment shader舍弃,“我才不要你类!”;否则,
摘要由CSDN通过智能技术生成


写在前面


关于alpha的问题一直是个比较容易摸不清头脑的事情,尤其是涉及到半透明问题的时候,总是不知道为什么A就遮挡了B,而B明明在A前面。这篇文章就总结一下我现在的认识~


Alpha Test和Alpha Blending是两种处理透明的方法。


Alpha Test采用一种很霸道极端的机制,只要一个像素的alpha不满足条件,那么它就会被fragment shader舍弃,“我才不要你类!”。被舍弃的fragments不会对后面的各种Tests产生影响;否则,就会按正常方式写入到缓存中,并进行正常的深度检验等等,也就是说,Alpha Test是不需要关闭ZWrite的Alpha Test产生的效果也很极端,要么完全透明,即看不到,要么完全不透明。


Alpha Blending则是一种中庸的方式,它使用当前fragment的alpha作为混合因子,来混合之前写入到缓存中颜色值。但Alpha Blending麻烦的一点就是它需要关闭ZWrite,并且要十分小心物体的渲染顺序。如果不关闭ZWrite,那么在进行深度检测的时候,它背后的物体本来是可以透过它被我们看到的,但由于深度检测时大于它的深度就被剔除了,从而我们就看不到它后面的物体了。因此,我们需要保证物体的渲染顺序是从后往前,并且关闭该半透明对象的ZWrite。


注意Alpha Blending只是关闭ZWrite,人家可没有关闭ZTest哦!这意味着,在输出一个Alpha Blending的fragment时,它还是会判断和当前Color Buffer中的fragment的深度关闭,如果它比当前的fragment深度更远,那么它就不会再做后续的混合操作;否则,它就会和当前的fragment进行混合,但是不会把自己的深度信息写入Depth Buffer中。这是非常重要的,这一点决定了,即便一个不透明物体出现在一个透明物体的前面,不透明物体仍可以正常的遮挡住透明物体!也就说说,对于Alpha Blending来说,Depth Buffer是只读的。



Surface Shader


在Unity的Surface Shader里实现上述两种技术是非常简单的,可以参见之前的文章——Alpha TestAlpha Blending。简单总结一下就是,只要在#pragma里设置alphatest:_Cutoffalpha指令即可。


但是,很多童鞋说在使用Alpha Blending的时候得不到正确的结果,那么很大可能就是Tags没有设对,更具体一点,就是渲染队列没有设置正确。一般透明对象应该起码设置为Tags { "Queue"Transparent" }。为什么要正确设置渲染队列呢?如果没有正确设置,那么很有可能透明物体后面的物体会出现在透明物体的前面。


但是,它们背后的原理是什么呢?这就要从它们生成的Vertex & Fragment Shader说起了。那么,请看下一节~



Vertex & Fragment Shader


我们先来说比较简单的Alpha Test


在Vertex & Fragment Shader里,要实现它非常简单。


一种方法是自己在shader中编写代码,只要使用类似下面的语句就可以了:

  // alpha test
  clip (o.Alpha - _Cutoff);

clip函数非常简单,就是检查它的参数是否小于0。如果是,就调用 discard舍弃该fragment;否则就放过它。


另一种方法是使用固定管线的Alphatest指令。具体可见官方文档使用

  • 34
    点赞
  • 75
    收藏
    觉得还不错? 一键收藏
  • 31
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值