unity 显示3D模型被遮挡时透明边框效果

在3D游戏中,地图上的各种物件会对模型照成遮挡。主要是在主角上 体验很不好。让被遮挡的部分有个透明边框显示出来,是个比较好的解决方案。

思路:要分成两个PASS来做,1个就是画出透明边框,另一个是正常的显示纹理。透明边框的PASS需要把在被遮挡时显示,这里需要对深度测试和深度写入做操作。当没被遮挡到时则正常显示模型。

上节做完边缘泛光刚好可以用上,稍微改造下就可以被边缘显示出来。
看图:

unity 显示3D模型被遮挡时透明边框效果_第1张图片
成品效果:
unity 显示3D模型被遮挡时透明边框效果_第2张图片
ZTest 默认是LEqual的 则是相对于摄像机在越靠前的物体优先渲染。则后面的物体会被前面的物体遮挡。而我们需要相反,半透明边框是要在被遮挡住的时候才被渲染,所以使用了Greater。

ZWrite 默认是 On 则默认做深度的写入,这里同理也要关掉。

代码:

Shader "JackyShader/maskShader"
{
	Properties
	{
		_MainTex ("Texture", 2D) = "white" {}
		_maskColor("MaskColor",Color) = (0,1,0)
	}
	
	SubShader
	{
		Tags { "RenderType"="Transparent" "Queue" = "Transparent+1" }
		LOD 100

		Pass
		{
			Blend SrcAlpha OneMinusSrcAlpha
			//深度大于于 深度最大值时,渲染物体
			ZTest Greater
			//关闭深度写入 就是为了不被靠前的物体遮挡到
            ZWrite Off
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			// make fog work
			#pragma multi_compile_fog
			#include "UnityCG.cginc"

			struct appdata
			{
				float4 vertex : POSITION;
				float2 uv : TEXCOORD0;
				float3 normal : NORMAL;
			};

			struct v2f
			{
				float2 uv : TEXCOORD0;
				UNITY_FOG_COORDS(1)
				float4 vertex : SV_POSITION;
				float4 pos : TEXCOORD1;
				float3 normal : NORMAL;
			};

			sampler2D _MainTex;
			float4 _MainTex_ST;
			float4 _maskColor;
			
			v2f vert (appdata v)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.uv = TRANSFORM_TEX(v.uv, _MainTex);
				o.pos = v.vertex;
				o.normal = v.normal;
				UNITY_TRANSFER_FOG(o,o.vertex);
				return o;
			}
			
			fixed4 frag (v2f i) : SV_Target
			{
				//显示被遮挡的模型内泛光
				fixed4 col = fixed4(0,0,0,0.1);
				float3 wpos = mul(unity_ObjectToWorld, i.pos).xyz;
				float3 viewDir = UnityWorldSpaceViewDir(wpos);
				viewDir = normalize(viewDir);

				float3 normal = UnityObjectToWorldNormal(i.normal);

				float flag = 1 - saturate(dot(viewDir,normal));

				float br = pow(flag,2.0);

				col = lerp(col , _maskColor , br);
				
				// apply fog
				UNITY_APPLY_FOG(i.fogCoord, col);
				return col;
			}
			ENDCG
		}
		
		Pass
		{
			//正常显示 模型
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			// make fog work
			#pragma multi_compile_fog
			#include "UnityCG.cginc"

			struct appdata
			{
				float4 vertex : POSITION;
				float2 uv : TEXCOORD0;
			};

			struct v2f
			{
				float2 uv : TEXCOORD0;
				UNITY_FOG_COORDS(1)
				float4 vertex : SV_POSITION;
			};

			sampler2D _MainTex;
			float4 _MainTex_ST;
			
			v2f vert (appdata v)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.uv = TRANSFORM_TEX(v.uv, _MainTex);
				UNITY_TRANSFER_FOG(o,o.vertex);
				return o;
			}
			
			fixed4 frag (v2f i) : SV_Target
			{
				// sample the texture
				fixed4 col = tex2D(_MainTex, i.uv);
			
				// apply fog
				UNITY_APPLY_FOG(i.fogCoord, col);
				return col;
			}
			ENDCG
		}
	}
	
}

你可能感兴趣的:(shader,unity,图形学,游戏,webgl)