透明度混合相較于透明度測試更加復雜一些助泽,透明度混合可以得到真正的半透明效果楞慈,使用當前片元和透明度作為混合因子旺嬉,與已經(jīng)存儲在顏色緩沖區(qū)的顏色值進行混合,得到新的顏色本冲。透明度混合需要關(guān)閉深度寫入准脂,這使得我們需要關(guān)注物體的渲染順序。
我們使用Unity的混合指令Blend檬洞,想實現(xiàn)半透明的效果就要把當前自身的顏色和已經(jīng)存在的顏色緩沖中的顏色進行混合狸膏,混合時使用的函數(shù)就是該指令決定的。
ShaderLab Blend指令
Blend Off關(guān)閉混合
Blend SrcFactor DstFactor開啟混合疮胖,并設(shè)置混合因子环戈。源顏色乘SrcFactor闷板,目標顏色乘以DstFactor澎灸,再將兩者相加后存入顏色緩存中。
相較于透明度測試遮晚,代碼部分改變性昭,Tags的Queue標簽設(shè)置為Transparent,RenderType標簽讓Shader歸入提前定義的組县遣,我們通過ZWriteOff關(guān)閉深度寫入糜颠,Blend設(shè)置兩個混合因子。
在fragment中萧求,我們返回的的Color值包括一個Alpha值其兴。
Shader "Unlit/AlphaBlend"
{
Properties{
_Color("Main Tint",Color) = (1,1,1,1)
_MainTex("Main Tex", 2D) = "white"{}
_AlphaScale("Alpha Scale", Range(0,1)) = 1
}
SubShader{
Tags{"Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent"}
Pass{
Tags{"LightMode" = "ForwardBase"}
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Lighting.cginc"
fixed4 _Color;
sampler2D _MainTex;
float4 _MainTex_ST;
fixed _AlphaScale;
struct a2v {
float4 vertex : POSITION;
fixed3 normal : NORMAL;
float4 texcoord : TEXCOORD0;
};
struct v2f {
float4 pos : SV_POSITION;
float3 worldNormal : TEXCOORD0;
float3 worldPos : TEXCOORD1;
float2 uv : TEXCOORD2;
};
v2f vert(a2v v) {
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.worldNormal = UnityObjectToWorldNormal(v.normal);
o.worldPos = mul(unity_ObjectToWorld, v.vertex);
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
return o;
}
fixed4 frag(v2f i) :SV_Target{
fixed3 worldNormal = normalize(i.worldNormal);
fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
fixed4 texColor = tex2D(_MainTex, i.uv);
fixed3 albedo = texColor.rgb * _Color.rgb;
fixed3 diffuse = _LightColor0.rgb * albedo * max(0, dot(worldNormal, worldLightDir));
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT * albedo;
return fixed4(diffuse + ambient, texColor.a * _AlphaScale);
}
ENDCG
}
}
}
透明度混合的雙面渲染
Cull Back是默認的,背對攝像機的一面不會被渲染
Cull Front 是面向攝像機的不會渲染
Pass{
Tags{"LightMode" = "ForwardBase"}
Cull Front
Pass{
Tags{"LightMode" = "ForwardBase"}
Cull Back
我們改動代碼夸政,先渲染背面元旬,再渲染正面,可以得到下面的結(jié)果