六 UnityShader透明效果( 二 )


Tags{"Queue"="AlphaTest""IgnoreProjector"="True"}
最后在片元着色器中根据纹理的alpha通道的值进行剔除
fixed4 frag(v2f i):SV_Target{// 获取归一化的光源方向const fixed3 worldLight = normalize(_WorldSpaceLightPos0);const fixed4 texColor = tex2D(_MainTex,i.uv);// 根据条件剔除if(texColor.a - _Cutoff < 0){discard;}// 环境光const fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;// 计算漫反射const fixed3 diffuse = _LightColor0.rgb * texColor.rgb * _Diffuse.rgb * (0.5*dot(i.worldNormal, worldLight)+0.5);fixed3 color = ambient + diffuse;return fixed4(color, 1);}
找一张alpha值不同的图片作为纹理 , 得到如下效果
三、透明度混合
Unity提供了设置混合模式的命令——Blend 。混合时使用的函数就由该指令决定 。Unity提供的Blend指令如下
对于「Blend」和「Blend, 」两个命令 , 它们实际上表达的是两个混合公式
O r g b = S r c F a c t o r × S r g b + D s t F a c t o r × D r g b O_{rgb}=×S_{rgb}+×D_{rgb} Orgb?=×Srgb?+×Drgb?
O a = S r c F a c t o r A × S a + D s t F a c t o r A × D a O_{a}=×S_{a}+×D_{a} Oa?=×Sa?+×Da?
其中 O r g b 、 O a O_{rgb}、O_{a} Orgb?、Oa?代表混合后的rgb通道和a通道 ,  S r g b 、 S a S_{rgb}、S_{a} Srgb?、Sa?代表源颜色通道 ,  D r g b 、 D a D_{rgb}、D_{a} Drgb?、Da?代表目标颜色通道 。第一个命令只提供了两个因子 , 意味着rgb通道和a通道的混合因子都是和 。
那么这些混合因子可以有哪些值呢?
另外 , 前面的公式将源颜色和目标颜色与混合因子的乘积相加得出最终结果 。我们当然也可以自定义其他的混合操作 。「 」的作用就是如此 。Unity提供的混合操作如下
下面列出了常见的混合类型 , 类似于PS中对应的混合效果

六  UnityShader透明效果

文章插图
// 正常(Normal) , 即透明度混合BlendSrcAlphaOneMinusSrcAlpha// 柔和相加(Soft Additive)BlendOneMinusDstColorOne// 正片叠底(Multiply) , 即相乘BlendDstColorZero// 两倍相乘(2x Multiply)BlendDstColorSrcColor// 变暗(Darken)BlendOpMinBlendOneOne// 变亮(Lighten)BlendOpMaxBlendOneOne// 滤色(Screen)BlendOneMinusDstColorOne// 等同于BlendOneOneMinusSrcColor// 线性减淡(Linear Dodge)BlendOneOne
透明度混合实现
接下来我们尝试实现透明度混合 。依然是基于之前的纹理采样的进行修改 。
首先定义一个属性用来控制整体的透明度 , 并在CG中声明对应变量
_AlphaScale("Alpha Scale",Range(0,1)) = 1
在Tags中指定渲染队列 , 忽略投影器影响 , 将「」设置为「」
Tags{"Queue"="Transparent""IgnoreProjector"="True""RenderType"="Transparent"}
在Pass通道中 , 将光照模式设置为前项渲染路径 , 关闭深度写入 , 并设置混合模式
Tags{ "LightMode"="ForwardBase" }ZWrite OffBlend SrcAlpha OneMinusSrcAlpha
最后设置片元着色器返回值中的透明通道
fixed4 frag(v2f i):SV_Target{const fixed3 worldLight = normalize(_WorldSpaceLightPos0);const fixed4 texColor = tex2D(_MainTex,i.uv);const fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;const fixed3 diffuse = _LightColor0.rgb * texColor.rgb * _Diffuse.rgb * (0.5*dot(i.worldNormal, worldLight)+0.5);fixed3 color = ambient + diffuse;// 修改返回值中的透明通道return fixed4(color, texColor.a * _AlphaScale);}