ios - Metal + ARKit — 在片段着色器中获取到当前片段的 z 距离
问题描述
我有一个金属着色器(SCNProgram
为 ARKit 应用程序编写),它获取从smoothedSceneDepth
. 我想使用捕获的深度信息来丢弃位于现实世界对象后面的任何虚拟对象的部分。但是,我无法在我的着色器中获得预期的片段深度。
这是我的基本片段着色器:
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);
时,红色在我最接近对象时最亮,然后在我后退时下降。即使我使用fragDepth = 1 - fragDepth
,深度似乎也不同lidarDepth
。
这里使用1 - fragDepth
:
(我也尝试使用此答案中的映射,但无法使其正常工作)
所以我的问题是:
在什么坐标系
in.position.z
中?如何转换
in.position.z
为可以与已有的捕获深度信息进行比较的深度值?(或相反亦然)
解决方案
好的,我还没有完全说服自己以下解决方案是正确的,但它似乎适用于我非常基本的应用程序:
在顶点着色器中,我写出眼睛空间中的位置:
// 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
没有使用(或者如果我在这里的解决方案有一些问题,请更正)
推荐阅读
- xml - 需要使用 XSLT 将日期格式更改为字符串
- node.js - 无法创建连接 socket.io
- build - 如何在没有完整的 aosp 源代码的情况下构建供应商模块
- php - Livewire:无法调用组件方法。在组件上找不到公共方法 [childMethodName]:[父]
- html - 如何在我的 html 页面中添加 Matplotlib 实时图表?
- c++ - 为什么在表达式解析器中的 `TokPrec < NextPrec` 时运算符优先级必须增加 1?
- acumatica - Acumatica - 案例状态组合框
- ruby - Chef - 将模板 erb 与数组一起使用
- python - 使用三个通道重塑张量时 Numpy 数组尺寸不匹配
- flutter - 颤振计时器问题