You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于gluProject与OpenGL裁剪的困惑:顶点Y坐标为何均超1080?

OpenGL固定变换管线中gluProject计算结果异常问题

问题背景

在OpenGL固定变换管线中,给定如下参数:

GL_MODELVIEW_MATRIX
0,175,303.109,0,688.503,-2741.84,1583,0,29.3148,5.52094,-3.18752,0,-87.4871,731.309,-1576.92,1
GL_PROJECTION_MATRIX
2.09928,0,0,0,0,3.73205,0,0,0,0,-1.00658,-1,0,0,-43.9314,0
GL_VIEWPORT
0,0,1920,1080

绘制单位立方体后,预期一半顶点的像素Y坐标大于1080,另一半为负值,但使用gluProject计算后,所有顶点的Y坐标均大于1080,计算结果如下:

model coordinate 0 0 0 -> screen coordinate 848.191 1474.61 0.989359
model coordinate 1 0 0 -> screen coordinate 821.586 1973.88 0.986045
model coordinate 0 1 0 -> screen coordinate -198317 667165 4.61719
model coordinate 1 1 0 -> screen coordinate -2957.48 12504.1 1.07433
model coordinate 0 0 1 -> screen coordinate 885.806 1479.77 0.989388
model coordinate 1 0 1 -> screen coordinate 868.195 1979.01 0.986088
model coordinate 0 1 1 -> screen coordinate -438501 1.39841e+06 8.60228
model coordinate 1 1 1 -> screen coordinate -3191.35 12592.4 1.07507

绘制立方体的代码:

glBegin(GL_QUADS);
for(int d = 0; d < 3; ++d)
    for(int s = 0; s < 2; ++s)
        for(int v = 0; v < 4; ++v)
        {
            const int a = (v & 1) ^ (v >> 1 & 1);
            const int b = v >> 1 & 1;

            const int d0 = d;
            const int d1 = (d + 1) % 3;
            const int d2 = (d + 2) % 3;

            double p[3];

            p[d] = s;
            p[d1] = a;
            p[d2] = b;

            glColor3dv(p);
            glVertex3dv(p);
        }
glEnd();

原因分析

所有顶点屏幕Y坐标均大于1080的核心原因是模型视图矩阵的变换完全改变了顶点在相机空间的位置,加上透视除法的符号影响,导致最终屏幕Y坐标全部超出视口上边界,具体拆解:

  1. 模型视图变换对顶点Y分量的影响
    OpenGL矩阵采用列主序,模型视图矩阵的Y平移分量为731.309,对单位立方体顶点(模型空间y∈{0,1})的变换结果:

    • 模型空间y=0的顶点:变换后相机空间Y分量为731.309或906.309(均为正数)
    • 模型空间y=1的顶点:变换后相机空间Y分量为-2010.53或-1835.53(均为负数)
  2. 透视除法的符号反转作用
    投影矩阵的最后一行决定了透视除法的w分量:w'' = -z'(z'为模型视图变换后的相机空间Z分量)。对于单位立方体顶点:

    • 模型空间y=0的顶点:z'为负数,w''为正数,透视除法后NDC-Y为正数,计算屏幕Y时screen_y = 540*(ndc_y +1),ndc_y均大于1.7,最终screen_y大于1458,远超1080。
    • 模型空间y=1的顶点:z'为正数,w''为负数,透视除法时负数除以负数得到正数NDC-Y,且因z'绝对值很小,NDC-Y绝对值极大,最终screen_y远大于1080。
  3. 预期错误的根源
    你错误地认为模型空间的y值与屏幕Y坐标的正负直接对应,但实际上模型视图矩阵的旋转、平移已经完全改变了顶点的相机空间位置,加上投影变换的非线性映射,模型空间的y值无法直接决定屏幕坐标的正负。

内容的提问来源于stack exchange,提问作者diegor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 16:45:54