Unity获取深度图

unityshader中可以通过直接对_CameraDepthTexture采样的方式,获取Camera生成图像的深度,甚至对这个纹理的采样,都已经有了封装好的函数SampleSceneDepth,源码可见

https://github.com/Unity-Technologies/Graphics/blob/master/Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl

使用SampleSceneDepth时,需要include它的源文件

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

使用样例

half4 frag(Varyings IN) : SV_Target
{                
    // To calculate the UV coordinates for sampling the depth buffer,
    // divide the pixel location by the render target resolution
    // _ScaledScreenParams.
    float2 UV = IN.positionHCS.xy / _ScaledScreenParams.xy;

    // Sample the depth from the Camera depth texture.
    #if UNITY_REVERSED_Z
        real depth = SampleSceneDepth(UV);
    #else
        // Adjust Z to match NDC for OpenGL ([-1, 1])
        real depth = lerp(UNITY_NEAR_CLIP_VALUE, 1, SampleSceneDepth(UV));
    #endif


    return depth;
}

写好该采样深度的shader后,在renderfeature中使用该shader的material对相机图像进行处理,即可得到深度图

注意这里根据相机图像大小生成一张临时的texture,若直接使用固定的大小的texture,则可能只在相机的rendertarget上渲染出一小部分,并不能获取整张图像的深度图

RenderTexture temporaryRT = RenderTexture.GetTemporary(windowSize.x, windowSize.y);
cmd.Blit(source, temporaryRT, settings.blitMaterial);
cmd.Blit(temporaryRT, source);

这里采样得到的depth是(0,1)范围的值

对该深度图进行采样时,将坐标转换到NDC后,将坐标变换到(0,1)的范围

float3 pos = ndcSpacePos.xyz * 0.5 + 0.5;

然后用pos.xy作为uv,对深度图进行采样,采样后得到该点的深度值depth

若要再将该点坐标转换到其他空间,需要先将坐标值转化到ndc中(有点疑问,为什么depth不需要也变换到(-1,1),unity默认的ndc的z坐标为(0,1)吗?)

float3 ndcPos = float3(2 * pos.xy - 1, depth);

得到ndc坐标后,便可用空间变换矩阵对该点坐标进行空间变换了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值