Unity Shader CG语言中,SAMPLE_DEPTH_TEXTURE源码
时间: 2024-03-14 21:46:18 浏览: 311
以下是Unity Shader中使用CG语言实现SAMPLE_DEPTH_TEXTURE的示例代码。
在vertex shader中,我们需要将顶点坐标和投影矩阵相乘得到裁剪坐标,然后将裁剪坐标传递给fragment shader。
```
v2f vert (appdata_base v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
return o;
}
```
在fragment shader中,我们首先需要从深度纹理中采样得到深度值,然后将其转换为线性深度值。转换方法可以根据具体场景进行调整。接着,我们可以根据深度值计算出该像素的位置,并将该位置作为颜色输出。
```
half4 frag (v2f i) : SV_Target
{
float depth = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UNITY_PROJ_COORD(i.vertex)).r);
float linearDepth = 2.0 * _ZBufferParams.w / (_ZBufferParams.y + _ZBufferParams.x - depth * (_ZBufferParams.y - _ZBufferParams.x));
float4 clipPos = float4(ComputeGrabScreenPos(i.vertex.xy, linearDepth), linearDepth, 1.0);
float4 viewPos = mul(_InvProjMatrix, clipPos);
viewPos /= viewPos.w;
return float4(viewPos.xyz, 1.0);
}
```
注意,这里我们还需要使用Unity提供的函数Linear01Depth将深度值从非线性转换为线性。同时,我们需要使用_ZBufferParams和_InvProjMatrix这两个Unity内置的变量来进行后续计算。
最后,在主程序中,我们需要将深度纹理绑定到对应的纹理单元,并将投影矩阵和_ZBufferParams传递给shader。
```
Shader "Custom/DepthShader" {
Properties {
_MainTex ("Texture", 2D) = "white" {}
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 100
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _CameraDepthTexture;
float4 _ZBufferParams;
float4x4 _InvProjMatrix;
struct appdata_base {
float4 vertex : POSITION;
};
struct v2f {
float4 vertex : SV_POSITION;
};
v2f vert (appdata_base v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
return o;
}
half4 frag (v2f i) : SV_Target
{
float depth = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UNITY_PROJ_COORD(i.vertex)).r);
float linearDepth = 2.0 * _ZBufferParams.w / (_ZBufferParams.y + _ZBufferParams.x - depth * (_ZBufferParams.y - _ZBufferParams.x));
float4 clipPos = float4(ComputeGrabScreenPos(i.vertex.xy, linearDepth), linearDepth, 1.0);
float4 viewPos = mul(_InvProjMatrix, clipPos);
viewPos /= viewPos.w;
return float4(viewPos.xyz, 1.0);
}
ENDCG
}
}
FallBack "Diffuse"
}
```
注意,我们需要使用Unity内置的宏UNITY_PROJ_COORD来将裁剪坐标转换为纹理坐标。另外,由于_CameraDepthTexture是Unity自动渲染深度纹理的结果,因此无需手动绑定纹理。
阅读全文