思路:渲染两次。
1.第一次渲染:利用Greater进行深度测试,当目标被遮挡时,用一个边缘光的效果显示。
2.第二次渲染:正常渲染。
边缘光的思路:观察方向和顶点法向量夹角越大,边缘光越明显。边缘光强度由公式rim=1-dot(view,normal)来表示。
代码实现:
Shader "Pj/XRay" { Properties { _MainTex("Base 2D", 2D) = "white"{} _XRayColor("XRay Color",Color)=(0,0,0,1) _SelfBritness("Self Britness",Range(0,5))=1 } SubShader { Tags{ "Queue" = "Geometry+233" "RenderType" = "Opaque" } Pass { Blend SrcAlpha OneMinusSrcAlpha //Blend One OneMinusSrcColor ZWrite Off ZTest Greater //Offset -1000,0 CGPROGRAM #pragma vertex vert #pragma fragment frag #include "Lighting.cginc" #include "UnityCG.cginc" sampler2D _MainTex; float4 _MainTex_ST; float4 _XRayColor; float _SelfBritness; struct v2f { float4 pos : SV_POSITION; float4 worldPos:TEXCOORD0; float3 normal: NORMAL; //float2 uv : TEXCOORD1; }; v2f vert (appdata_base v) { v2f o; o.pos = mul(UNITY_MATRIX_MVP, v.vertex); o.worldPos=mul(_Object2World, v.vertex); //o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); o.normal=v.normal; return o; } fixed4 frag(v2f i) : SV_Target { float3 normal = normalize(mul(i.normal, (float3x3)_World2Object)); float3 viewDir=normalize(_WorldSpaceCameraPos-i.worldPos).xyz; float rim = 1 -max(0, dot(normal, viewDir)); return _XRayColor * rim* _SelfBritness ; } ENDCG } Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "Lighting.cginc" sampler2D _MainTex; float4 _MainTex_ST; struct v2f { float4 pos : SV_POSITION; float2 uv : TEXCOORD1; }; v2f vert(appdata_base v) { v2f o; o.pos = mul(UNITY_MATRIX_MVP, v.vertex); o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); return o; } fixed4 frag(v2f i) : SV_Target { return tex2D(_MainTex, i.uv); } ENDCG } } FallBack "Diffuse" }