引言

在Unity中,我们通常使用两种方法来实现透明效果:第一种是使用透明度测试,这种方法其实无法得到真正的半透明效果;另一种是透明度混合,这种方法很棒。

事实上,对于不透明物体,不考虑它们的渲染顺序也能得到正确的排序效果,这是由于强大的深度缓冲的存在。根据深度缓冲中的值来判断该片元距离摄像机的距离,当渲染一个片元时,需要把它的深度值和已经存在于深度缓冲中的值进行比较(如果开启了深度测试(也就是读操作)),如果它的值距离摄像机更远,那么说明这个片元不应该被渲染到屏幕上(有物体挡住了它);否则,这个片元应该覆盖掉此时颜色缓冲中的像素值,并把它的深度值更新到深度缓冲中(如果开启了深度写入(也就是写操作))。

但如果想要实现透明效果,事情就不那么简单了,这是因为,当用透明度混合时,我们关闭了深度写入(ZWrite)。

简单来说,透明度测试透明度混合的基本原理如下:
透明度测试:
它采用一种“霸道极端”的机制,只要一个片元的透明度不满足条件(通常是小于某个阈值),那么它对应的片元就会被舍弃。也就是说,透明度测试是不需要关闭深度写入的,它和其他不透明物体最大的不同就是它会根据透明度来舍弃一些片元。虽然简单,但是它产生的效果也很极端,要么完全透明,即看不到,要么完全不透明。
透明度混合:
这种方法可以得到真正的半透明效果。它会使用当前片元的透明度作为混合因子,与已经存储在颜色缓冲中的颜色值进行混合,得到新的颜色。也就是说,对于透明度混合来说,深度缓冲是只读的。

渲染顺序的重要性

如果不关闭深度写入,一个半透明表面背后的表面本来可以透过它被我们看到的,但由于深度测试时判断结果是该半透明表面距离摄像机更近,导致后面的表面会被剔除,我们也就无法透过半透明表面看到后面的物体了。关闭深度写入导致渲染顺序将变得非常重要。

Unity Shader的渲染顺序

unity 相机透明背景 unity设置图片透明度_半透明效果

透明度测试

不好!别用!
得到的透明效果在边缘处往往参差不齐,有锯齿。

透明度混合

好用!需要使用Unity提供的混合命令——Blend。Blend是Unity提供的设置混合模式的命令。也就是混合当前自身的颜色和已存在于颜色缓冲中的颜色。
透明度混合适合绝大多数模型。但当模型本身有复杂的遮挡关系的时候,就会有各种因为排序错误而产生的错误的透明效果,这时就要用下方的开启深度写入的半透明效果

开启深度写入的半透明效果

透明度混合的变种。由于关闭深度写入会造成错误的排序的情况。一种很好的解决方法:使用两个Pass来渲染模型。第一个Pass开启深度写入,但不输出颜色,仅仅把该模型的深度值写入深度缓冲中;第二个Pass进行正常的透明度混合。由于上一个Pass 已经得到了逐像素的正确的深度信息,该Pass就可以按照像素级别的深度排序结果进行透明渲染。但这种方法的缺点在于,多使用一个Pass 会对性能造成一定的影响。