繁体   English   中英

Metal + ARKit — 在片段着色器中获取到当前片段的 z 距离

[英]Metal + ARKit — Get z distance to current fragment in fragment shader

我有一个金属着色器(作为SCNProgram应用程序的 SCNProgram 编写),它采用从 smoothedSceneDepth 捕获的当前场景的深度smoothedSceneDepth 我想使用捕获的深度信息来丢弃位于真实世界 object 后面的任何虚拟对象的部分。 但是,我无法在我的着色器中获得预期的片段深度。

这是我的基本片段着色器:

struct ColorInOut {
    float4 position [[ position ]];
    float2 depthTexCoords;
};

fragment float4 fragmentShader(
    const ColorInOut in [[ stage_in ]],
    depth2d<float, access::sample> sceneDepthTexture [[ texture(1) ]]
) {
    constexpr sampler textureSampler(mag_filter::linear, min_filter::linear);
    
    // Closest = 0.0m, farthest = 5.0m (lidar max)
    // Seems to be in meters?
    const float lidarDepth = sceneDepthTexture.sample(textureSampler, in.depthTexCoords);
 
    float fragDepth = // ??? somehow get z distance to the current fragment in meters ???

    // Compare the distances
    const float zMargin = 0.1
    if (lidarDepth < fragDepth - zMargin) {
         discard_fragement()
    }

    ...
}

我的理解是片段着色器中的position.z应该在最接近 = 0 到最远 = 1 的范围内。 但是,当我尝试使用当前的相机平面将其转换回现实世界的距离时,结果似乎不对:

const float zNear = 0.001;
const float zFar = 1000;

float fragDepth = in.position.z * (zFar - zNear);

当我使用return float4(fragDepth, 0, 0, 1);调试着色器时 ,当我最靠近 object 时,红色最亮,然后在我后退时消失。 即使我使用fragDepth = 1 - fragDepth ,深度似乎也与lidarDepth不同。

这里使用1 - fragDepth

使用 1 - fragDepth

(我也尝试使用此答案中的映射,但无法使其正常工作)

所以我的问题是:

  • in.position.z在什么坐标系中?

  • 如何将in.position.z转换为可以与我已经拥有的捕获的深度信息进行比较的深度值? (或相反亦然)

好的,我还没有完全说服自己以下解决方案是正确的,但它似乎适用于我非常基本的应用程序:

在顶点着色器中,我在眼睛空间中写出 position:

// in vertex shader
out.fragEyePosition = scn_node.modelViewTransform * float4(in.position, 1.0);

在片段着色器中,我可以使用-in.fragEyePosition.z进行深度测试:

// in fragment shader

float depth = -in.fragEyePosition.z;

const float zMargin = 0.1;
if (lidarDepth - depth < -zMargin) {
    discard_fragment();
}

...

我很感激解释为什么这有效以及为什么我之前使用.position的尝试没有(或者如果我在这里的解决方案有一些问题,请更正)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM