Unity 获得Transparent材质的深度纹理

来源:互联网 发布:酷友网络开发怎么样 编辑:程序博客网 时间:2024/06/05 11:18

最近 做的项目中 需要获得海水的深度信息 

正常获得信息的步骤是设置camera.depthTextureMode = DepthTextureMode.Depth; 然后在shader中声明_CameraDepthTexture 通过half rDepth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv);
rDepth = Linear01Depth(rDepth); 获得【0,1】区间的深度值

但是海水使用的是Transparent渲染队列 默认的camera深度纹理_CameraDepthTexture是不会将队列>2500的材质写进深度纹理的

仔细再网上查了一下 写一下思路

1.写自定义的深度获取shader

2.代码中使用RenderWithShader 对指定类型的shader替换为深度获取shader

3.获得渲染纹理数据


1.具体代码

Shader "Custom/CopyDepth" {
Properties{
_MainTex("", 2D) = "white" {}
_Cutoff("", Float) = 0.5
_Color("", Color) = (1,1,1,1)
}


SubShader{
Tags{ "RenderType" = "Transparent" }//需要替换的渲染类型 可以将此类型设置为你需要获取深度纹理材质的类型 这里我用的是Transparent
CULL Off
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_POSITION;
float4 nz : TEXCOORD0;
};
v2f vert(appdata_base v)
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.nz.xyz = COMPUTE_VIEW_NORMAL; //该点的法线信息
o.nz.w = COMPUTE_DEPTH_01;//该点的深度信息
return o;
}


fixed4 _Color;
fixed4 frag(v2f i) : SV_Target
{
//clip(_Color.a-0.01);
return EncodeDepthNormal(i.nz.w, i.nz.xyz);
}
ENDCG
}
}
SubShader{
Tags{ "RenderType" = "Opaque" }
CULL Off
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_POSITION;
float4 nz : TEXCOORD0;
};
v2f vert(appdata_base v)
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.nz.xyz = COMPUTE_VIEW_NORMAL; //该点的法线信息
o.nz.w = COMPUTE_DEPTH_01;//该点的深度信息
return o;
}


fixed4 _Color;
fixed4 frag(v2f i) : SV_Target
{

return EncodeDepthNormal(i.nz.w, i.nz.xyz);
}
ENDCG
}
}
//Fallback "Diffuse"
}

2.

Camera depthCam;
        if (depthCamObj == null)
        {
            depthCamObj = new GameObject("DepthCamera");
            depthCamObj.AddComponent<Camera>();
            depthCam = depthCamObj.GetComponent<Camera>();
            depthCam.enabled = false;
            // depthCamObj.hideFlags = HideFlags.HideAndDontSave;
        }
        else
        {
            depthCam = depthCamObj.GetComponent<Camera>();
        }


        depthCam.CopyFrom(mCam);
        depthTexture = RenderTexture.GetTemporary(mCam.pixelWidth, mCam.pixelHeight, 16, RenderTextureFormat.ARGB32);
        depthCam.backgroundColor = new Color(0, 0, 0, 0);
        depthCam.clearFlags = CameraClearFlags.SolidColor;
        //depthCam.depthTextureMode = DepthTextureMode.Depth;
        depthCam.targetTexture = depthTexture; //上面shader中获取到的深度信息保存在depthTexture中
        depthCam.RenderWithShader(mCopyShader, "RenderType");

3.

Shader "Unlit/RealCamera"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_DepthTex("Texture", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100


Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog

#include "UnityCG.cginc"


struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};


struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
float4 scrPos: TEXCOORD1;
};


sampler2D _MainTex;
sampler2D _DepthTex;
uniform sampler2D _CameraDepthTexture;
float4 _MainTex_ST;

v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.scrPos = ComputeScreenPos(o.vertex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}

fixed4 frag (v2f i) : SV_Target
{
// sample the texture
//fixed depth = Linear01Depth(tex2D(_DepthTex, i.uv).r);


float depth;
float3 normal;
DecodeDepthNormal(tex2D(_DepthTex, i.uv), depth, normal); //该函数将深度纹理中的深度信息和法线信息存储到depth 和normal中



half rDepth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv);//正常对于非transparent取深度信息
rDepth = Linear01Depth(rDepth);
fixed4 col = fixed4(rDepth, rDepth, rDepth, 1);
//col = tex2D(_CameraDepthTexture, i.uv);
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
ENDCG
}
}
Fallback "Diffuse"
}

后续上传工程

demo使用的是unity5.5.2 地址

http://download.csdn.net/detail/maxiaosheng521/9820251

0 0