透明度测试的实现实际上与对待普通的不透明物体几乎是一样的,只是在片元着色器中增加了对透明度阈值的判断和对片元进行裁剪的代码;而透明度混合的实现要比透明度测试复杂一些。
原理回顾
透明度混合可以得到真正的半透明效果。它会使用当前片元的透明度作为混合因子,与已经存储在颜色缓冲中的颜色值进行混合,得到新的颜色。它需要关闭深度写入,因而我们需要非常注意渲染的顺序。另外,透明度混合虽然关闭了深度写入,但没有关闭深度测试,只不过此时比较深度值将决定是否进行混合操作。在这种情况下,不透明物体出现在透明物体前的场景中,即使先渲染了不透明物体,也可以正常地遮挡住透明物体的部分。换句话说,对于透明度混合而言,深度是只读的。需要注意的是,要格外小心物体的渲染顺序通常使用Unity提供的Blend命令进行透明度混合。其命令语义如下:Blend Off : 关闭混合
Blend SrcFactor DstFactor : 开启混合,并设置混合因子。颜色缓冲中存入的值是由源颜色(该片元产生的颜色)和SrcFactor的乘积与目标颜色(已经存在于颜色缓冲中的颜色)与DstFactor的乘积相加得到的。
Blend SrcFactor DstFactor, SrcFactorA DstFactorA : 和上面几乎一样只是混合因子不同
BlendOp BlendOperation : 使用BlendOperation而不是简单乘加去做混合
本节使用第二种语义。
实践运行平台:
Unity 2018.4.2f1 (64-bit)
准备工作在Unity中新建一个场景,命名为Scene_8_4。默认场景中将包含一个摄像机和一个平行光,并使用内置的天空盒子。为便于查看效果,在Window->Rendering->Lighting Seting->Skybox中去掉场景中的天空盒子。
新建Shader(右键Create->Shader->任一个Shader)并命名为AlphaBlend;新建材质(右键Create->Material)并命名为AlphaBlendMat,将新建的Shader拖拽赋给新建材质。
在场景中创建一个立方体,并拖拽到合适位置,将其材质修改为新建材质。
保存场景。
其他准备:一张透明纹理,其中每个方格的透明度不同(从左到右,从上到下依次是80%,70%,60%,50%)
Shader实现:
打开新建的AlphaBlend,删除所有已有代码并把AlphaTest代码粘贴进来,并作修改得到:
Shader "Custom/AlphaBlend"
{
Properties
{
_Color ("Main Tint", Color) = (1,1,1,1)
_MainTex ("Main Tex", 2D) = "white" {}
//使用新的属性_AlphaScale来代替原先的_Cutoff属性,用以控制透明纹理的整体透明度
_AlphaScale ("Alpha Scale", Range(0, 1)) = 1
}
SubShader
<