【Unity】简单的深度虚化shader

【Unity】简单的深度虚化shader

实现效果
在这里插入图片描述

可以用于对地图场景边界的白模处理

实现方法

1.关键方法

UnityObjectToClipPos:将物体坐标转换为屏幕坐标

LinearEyeDepth:将屏幕坐标中的z值转换为实际的深度值

saturate:将值规范到0~1之间,小于0,则返回值为0,大于1,则返回值为1。

2.实现原理

通过LinearEyeDepth转换的深度值是的区间,只和相机的裁剪的远近截面有关。

这里将深度值除去远截面值(far)归一化的值赋给透明度,得到下图效果

float depth = LinearEyeDepth(i.depth);	
float depth_normal =depth/47;

从图上看,虚化的值是从近截面一值到远截面,所以需要设置参数,控制虚化的范围和虚化的位置

用一个简单是数学公式
y = a x + b y=ax+b\\ y=ax+b
其中, a > 0 a>0 a>0; 0 < y < 1 0<y<1 0<y<1

a a a控制虚化的范围,也就是斜率

b b b控制虚化的位置

得到上图,发现近处的透明。再用1-值取反,完成效果。

3.完整shader
方法一

Shader "Custom/DepthShader" {
    
    
	Properties
	{
    
    
		_MainTex("Texture", 2D) = "white" {
    
    }
		_Color("Color",Color) = (1,1,1,1)
		_Blur("Blur", Range(0, 40)) = 32
		_Dis("Dis", Range(-40, 40)) = -32
	}
		SubShader
		{
    
    
			Tags {
    
     "Queue" = "Transparent"  "RenderType" = "Opaque"  }
			LOD 100

			Pass
			{
    
    
		Cull Back      //剔除后面
		//Blend SrcAlpha OneMinusSrcAlpha
			Blend One OneMinusSrcAlpha

		CGPROGRAM
		#pragma vertex vert
		#pragma fragment frag
		#include "UnityCG.cginc"

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

		struct v2f
		{
    
    
			float2 uv : TEXCOORD0;
			float4 vertex : SV_POSITION;
			float depth : TEXCOORD1;
		};

		sampler2D _MainTex;
		float _Blur;
		float _Dis;
		fixed4 _Color;
	   float4 _MainTex_ST;

		v2f vert(appdata v)
		{
    
    
			v2f o;
			o.vertex = UnityObjectToClipPos(v.vertex);
			o.depth = UnityObjectToClipPos(v.vertex).z;
			o.uv = TRANSFORM_TEX(v.uv, _MainTex);
			return o;
		}

		fixed4 frag(v2f i) : SV_Target
		{
    
    
		   float depth = LinearEyeDepth(i.depth);
		  float depth_normal = 1 - saturate((depth * _Blur) + _Dis);
			clip(depth_normal);
			float4 col_Blur = depth_normal;
			fixed4 col = tex2D(_MainTex, i.uv) * col_Blur * _Color;
			return col;
		}
		ENDCG
	}
}
}

方法二

Shader "Custom/DepthCameraShader" {
    
    
	Properties
	{
    
    
		_MainTex("Texture", 2D) = "white" {
    
    }
		_Color("Color",Color) = (1,1,1,1)
		_Blur("Blur", Range(0, 40)) = 32
		_Dis("Dis", Range(-40, 40)) = -32
	}
		SubShader
		{
    
    
			Tags {
    
     "Queue" = "Transparent"  "RenderType" = "Opaque"  }
			LOD 100

			Pass
			{
    
    
		Cull Back      //剔除后面
		Blend SrcAlpha OneMinusSrcAlpha

		CGPROGRAM
		#pragma vertex vert
		#pragma fragment frag
		#include "UnityCG.cginc"

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

		struct v2f
		{
    
    
			float2 uv : TEXCOORD0;
			float4 vertex : SV_POSITION;
			float3 worldPos:TEXCOORD2;
		};

		sampler2D _MainTex;
		float _Blur;
		float _Dis;
		fixed4 _Color;
	   float4 _MainTex_ST;

		v2f vert(appdata v)
		{
    
    
			v2f o;
			o.vertex = UnityObjectToClipPos(v.vertex);
			o.uv = TRANSFORM_TEX(v.uv, _MainTex);
			o.worldPos = mul(unity_ObjectToWorld, v.vertex);
			return o;
		}

		fixed4 frag(v2f i) : SV_Target
		{
    
    
			float dis = distance(_WorldSpaceCameraPos.xyz ,i.worldPos);
		    float depth_normal =1- saturate((dis * _Blur) + _Dis);
			float4 col_Blur = depth_normal;
			fixed4 col = tex2D(_MainTex, i.uv) * col_Blur * _Color;
			return col;
		}
		ENDCG
	}
		}
}

4.Shader Graphs实现方法

ShaderGraphs深度虚化资源

猜你喜欢

转载自blog.csdn.net/dxs1990/article/details/133128645