启用深度图
URP
在URP中,默认启用深度图,可在渲染管线资产中修改。
Built-In
在Built-In中,深度图默认不启用,需要使用C#显式开启:
Camera cam = GetComponent<Camera>();
cam.depthTextureMode |= DepthTextureMode.Depth;| 枚举 | 解释 |
|---|---|
| DepthTextureMode.None | 不生成任何纹理(默认) |
| DepthTextureMode.Depth | 生成深度纹理 |
| DepthTextureMode.DepthNormals | 生成深度 + 法线纹理 |
| DepthTextureMode.MotionVectors | 指定是否应渲染运动矢量(如果可能) |
采样内容
采样深度图,获取深度图中的原始值。
URP
法一:使用库函数
引入库 这个库文件很轻量,只有一个纹理、采样器声明和两个简单函数,可以放心使用。
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"采样深度图
float rawDepth = SampleSceneDepth(uv);法二:手动采样
声明纹理和采样器
TEXTURE2D_X_FLOAT(_CameraDepthTexture);
SAMPLER(sampler_CameraDepthTexture);采样深度图
float rawDepth = SAMPLE_TEXTURE2D_X(_CameraDepthTexture, sampler_CameraDepthTexture, uv).r;Built-In
声明纹理采样器
sampler2D _CameraDepthTexture;采样深度图
float rawDepth = tex2D(_CameraDepthTexture, uv).r;
float rawDepth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); // HLSL使用HLSL时可以使用宏SAMPLE_DEPTH_TEXTURE,其原理与使用tex2D没区别。
线性化处理
从深度图中采样到的值是NDC的Z映射到01的值,它在透视投影下是非线性的,故在透视投影下需要对其进行线性化处理。具体原理:-> 线性深度值计算
Linear01Depth
float depth = Linear01Depth(rawDepth, _ZBufferParams);将深度值转换到线性的[0, 1]空间:
- 值趋近 0 时,物体在近裁剪平面处;
- 值趋近 1 时,物体在远裁剪平面处。
LinearEyeDepth
float depth = LinearEyeDepth(rawDepth, _ZBufferParams);将原始深度值转换到视图空间下的深度(物体相对于摄像机的视图空间 Z 坐标)