Unity 深度图片获取

1、  在Unity中,要得到深度缓存(Depthbuffer),就需要用到一个RenderTexture纹理。

2、  深度缓存,或者深度纹理,其实就是一个包含有场景里物体离照相机的距离值的一张纹理图。

3、  为了让摄像机生成一张深度纹理,只需要设置Camera.depthTextureMode即可。但这个时候生成了纹理,还需要我们去获取。所以我们需要把它传到一个shader中,于是就用到OnRenderImage这个函数。

 

于是我们得出下面一个例子:

using UnityEngine;
using System.Collections;

//so that we can see changes we make without having to run the game

[ExecuteInEditMode]
public class PostProcessDepthGrayscale : MonoBehaviour {

   public Material mat;

   void Start () {
//设置Camera的depthTextureMode,使得摄像机能生成深度图。
      Camera.main.depthTextureMode = DepthTextureMode.Depth;
   }

   void OnRenderImage (RenderTexture source, RenderTexture destination){
      Graphics.Blit(source,destination,mat);
      //mat就是包含shader的一个材质球,而这个shader就是我们要把
             //destination这个render纹理传进去的shader。Shader的写法如下所示。
   }
}


 

接下来这个shader代码如下:

Shader "Custom/DepthGrayscale" {
SubShader {
Tags { "RenderType"="Opaque" }

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

sampler2D _CameraDepthTexture;

struct v2f {
   float4 pos : SV_POSITION;
   float4 scrPos:TEXCOORD1;
};

//Vertex Shader
v2f vert (appdata_base v){
   v2f o;
   o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
   o.scrPos=ComputeScreenPos(o.pos);
   //for some reason, the y position of the depthtexture comes out inverted
   //o.scrPos.y = 1 - o.scrPos.y;
   return o;
}

//Fragment Shader
half4 frag (v2f i) : COLOR{
   float depthValue =Linear01Depth (tex2Dproj(_CameraDepthTexture,UNITY_PROJ_COORD(i.scrPos)).r);
   half4 depth;

   depth.r = depthValue;
   depth.g = depthValue;
   depth.b = depthValue;

   depth.a = 1;
   return depth;
}
ENDCG
}
}
FallBack "Diffuse"
}


 

前面都好理解,而且需要注意的是,_CameraDepthTexture这个变量的值是Unityshader内部传进去的。

float depthValue =Linear01Depth (tex2Dproj(_CameraDepthTexture,UNITY_PROJ_COORD(i.scrPos)).r);

Linear01Depth这个是将其中的值转换成深度的01之间的值,tex2Dproj采样得到的颜色值为何只取r值,而且取gb值是全黑的。这需要再考虑一下。(对于这个问题,现测得RenderTexture如果它的Format改成Depth的话,就只有红色这一个通道颜色了。所以会出现上面的这个情况。)

而且,这里的深度是受RenderQueue的值的影响,并不只z轴坐标。比如你的RenderQueue=3000,但是z轴坐标离摄像机很近,那它的深度值也是很大的。得到一幅深度图如下图:


可见,离摄像机越近,深度越小,颜色值越深。

你可能感兴趣的:(Unity)