从对象空间坐标

时间:2016-03-02 18:27:07

标签: opengl

任何人都可以解释一下为了从对象空间坐标生成NDC所执行的步骤是什么,下面的示例。

    float vertices[] = {
 -2.0f, -12.0f,
 2.0f, -12.0f,
-2.0f, 12.0f, 
 2.0f, 12.0f
    };

这是我的mvp矩阵:

        float MVP[16] = {

         0.993,  0.054, -0.102, -0.102,
 0.007,  0.852,  0.524,  0.524,
-0.115,  0.521, -0.846, -0.846,
0.575, -2.604,  4.061,  4.260 };

根据我的计算,我得到:

X,Y,Z,W:

0.824918 7.111959 1.110172 1.000000
-1.111003 5.714332 1.090060 1.000000
-0.123152 0.698949 0.981588 1.000000
0.256286 0.747339 0.980855 1.000000

但那些都是错的。错误的意思是,如果我这样做:

         vec4 vert =  mvp * vec4(inPos.x,inPos.y,0,1);
        vert.xyzw/=vert.w;
        gl_Position = vert;
在VS中,我获得了不同的o / p:

         vec4 vert =  mvp * vec4(inPos.x,inPos.y,0,1);
        gl_Position = vert;

1 个答案:

答案 0 :(得分:1)

首先,我不能完全重现你得到的数字。也许你在问题中舍入了矩阵元素。我得到的值是:

V0: [0.819627 7.09211 1.1091 1]
V1: [-1.10977 5.69893 1.08916 1]
V2: [-0.123419 0.698661 0.981492 1]
V3: [0.255704 0.7471 0.980762 1]

然而,问题还有别处。当您查看这些点的剪辑空间坐标时,您会得到:

V0: [-1.495 -12.936 -2.023 -1.824]
V1: [2.477 -12.72 -2.431 -2.232]
V2: [-1.327 7.512 10.553 10.752]
V3: [2.645 7.728 10.145 10.344]

注意几件事: 观察体积受到剪辑空间中的不等式-w <= x,y,z <= w的限制。 V0和V1的坐标不满足该不等式。所以这些点位于观看视锥体之外。通常,GL将剪切部分位于观看体积内外的图元。

剪辑本身不是问题。请注意,V0和V1的w组件实际上是否定。这意味着那些点位于投影中心(=虚拟摄像机)后面。通过将它们除以w,您可以将这些点镜像回相机前面的 。相机后面的点的NDC坐标在xy z 中进行镜像,跳过剪切步骤将导致完全错误的基元情况。

GL将永远不会出现此问题,因为剪辑将在剪辑空间中完成,然后才能完成分割。如果你想要有意义的NDC坐标,你还必须实现自己的剪辑。但是,在顶点着色器中几乎无法完成此操作(除非您绘制的所有内容都是单独的点)。对于线性或三角形原始,您需要所有顶点的数据来计算基本边缘和剪切平面之间的交集,并且您可能必须动态创建新的基元。

这也意味着对于位于投影中心后面的点,根本没有有意义的NDC坐标。例如,考虑一个三角形,其中两个顶点位于摄像机前面,内部很好视图体积,第三个顶点位于相机后面。剪切将在从第三个点到其他边缘的每个边缘上创建一个新点(并将生成两个三角形替换原始三角形)。这两个新点确实具有有意义的NDC坐标,但第三个原点从未有过 - 并且第三个输入点与新创建的点之间也没有1:1映射。