OpenGL在管道中正好乘以哪些矩阵?

时间:2014-07-20 17:14:31

标签: opengl matrix vertex-shader

最后,我一直在组建一个OpenGL程序,并且我已经达到了我在转换矩阵(模型转换,相机转换和透视转换)中编码的程度。到目前为止,我一直在计算我的模型变换并发送到一个制服并在顶点着色器中乘以它。最近我将相机和透视变换添加到了着色器中发送到制服的矩阵。

但是现在,很多事情都没有起作用,还有一些我无法理解的事情:

首先,this webpage表示OpenGL会自动按位置的Z组件划分所有内容(用于透视变换),但我无法弄清楚这种情况发生在哪里,其次:

number resources mention个{{3}} OpenGL函数,如glFrustumf(),glMatrixMode(),glPushMatrix(),glPopMatrix(),glLoadIdentity(),gRotatef()所有这些函数似乎都在OpenGL中传递和修改矩阵,我根本不需要在顶点着色器中使用它们。

所以现在我完全迷失了如何在OpenGL中完成转换。我们自己计算它们并在顶点着色器中将它们相乘,还是我们将参数发送给OpenGL并让它完成API背后的所有工作,或其他完全不同的工作?

由于

2 个答案:

答案 0 :(得分:4)

Perspective Divison

通过ModelViewProjection矩阵转换顶点后,它们处于裁剪空间中。如果不将x,y和z分量除以w分量,则值在-w到w的范围内。超出该范围的所有内容都将被剪裁。

透视分割(除以w分量)使该范围为-1到1,称为“标准化设备坐标”。这是由OpenGL在顶点着色器输出gl_Position上自动完成的。这(如果我没记错的话)是为硬件完成的,这样所有后续计算都不必考虑变量范围。

固定与可编程管道

如果您使用制服将自己的转换传递给顶点着色器,那么您正在使用现代OpenGL管道(是的!)。这使您可以完全控制顶点的变换。

如果您正在使用已弃用的函数,例如glFrustumf(),glMatrixMode(),glPushMatrix(),glPopMatrix(),glLoadIdentity(),gRotatef()等,那么您正在使用旧的固定函数管道。

答案 1 :(得分:4)

glMatrixMode()用于指定您将在后续代码中操作的内置矩阵(即使用glTranslate(),glRotate()等)。常用参数为GL_MODELVIEW,GL_PROJECTION,分别表示模型视图矩阵和投影矩阵。

glFrustumf()用于指定您的相机视锥。在OpenGL中,截头锥体以外的任何东西都是不可见的,并且会被剔除,从而有助于节省大量的GPU周期。

谈到“除以Z”。它应该是“除以W”,是同质坐标的第四个组成部分。简而言之,在3D转换中,OpenGL使用4分量同质坐标(x,y,z,w)而不是(x,y,z)。变换矩阵,例如模型视图矩阵和投影矩阵都是4乘4矩阵。这样做的原因是,平移,旋转和透视投影等3D变换都可以用4x4矩阵乘法很好地表达。

您无需担心用w划分,无论是使用固定管道还是可编程GLSL管道。 OpenGL将为您处理它。如果您确实想知道它发生的位置,它会在将模型视图投影矩阵与顶点位置相乘后立即发生。在顶点着色器中,它发生在:

之后
gl_position=proj*view*model*vec4(in_vertex,1);

在管道中的某处,在顶点着色器和片段着色器之间。确切地说,在光栅化发生之前。除以w后,顶点坐标将转换为标准化设备坐标,其中由glFrustum()指定的平截头体内的所有3D对象的坐标在[-1,1] x [-1]内标准化。 ,1] x [-1,1]框。这使后续计算更容易。