Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
OpenGL在管道中与哪些矩阵相乘?_Opengl_Matrix_Vertex Shader - Fatal编程技术网

OpenGL在管道中与哪些矩阵相乘?

OpenGL在管道中与哪些矩阵相乘?,opengl,matrix,vertex-shader,Opengl,Matrix,Vertex Shader,在最后一段时间里,我一直在编写一个OpenGL程序,我已经达到了在变换矩阵(模型变换、相机变换和透视变换)中编码的程度。到目前为止,我一直在计算我的模型变换,并将其发送到一个统一的顶点着色器中,然后将其相乘。最近,我将摄影机和透视变换添加到矩阵中,该矩阵被发送到着色器中的统一体 但是现在,很多事情都不起作用,还有一些事情我不明白: 首先,OpenGL会自动用位置的Z分量(用于透视变换)划分所有内容,但我不知道在哪里会发生这种情况,其次: OpenGL函数中有许多函数,如glFrustumf()、

在最后一段时间里,我一直在编写一个OpenGL程序,我已经达到了在变换矩阵(模型变换、相机变换和透视变换)中编码的程度。到目前为止,我一直在计算我的模型变换,并将其发送到一个统一的顶点着色器中,然后将其相乘。最近,我将摄影机和透视变换添加到矩阵中,该矩阵被发送到着色器中的统一体

但是现在,很多事情都不起作用,还有一些事情我不明白:

首先,OpenGL会自动用位置的Z分量(用于透视变换)划分所有内容,但我不知道在哪里会发生这种情况,其次:

OpenGL函数中有许多函数,如glFrustumf()、glMatrixMode()、glPushMatrix()、glPopMatrix()、glLoadIdentity()、gRotatef()等。所有这些函数似乎都在OpenGL内部传递和修改矩阵,我根本不需要在顶点着色器中处理它们

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

谢谢

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

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

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

如果您使用的是不推荐使用的函数,如glFrustumf()、glMatrixMode()、glPushMatrix()、glPopMatrix()、glLoadIdentity()、gRotatef()等,那么您使用的是较旧的固定函数管道。

glMatrixMode()用于指定在后续代码中要操作的内置矩阵(即使用glTranslate()、glRotate()等)。常用的参数有GL_模型视图、GL_投影,即模型视图矩阵和投影矩阵

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

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

您不需要担心除以w,可以使用固定管道或可编程GLSL管道。OpenGL将为您处理它。如果您确实想知道它发生在何处,则会在模型视图投影矩阵与顶点位置相乘后立即发生。在顶点着色器中,它发生在以下情况之后:

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

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

您可以自己在顶点着色器中进行变换。将模型、视图和投影矩阵传递给顶点着色器,并设置
gl_position=proj*view*model*vec4(在顶点中,1)那么所有的GLFRUSTOMF()、glMatrixMode()等函数都是用来做什么的呢?这种“除以Z”的情况发生在哪里?glFrustumf(),glMatrixMode()来自Opengl 1.x。在现代Opengl(2.0+)中,您不使用此函数。“除以Z”正好发生在片段着色器之前。它实际上除以向量4的“w”坐标。那么
vec4(x,y,z,w)->vec4(x/w,y/w,z/w,1)
那么这个“除以z”是怎么发生的呢?我也必须自己做吗?不,你不必自己做。在我的第一条评论中,您可以看到
gl_position
是一个vec4,变换后
w
坐标不是1。被
w
除法是隐式的。+1表示正确的乘法顺序(矩阵乘以矩阵乘以矩阵乘以列)。数学一直都是按照这个顺序来教的,我不知道为什么有人在某个时候把它颠倒过来:D