基本原理:被遮挡的部分关闭深度写入, 显示透明效果;未被遮挡的部分不关闭深度测试,显示正常贴图效果,即使用两个Pass即可。
Pass1:关闭深度写入(ZWrite Off),深度测试渲染较远的物体,即模型被物体遮挡的部分(ztest greater)。
Pass2:开启深度写入,正常渲染。
1 Shader "xj/Character/Normal" { 2 Properties { 3 _Color ("Main Color", Color) = (1,1,1,1) 4 _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {} 5 _intensity ("Intensity", float ) = 1.0 6 7 _RimColor("RimColor",Color) = (0,1,1,1) 8 _RimPower ("Rim Power", Range(0.1,8.0)) = 1.0 9 } 10 11 12 SubShader 13 { 14 LOD 300 15 Tags { "Queue" = "Geometry+500" "RenderType"="Opaque" } 16 Pass 17 { 18 Blend SrcAlpha One 19 ZWrite off 20 Lighting off 21 22 ztest greater 23 24 CGPROGRAM 25 #pragma vertex vert 26 #pragma fragment frag 27 #include "UnityCG.cginc" 28 29 float4 _RimColor; 30 float _RimPower; 31 32 struct appdata_t { 33 float4 vertex : POSITION; 34 float2 texcoord : TEXCOORD0; 35 float4 color:COLOR; 36 float4 normal:NORMAL; 37 }; 38 39 struct v2f { 40 float4 pos : SV_POSITION; 41 float4 color:COLOR; 42 } ; 43 v2f vert (appdata_t v) 44 { 45 v2f o; 46 o.pos = mul(UNITY_MATRIX_MVP,v.vertex); 47 float3 viewDir = normalize(ObjSpaceViewDir(v.vertex)); 48 //视线与法线垂直的部分(点乘为0)即是外轮廓,加重描绘 49 float rim = 1 - saturate(dot(viewDir,v.normal )); 50 o.color = _RimColor*pow(rim,_RimPower); 51 return o; 52 } 53 float4 frag (v2f i) : COLOR 54 { 55 return i.color; 56 } 57 ENDCG 58 } 59 Pass { 60 CGPROGRAM 61 #pragma vertex vert 62 #pragma fragment frag 63 #pragma fragmentoption ARB_precision_hint_fastest 64 65 #include "UnityCG.cginc" 66 67 struct appdata_t { 68 float4 vertex : POSITION; 69 half2 texcoord : TEXCOORD0; 70 }; 71 72 struct v2f { 73 float4 vertex : SV_POSITION; 74 half2 texcoord : TEXCOORD0; 75 }; 76 77 sampler2D _MainTex; 78 fixed4 _Color; 79 fixed _intensity; 80 81 v2f vert (appdata_t v) 82 { 83 v2f o; 84 o.vertex = mul(UNITY_MATRIX_MVP,v.vertex); 85 o.texcoord = v.texcoord; 86 return o; 87 } 88 89 fixed4 frag (v2f i) : SV_Target 90 { 91 fixed4 col = tex2D(_MainTex, i.texcoord) * _Color * _intensity; 92 return col; 93 } 94 ENDCG 95 } 96 } 97 }