启用深度图

URP

在URP中,默认启用深度图,可在渲染管线资产中修改。

Built-In

在Built-In中,深度图默认不启用,需要使用C#显式开启:

CS
Camera cam = GetComponent<Camera>();
cam.depthTextureMode |= DepthTextureMode.Depth;
枚举 解释
DepthTextureMode.None 不生成任何纹理(默认)
DepthTextureMode.Depth 生成深度纹理
DepthTextureMode.DepthNormals 生成深度 + 法线纹理
DepthTextureMode.MotionVectors 指定是否应渲染运动矢量(如果可能)

采样内容

采样深度图,获取深度图中的原始值。

URP

法一:使用库函数

引入库 这个库文件很轻量,只有一个纹理、采样器声明和两个简单函数,可以放心使用。

HLSL
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"

采样深度图

HLSL
float rawDepth = SampleSceneDepth(uv);

法二:手动采样

声明纹理和采样器

HLSL
TEXTURE2D_X_FLOAT(_CameraDepthTexture);
SAMPLER(sampler_CameraDepthTexture);

采样深度图

HLSL
float rawDepth = SAMPLE_TEXTURE2D_X(_CameraDepthTexture, sampler_CameraDepthTexture, uv).r;

Built-In

声明纹理采样器

HLSL
sampler2D _CameraDepthTexture;

采样深度图

HLSL
float rawDepth = tex2D(_CameraDepthTexture, uv).r;
float rawDepth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); // HLSL

使用HLSL时可以使用宏SAMPLE_DEPTH_TEXTURE,其原理与使用tex2D没区别。


线性化处理

从深度图中采样到的值是NDC的Z映射到01的值,它在透视投影下是非线性的,故在透视投影下需要对其进行线性化处理。具体原理:-> {{< link title=“线性深度值计算” url="/posts/490808ae" icon="/favicon.ico" >}}

Linear01Depth

HLSL
float depth = Linear01Depth(rawDepth, _ZBufferParams);

将深度值转换到线性的[0, 1]空间:

  • 值趋近 0 时,物体在近裁剪平面处;
  • 值趋近 1 时,物体在远裁剪平面处。

LinearEyeDepth

HLSL
float depth = LinearEyeDepth(rawDepth, _ZBufferParams);

将原始深度值转换到视图空间下的深度(物体相对于摄像机的视图空间 Z 坐标)

: Cheyne Xie

: https://chaim.eu.org/posts/c85e65cb/

: CC BY-NC-SA 4.0

This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. Please attribute the source, use non-commercially, and maintain the same license.