C++ OpenGL投影/矩阵混淆

C++ OpenGL投影/矩阵混淆,c++,opengl,glsl,shader,C++,Opengl,Glsl,Shader,我试图投影一个点的法线,并根据它(从相机/观察平面的角度)向左倾斜或向右倾斜来给它上色 要做到这一点,我将点取为法线,并将其乘以gl_ModelViewProjectionMatrix,然后检查它是否具有正x值或负x值。然而,我所有的点都变成红色(表示垂直线的左边,这绝对不是事实)。如果我将ModelViewProjectionMatrix更改为gl_ProjectionMatrix,我会得到红色和绿色的点,但是如果没有ModelViewMatrix,从摄影机的角度看,它们显然没有颜色 我是不是

我试图投影一个点的法线,并根据它(从相机/观察平面的角度)向左倾斜或向右倾斜来给它上色

要做到这一点,我将点取为法线,并将其乘以gl_ModelViewProjectionMatrix,然后检查它是否具有正x值或负x值。然而,我所有的点都变成红色(表示垂直线的左边,这绝对不是事实)。如果我将ModelViewProjectionMatrix更改为gl_ProjectionMatrix,我会得到红色和绿色的点,但是如果没有ModelViewMatrix,从摄影机的角度看,它们显然没有颜色

我是不是误解了什么

着色器示例:

void main(){
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

    vec4 temp = vec4(vNormal.x, vNormal.y, vNormal.z, 1);
    vMajorTransformed = gl_ModelViewProjectionMatrix * temp;

    if (vMajorTransformed.x < 0) {
        gl_FrontColor = vec4(1, 0, 0, 1);
    } else {
        gl_FrontColor = vec4(0, 1, 0, 1);
    }

    gl_PointSize = 3;
}
void main(){
gl_位置=gl_模型视图投影矩阵*gl_顶点;
vec4 temp=vec4(vNormal.x,vNormal.y,vNormal.z,1);
VmajortTransformed=gl_ModelViewProjectionMatrix*温度;
if(VmajortTransformed.x<0){
gl_FrontColor=vec4(1,0,0,1);
}否则{
gl_FrontColor=vec4(0,1,0,1);
}
gl_PointSize=3;
}

法线是方向,而不是点。这意味着其
w
组件应为0。否则,您可能会对其应用一个平移,这肯定会弄乱
x,y,z
坐标(我猜您的情况就是这样)

还请注意,如果modelview矩阵包含旋转和平移以外的任何内容,法线将再次混乱。它们必须通过逆转置来转换。反转和转置在仅旋转矩阵上抵消,但对于其他变换,必须使用它们


您可能不想对它们应用投影-您正在进行的测试(
x
coordinate)可以在摄影机坐标(通常比投影空间更容易推理)中进行评估。

我可以问一下,为什么要将法线转换为剪辑空间(通过包含投影矩阵)?通常,如果要在片段着色器中使用法线进行照明计算,则要将法线带入视图空间的距离最远。如果在任何方向上具有非均匀缩放,则可能还希望避免使用ModelView矩阵变换法线,有一个特殊的3x3子矩阵,通过逆转置计算,即使在这种情况下,也可以正确变换法线。这是我对我试图做的事情的误解-我想我需要剪辑空间生成坐标。逆(转置(gl_ModelViewMatrix))?看起来很有效。我不知道-我要花更多的时间在我的欧几里德几何上-谢谢。顺便说一句,因为您在这里使用的是GLSL的旧版本,它仍然支持旧的固定函数矩阵内置,GL已经为您计算了法线矩阵。它被称为
gl_NormalMatrix
,与
gl_ModelViewMatrix
的不同之处在于,它是3x3-如果乘以该矩阵,则无需创建4D向量或担心W变换法线。(例如,
vmajorttransformed=gl_NormalMatrix*vNormal
,假设
vmajorttransformed
vec3
)。