2

我在将世界坐标移动到 ndc 坐标时遇到问题,而不是用它计算一些东西并将其移回着色器内。

代码如下所示:

vec3 testFunc(vec3 pos, vec3 dir){
    //pos and dir are in worldspace, convert to NDC
    vec4 NDC_dir = MVP * vec4(dir,0);
    vec4 NDC_pos = MVP * vec4(pos,1);
    NDC_dir /= NDC_dir.w;
    NDC_pos /= NDC_pos.w;

    //... do some caclulations => get newPos in NDC 

    //Transform newPos back to worldspace
    vec4 WS_newPos = inverse(MVP) * vec4(newPos,1);
    return WS_newPos.xyz / Ws_newPos.w;
}

我在测试时发现,虽然 NDC_dir.x 和 NDC_dir.y 似乎是合理的,但 NDC_dir.w 和 NDC_dir.z 总是几乎相等。因此,除以“w”时,z 值始终约为 1。我认为这不应该是正确的吗?(与 NDC_pos 相同)。

另一方面,当我将“pos”转换为 NDC 并将其转换回 Worldspace(没有任何计算)时,它似乎得到了原始点,这实际上意味着转换是正确的。

谁能告诉我我在这里做错了什么,如果没有,为什么 z 值总是 1?

更新: 这有点尴尬。我有两个问题:1. 一个是@Arne 指出的方向问题。另一个只是我这边的缩放问题。我有一个非常小的近夹子和一个大的远夹子。由于该值是对数的,我只需分两步就可以实现 z 值实际上是从 -1 变为 1。

4

1 回答 1

1

我在测试时发现,虽然 NDC_dir.x 和 NDC_dir.y 似乎是合理的,但 NDC_dir.w 和 NDC_dir.z 总是几乎相等。因此,除以“w”时,z 值始终约为 1。我认为这不应该是正确的吗?(与 NDC_pos 相同)。

其实是的,应该是这样的。如果您的输入是这样形成的,{x,y,z,0}那么它将被解释为在 {x,y,z} 方向上无限远的点。因此,深度分量应该始终是最远的,如果完全可见的话。顺便说一句,无限远的点仍然是平移不变的

但是您应该知道,无限远的点可能不是您在 NDC 中想要的。

3D 空间中的向量对平移是不变的,它只是保持相同的向量,因为向量只有方向,没有位置。这在扭曲的 NDC 中是不可能的。

如果要变换一个向量,最好先变换两个点,然后再取NDC中的差值。但是你应该知道你的结果取决于位置。

于 2015-11-24T15:36:27.250 回答