// 使用Alpha Blend和Alpha Test混合处理 Shader "Zhanyou/Character/NPCDead" { Properties { _MainTex ("Base (RGB)", 2D) = "white" {} _Emission ("Emission", Range(0, 1)) = 0.2 // 角色材质颜色,乘法运算 _Color("Blend Color", Color) = (1, 1, 1, 1) // Emission叠加颜色,加法运算 _AddColor("Additive Color", Color) = (0, 0, 0, 1) // 溶解贴图,RGB为颜色,A为溶解开始数值 _DissolveTex ("Dissolve Tex", 2D) = "white" {} // 部分溶解的渐变区域值 _DissolveFade ("Dissolve Fade", Range(0, 1)) = 0.1 // 完全溶解的Alpha数值 _DissolveEnd ("Dissolve End", Range(0, 1)) = 0.5 } SubShader { Tags { "IgnoreProjector"="True" "Queue"="AlphaTest+20" // 仍然认为这个是普通NPC的Type "RenderType"="Opaque" } // 第一个通道为溶解未开始部分写入ZBuffer Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata_t { float4 vertex : POSITION; float2 texcoord : TEXCOORD0; }; struct v2f { float4 vertex : SV_POSITION; float2 dissolveCoord : TEXCOORD0; }; uniform sampler2D _DissolveTex; uniform half4 _DissolveTex_ST; uniform half _DissolveFade; uniform half _DissolveEnd; v2f vert (appdata_t v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.dissolveCoord = TRANSFORM_TEX(v.texcoord, _DissolveTex); return o; } fixed4 frag (v2f i) : SV_Target { fixed4 dissolve = tex2D(_DissolveTex, i.dissolveCoord); clip(dissolve.a - _DissolveEnd - _DissolveFade); return 0; } ENDCG } // 第二个通道写入RGBA值 Pass { Blend SrcAlpha OneMinusSrcAlpha // 注:部分NPC会挡住自己,暂时将渲染次序改高防止遮挡其他透明物体 ZWrite Off Offset 0, 0.01 CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma multi_compile_fog #include "NpcBase.cginc" struct v2f { float4 pos : SV_POSITION; float2 texcoord : TEXCOORD0; float2 dissolveCoord : TEXCOORD01; half rim : TEXCOORD2; UNITY_FOG_COORDS(3) }; uniform sampler2D _DissolveTex; uniform half4 _DissolveTex_ST; uniform half _DissolveFade; uniform half _DissolveEnd; v2f vert (appdata_tan v) { v2f o; UNITY_INITIALIZE_OUTPUT(v2f, o); NPC_VERT_COMMON(o); o.dissolveCoord = TRANSFORM_TEX(v.texcoord, _DissolveTex); UNITY_TRANSFER_FOG(o, o.pos); return o; } fixed4 frag(v2f i) : SV_TARGET { fixed4 col; NPC_FRAG_COMMON(col); fixed4 dissolve = tex2D(_DissolveTex, i.dissolveCoord); if (dissolve.a <= _DissolveEnd + _DissolveFade) { col.a = max(0.0, (dissolve.a - _DissolveEnd) / _DissolveFade); col.rgb = lerp(lerp(dissolve.rgb, col.rgb, col.a), dissolve.rgb, col.a * col.a); } else UNITY_OPAQUE_ALPHA(col.a); UNITY_APPLY_FOG(i.fogCoord, col); return col; } ENDCG } // 其实没有用的投影通道,但是Unity貌似会用这个通道做屏幕深度运算,所以保留一个 // Shadow Caster // ---- shadow caster pass: Pass { Name "ShadowCaster" Tags { "LightMode" = "ShadowCaster" } CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma multi_compile_shadowcaster #pragma skip_variants FOG_LINEAR FOG_EXP FOG_EXP2 #include "HLSLSupport.cginc" #include "UnityShaderVariables.cginc" #define UNITY_PASS_SHADOWCASTER #include "UnityCG.cginc" #include "Lighting.cginc" half _Cutoff; uniform sampler2D _DissolveTex; uniform float4 _DissolveTex_ST; uniform half _DissolveFade; uniform half _DissolveEnd; struct v2f { V2F_SHADOW_CASTER; float2 uv : TEXCOORD1; // _MainTex float3 worldPos : TEXCOORD2; }; v2f vert (appdata_full v) { v2f o; UNITY_TRANSFER_INSTANCE_ID(v,o); o.uv = TRANSFORM_TEX(v.texcoord, _DissolveTex); float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz; fixed3 worldNormal = UnityObjectToWorldNormal(v.normal); o.worldPos = worldPos; TRANSFER_SHADOW_CASTER_NORMALOFFSET(o) return o; } fixed4 frag (v2f i) : SV_Target { fixed4 c = tex2D(_DissolveTex, i.uv); clip(c.a - _DissolveEnd - _DissolveFade); SHADOW_CASTER_FRAGMENT(i) } ENDCG } } Fallback "Zhanyou/Character/NPCAlpha" }