unityshader精要8
Chapter8 透明效果
实现透明的方法
unity中通常使用两种方式实现透明效果
1.透明度测试(alpha test),(无法实现真正的半透明)
2.透明度混合(alpha blending)
使用深度测试,可以不考虑渲染顺序,但是使用透明度混合时,需要关闭ZWrite
,关闭了深度写入
虽然透明度测试不需要关闭,但是它的机制是如果透明度不满足某个阈值(通常小于),直接舍弃该片元。
- 为什么关闭
ZWrite
?
由于深度测试丢弃远处被遮挡部分,但是透明物体的机制是"可以透过并看见远处的物体"。
关闭了ZWrite,渲染顺序则成了问题。
流程
1.渲染时,会进行深度测试,如果先渲染后面的不透明b,将b写入颜色缓冲和深度缓冲;然后渲染前面的透明a,a写入颜色缓冲,会发生透明混合,显示正确。
2.如果先渲染a,进行深度测试,写入颜色缓冲,但是关闭了ZWrite,无法写入深度值,然后渲染b,写入深度值,写入颜色缓冲,b的颜色覆盖a,只能看见b。
3.半透明物体之间亦然。
Alpha Test
Unity Shader解决方案为SubShader 中的Tags
以下为透明度测试alpha test示例
1 | SubShader{ |
每块的透明度都不同,根据面板调整_Cutoff可以看出哪个更低,低的那个会直接被剔除
结果图
Alpha Blend
1 | SubShader{ |
解决排序问题
一般先开启深度测试、写入,先渲染不
透明物体,然后关闭写入,对不透明物体排序,先渲染后面的物体
- 但是仍然存在很大问题。
比如一个物体,各个部分互相遮挡,又或者多个物体,相互遮挡,而深度排序是像素级别的。
问题在于
现在开启ZWrite
1 | Pass{ |
新添加一个Pass通道。该Pass专门用来写入深度缓冲,并且先执行。
Pass通道中加上//Cull Front/Back/Off 需要双面渲染时关闭剔除
注意如果关闭了深度写入,此时再双面渲染就会出现半透明错误渲染
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.