关于opengl:转换为NDC,计算并转换回世界空间

Transform to NDC, calculate and transform back to worldspace

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

该代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
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(不进行任何计算)时,似乎获得了原始Point,这实际上意味着转换是正确的。

有人可以告诉我我在这里做错什么吗?如果没有,为什么z值总是1?

更新:
这有点尴尬。我有两个问题:1. @Arne指出了方向问题。另一个只是我这方面的扩展问题。我有一个很小的近端剪辑和一个很大的远段剪辑。由于该值是对数的,因此我仅作了两步就意识到z值实际上从-1变为1。


What I found when testing is, that whilte the NDC_dir.x and NDC_dir.y seem to be reasonable, the NDC_dir.w and NDC_dir.z are always almost equal. Therefor when dividing by"w" the z-Value is always about 1. I dont think this is how it should be right? (Same for NDC_pos).

确实是的,这应该是这样。 如果输入形式为{x,y,z,0},则它将被解释为在{x,y,z}方向上无限远的点。 因此,深度分量应始终保持最远的距离(如果完全可见)。 顺便说一下,无限远的点仍然是平移不变的

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

3D空间中的向量对于平移而言是不变的,只是保持相同的向量,因为向量仅具有方向,而没有位置。 在失真的NDC中这实际上是不可能的。

如果要变换向量,则最好变换两个点,然后再次求和NDC。 但是您应该知道结果取决于位置。