[UnityShader]说厌了的遮挡显示
首先是效果
这个其实有相当多的地方在说了,我就不嚼舌根了
大概原理:一个Shader两个Pass,第一个Pass不管深度,都渲染,但是不写入深度,第二个Pass几乎没有改动,因为后执行,会覆盖掉第一个Pass本就该渲染的地方(因为第一个Pass没有写入深度),而第一个Pass不该渲染的地方则不会做处理,因为此Pass的深度测试未通过
结合上面那张图来说就是第一个Pass不管模型有没有被绿色遮挡都渲染成全白,因为深度测试都通过,而第二个Pass会进行正常的深度测试,绿色部分是不会通过的,但是被绿色部分遮住以外的部分会通过,那么就覆盖了第一个pass的白色
ps:第二个Pass可以用unity内置的shader替代
1 // Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject' 2 3 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)' 4 5 Shader "Custom/RoleMaskShader" 6 { 7 Properties 8 { 9 _MainTex ("Texture", 2D) = "white" {} 10 _MainColor("MainColor", COLOR) = (1,1,1,1) 11 _ShadowColor("Color", COLOR) = (1,1,1,1) 12 _DiffuseScale("DiffuseScale", float) = 0.5 13 } 14 SubShader 15 { 16 //Tags { "RenderType"="Opaque" } 17 //LOD 100 18 19 Pass//第一个pass 20 { 21 Tags{"RenderType" = "Transparent" "Queue" = "Transparent"} 22 ZWrite off//关掉深度写入 23 ZTest greater//深度大于的通过,这里直接关掉也行 24 Blend SrcAlpha OneMinusSrcAlpha//混合,必须要开 25 CGPROGRAM 26 #pragma vertex vert 27 #pragma fragment frag 28 #include "UnityCg.cginc" 29 30 v2f_img vert(appdata_base a2v) 31 { 32 v2f_img o; 33 o.pos = UnityObjectToClipPos(a2v.vertex); 34 o.uv = a2v.texcoord; 35 return o; 36 } 37 fixed4 _ShadowColor; 38 fixed4 frag(v2f_img i) : SV_TARGET0 39 { 40 return _ShadowColor;//被挡住可以做描边等等 41 } 42 43 ENDCG 44 } 45 Pass//第二个pass,随意,这里写的是一个halfLambert 46 { 47 Tags{"RenderType" = "Transparent" "Queue" = "Transparent"} 48 CGPROGRAM 49 #pragma vertex vert 50 #pragma fragment frag 51 #include "UnityCg.cginc" 52 #include "Lighting.cginc" 53 54 struct v2f 55 { 56 float4 pos : POSITION; 57 fixed2 uv : TEXCOORD0; 58 float3 normal : TEXCOORD1; 59 }; 60 61 v2f vert(appdata_base a2v) 62 { 63 v2f o; 64 o.pos = UnityObjectToClipPos(a2v.vertex); 65 o.uv = a2v.texcoord; 66 o.normal = mul(a2v.normal, (float3x3)unity_WorldToObject).xyz; 67 return o; 68 } 69 fixed4 _MainColor; 70 sampler2D _MainTex; 71 float _DiffuseScale; 72 fixed4 frag(v2f i) : SV_TARGET0 73 { 74 fixed4 texColor = tex2D(_MainTex, i.uv); 75 float halfLambert = saturate(dot(normalize(i.normal), normalize(_WorldSpaceLightPos0.xyz))) * _DiffuseScale + (1 - _DiffuseScale); 76 fixed3 diffuseColor = _LightColor0.rgb * texColor.rgb * halfLambert * _MainColor; 77 return fixed4(diffuseColor, 1); 78 } 79 80 ENDCG 81 } 82 } 83 84 FallBack "VertexLit"//影子,和unity渲染阴影机制有关,shadowCaster 85 86 }
over~废话结束