Unity3d的深度图可以实现一些神奇的效果,关键之处仅三行代码
- _CameraDepthTexture//Unity3d提供给我们的深度图
- float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,uv);//按uv坐标获取_CameraDepthTexture中的深度
- depth = Linear01Depth(depth);//深度线性到01范围
有了深度,我们可以模仿扫描仪的效果去扫描场景,效果如下:
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>();
_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);
}
}
}