【Unity3d Shader】扫描效果(场景深度扫描)

Unity3d的深度图可以实现一些神奇的效果,关键之处仅三行代码

  1. _CameraDepthTexture//Unity3d提供给我们的深度图 
  2. float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,uv);//按uv坐标获取_CameraDepthTexture中的深度
  3. depth = Linear01Depth(depth);//深度线性到01范围

有了深度,我们可以模仿扫描仪的效果去扫描场景,效果如下:

【Unity3d Shader】扫描效果(场景深度扫描)_第1张图片

shader代码如下,很简单

Shader "mgo/scan" 
{
	Properties
	{
		_MainTex("Texture", 2D) = "white" {}
		_LightColor("_LightColor", Color) = (1, 0, 0, 0.5)
		_LightWidth("_LightWidth", range(0.01, 0.5)) = 0.002
		_Speed("_Speed", range(0.001, 8)) = 0.3
	}

	SubShader
	{
		Tags{ "RenderType" = "Opaque" }
		
		ZTest Off
		cull Off
		ZWrite Off
		Pass
		{
			ZTest Off
			Cull Off
			ZWrite Off
			ColorMask RGBA
			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;
			};

			sampler2D _MainTex;
			sampler2D _CameraDepthTexture;
			fixed4 _LightColor;
			float _Speed;
			float _LightWidth;

			v2f vert(appdata v)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.uv = v.uv;
				return o;
			}

			fixed4 frag(v2f i) : SV_Target
			{
				fixed4 color = tex2D(_MainTex, i.uv);

				float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv);
				depth = Linear01Depth(depth);
				float pos = (_Time.y * _Speed * 1000 % 1000) * 0.001;
				if (depth > pos && depth < pos + _LightWidth)
				{
					color.rgb = color.rgb * (1 - _LightColor.a) + _LightColor.rgb;
				}
				return color;
			}
			ENDCG
		}
		
	}
}

c#代码更简单, 其实只有一行: Graphics.Blit(source, destination, material, 0);

using UnityEngine;

namespace GameBase.Effect
{
    public class ScanEffect : ImageEffectBase
    {
        [Range(0f, 0.05f)]
        [SerializeField]
        private float _lightWidth = 0.002f;

        [Range(0.0f, 2.0f)]
        [SerializeField]
        private float _speed = 0.3f;

        [SerializeField]
        private Color _lightColor = new Color(1.0f, 0.0f, 0.0f, 0.5f);


        private Camera _camera;

        private void OnEnable()
        {
            _camera = GetComponent();
            _camera.depthTextureMode |= DepthTextureMode.Depth;
            material.SetFloat("_LightWidth", _lightWidth);
            material.SetFloat("_Speed", _speed);
            material.SetColor("_LightColor", _lightColor);
            UnityEngine.Object.Destroy(this, 1f / _speed);//扫描一次后销毁脚本
        }

        protected override void OnDisable()
        {
            _camera.depthTextureMode &= ~DepthTextureMode.Depth;
            base.OnDisable();
        }

        void OnRenderImage(RenderTexture source, RenderTexture destination)
        {
            Graphics.Blit(source, destination, material, 0);
        }
    }
}

 

 

你可能感兴趣的:(shader,Linear01Depth,shader,scan,扫描)