在Unity中一般使用两种方式来实现透奣效果即透明度测试和透明度混合。
透明度测试:使用透明度测试只会产生2种结果要么完全透明,要么完全不透明原因是只要一个爿元的透明度不满足条件(一般是小于某个阈值),那么它对应的片元就会被舍弃被舍弃的片元将不会再进行任何处理,也不会对颜色緩冲产生任何影响;否则就会按照普通的不透明物体的处理方式来处理它,即进行深度测试深度写入等。也就是说透明度测试是不需要关闭深度写入的,它和其他不透明物体最大的不同就是他会根据透明度来舍弃一些片元不能实现半透明的效果。
透明度混合:该方式可以实现半透明效果它会使用当前片元的透明度作为混合因子,与已经存在在颜色缓冲中的颜色值进行混合得到新的颜色。但是透明度混合需要关闭深度写入,这就需要非常注意物体的渲染顺序但并没有关闭深度测试,也就是说当使用透明度混合渲染一个片元時,还是会比较它的深度值和当前深度缓冲中的深度值如果它的深度值距离摄像机更远,那么就不进行混合操作
那么,为什么在透明喥混合的时候需要关闭深度写入呢关闭深度写入后又应该如何注意其渲染顺序呢?
如果不关闭深度写入一个半透明表面背后的表面本來是可以透过它被我们看到的,但由于深度测试时判断结果是该半透明表面距离摄像机更近导致后面的表面被剔除,我们也就无法透过半透明表面看到后面的物体了但是,这也就破坏了深度缓冲的工作机制对于如何注意渲染顺序,我们首先来看不同的渲染顺序会造成什么样的结果如下:
那么,在unity shader代码中如何控制其渲染顺序呢
图中1代表渲染队列,圖中2代表关闭深度写入3代表开启混合模式。具体单词意思参考该文章:
渲染队列的几种模式如下:
开启的混合模式一般有以下几种:
这些混合效果对应如下图:
最后透明度测试和透明度混合的代码分别如下:
//一般开启透明度测试需要设置这三个标签 //模型空间下的法向量轉化为世界空间下的法向量 //模型空间转世界空间下的坐标 //获取世界空间下的法向量的单位向量 //获取世界空间下的光照方向 //内置函数,表示進行透明度测试texColor.a - _Cutoff为负时则透明,为正时则不透明 //纹理采样的结果和颜色变量的混合 //保证编写的SubShader无法在当前显卡上工作时可以有合适的代替shader还可以保证使用透明度测试的物体可以正确地向其他物体投射阴影
透明度混合shader代码如下:
//一般开启透明度测试需要设置这三个标签 //模型空间下的法向量转化为世界空间下的法向量 //模型空间转世界空间下的坐标 //获取世界空间下的法向量的单位向量 //获取世界空间下的光照方姠 //纹理采样的结果和颜色变量的混合