SceneDepth_Effect.shader
Shader "Custom/SceneDepth_Effect" { Properties { _MainTex ("Base (RGB)", 2D) = "white" {} _DepthPower ("Depth Power", Range(1, 5)) = 1 } SubShader { Pass { CGPROGRAM #pragma vertex vert_img #pragma fragment frag #pragma fragmentoption ARB_precision_hint_fastest #include "UnityCG.cginc" uniform sampler2D _MainTex; fixed _DepthPower; sampler2D _CameraDepthTexture; fixed4 frag(v2f_img i) : COLOR { float d = UNITY_SAMPLE_DEPTH( tex2D(_CameraDepthTexture, i.uv.xy) ); d = pow(Linear01Depth(d), _DepthPower); return d; } ENDCG } } FallBack "Diffuse" }
UNITY_SAMPLE_DEPTH()函数会从_CameraDepthTexture中获得深度值并且为每个像素产生一个单精度的浮点值。
Linear01Depth()函数会确保深度值在0到1之间。
TestRenderImage.cs
using UnityEngine; using System.Collections; [ExecuteInEditMode] public class TestRenderImage : MonoBehaviour { public Shader curShader; private Material curMaterial; public float depthPower = 1.0f; Material material { get { if(curMaterial == null) { curMaterial = new Material(curShader); curMaterial.hideFlags = HideFlags.HideAndDontSave; } return curMaterial; } } void Start () { if(!SystemInfo.supportsImageEffects) { enabled = false; return; } if(null != curShader && !curShader.isSupported) { enabled = false; } } //对屏幕后期处理 void OnRenderImage(RenderTexture sourceTexture, RenderTexture destTexture) { if (curShader != null) { material.SetFloat("_DepthPower", depthPower); Graphics.Blit (sourceTexture, destTexture, material); } else { Graphics.Blit (sourceTexture, destTexture); } } void Update () { //开启Unity内置的深度模式来获取当前游戏中所有对象的深度。 //一旦开启了深度模式,我们就可以利用这些深度信息实现很多不同的效果。 Camera.main.depthTextureMode = DepthTextureMode.Depth; depthPower = Mathf.Clamp (depthPower, 0f, 5); } void OnDisable() { if (curMaterial) DestroyImmediate (curMaterial); } }
运行测试