Shader入门(二十四)相机深度纹理

发表于2018-02-02
评论0 3.3k浏览
下面这篇文章主要和大家介绍相机深度纹理,相机可以生成深度和深度法线纹理,以及运动向量纹理(需要Unity5.4以上)。我们可以使用这些纹理来实现屏幕后处理效果。

当你需要某种纹理的时候,可以为Camera的depthTextureMode添加以下变量:

DepthTextureMode.Depth深度纹理

DepthTextureMode.DepthNormals一个包含深度和视图空间法线的纹理


例如:

using UnityEngine;  
using System.Collections;  
[RequireComponent(typeof(Camera))]  
public class TestDepth : MonoBehaviour {  
    private Material _mat;  
    // Use this for initialization  
    void Start () {  
        Camera cam = GetComponent<Camera> ();  
        cam.depthTextureMode |= DepthTextureMode.Depth;  
        Shader shader = Shader.Find ("Custom/TestDepth");  
        if (null != shader) {  
            _mat = new Material (shader);  
        }  
    }  
    void OnRenderImage(RenderTexture source, RenderTexture destination)  
    {  
        if (null != _mat) {  
            Graphics.Blit (source, destination, _mat);  
        } else {  
            Graphics.Blit (source, destination);  
        }  
    }  
}  


深度会被保存在_CameraDepthTexture中,可以通过uv坐标来获取贴图中的值,然后使用UNITY_SAMPLE_DEPTH宏来转换为深度。

float2 uv = i.uv;  
   float depth = UNITY_SAMPLE_DEPTH(tex2D(_CameraDepthTexture, uv));  

需要注意的是,深度纹理使用了与阴影投射(shadow caster)相同的Shader pass,所以如果一个对象不支持阴影投射,那么它将不会出现在深度纹理当中,并且只有RenderQueue小于等于2500的对象才能被渲染到深度纹理当中去。


而使用DepthTextureMode.DepthNormals时,我们可以获取深度法线纹理:_CameraDepthNormalTexture。Unity将法线编码到R和G通道里,而深度编码到B和A通道里。

我们可以通过DecodeDepthNormal方法获取深度和法线:

float2 uv = i.uv;  
   half depth;  
   half3 norm;  
   DecodeDepthNormal(tex2D(_CameraDepthNormalTexture, uv), depth, norm);  

使用深度法线纹理,我们可以实现边缘检测等图像效果(可能会在后续文章中介绍)。

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引