OpenGL中所有受当前ModelViewMatrix影响的参数设定
OpenGL中所有受当前ModelViewMatrix影响的参数设定
glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
The position is transformed by the modelview matrix when glLight is called (just as if it were a point), and it is stored in eye coordinates.
如上,传入的光位置参数是定义在模型坐标系下的,但被保存在镜头空间中.且除非再次指定,该值不变,即相当于光的位置相对镜头固定.这通常不是我们想要的, 通常光应该相对世界固定(如DirectX).所以需要在每次变更ModelViewMatrix后再次设置光的位置,以表明其相对世界固定.
glClipPlane:
When you call glClipPlane, equation is transformed by the inverse of the modelview matrix and stored in the resulting eye coordinates. Subsequent changes to the modelview matrix have no effect on the stored plane-equation components.
即不同于 glLightfv, glClipPlane指定的平面公式参数受到当前ModelViewMatrix逆矩阵的影响(没想到吧),实际存储的数值为: 传入的平面公式参数四元组 P 乘以 (ModelViewMatrix ^ -1). 需要特别指出的是,这里的计算是P * M,而不是OpenGL习惯的M * V.
glTexGenfv:
与glClipPlane相同,GL_EYE_LINEAR模式下的纹理坐标自动生成,参数指定的平面公式系数4元组,受到当前 ModelViewMatrix逆矩阵影响后存储在镜头空间,即: P * (ModelViewMatrix ^ -1)。但GL_OBJECT_LINEAR没有这种特性。
推论:
1.分别为(s,t,r,q)这4个纹理坐标分量定义一个平面公式,实际上可以理解为定义了一个纹理坐标转换矩阵Ma,这个Ma与纹理变换矩阵 glMatrixMode(GL_TEXTURE)机制是相互独立的,也就是说纹理坐标自动生成机制可以提供一个额外的纹理变换矩阵. 通过glTexGenfv(GL_x, GL_EYE_PLANE, …)可以指定矩阵的4个行向量,记这个矩阵为Ma.
2.平面公式定义下的纹理坐标自动生成可以总结为 M * V.
3.在GL_OBJECT_LINERAR模式下, V是模型坐标系的坐标, M等于Ma.
4.在GL_EYE_LINEAR模式下就复杂多了, V是镜头坐标系下的坐标, M = Ma * (ModelViewMatrix ^ -1).其中ModelViewMatrix是执行glTexGenfv时的ModelViewMatrix. 纹理坐标总公式为:
Vtex = Ma * (ModelViewMatrix1 ^ -1) * TextureMatrix * ModelViewMatrix2 * Vobject
其中: Ma是glTexGenfv(GL_x, GL_EYE_PLANE, …)定义的平面公式矩阵
ModelViewMatrix1是指定glTexGenfv时的ModelViewMatrix,为了得到视图矩阵的逆矩阵,我们总是应该在当前只指定了gluLookAt的时候调用glTexGenfv.
ModelViewMatrix2是实际渲染时的ModelViewMatrix
TextureMatrix是纹理矩阵
Voject是模型顶点坐标.
5. 假设当前Batch渲染时的ModelViewMatrix等于glTexGenfv指定时的ModelViewMatrix,且没有 TextureMatrix作用,依矩阵乘法结合率,则有 Vtex = Ma * Vobject,等同与GL_OBJECT_LINERAR模式.这就是为什么有的时候GL_EYE_LINEAR和GL_OBJECT_LINEAR的 图像没有差别的原因.
6.假设当前Batch渲染时的ModelViewMatrix不等于glTexGenfv指定时的ModelViewMatrix,通常的技巧设置 glTexGenfv指定时的ModelViewMatrix为纯ViewMatrix(即用gluLookAt指定),随后镜头不再变 换,ModelViewMatrix仅追加ModelMatrix变换,ViewMatrix不变,即有:
Vtex = Ma * (ViewMatrix ^ -1) * ModelViewMatrix * Vobject = Ma * (ViewMatrix ^ -1) * Veye = Ma * Vworld
就是说Ma神奇地作用到了物体的世界坐标上了,这就是Project Texture, Shadow Map使用固定管线渲染时大量应用的技巧.
Shader编程大大降低了一些图形学技巧的复杂性,但我坚持要知其然,知其所以然.
from: http://www.cnitblog.com/linghuye/archive/2007/10/19/35091.html
应该还有一个需要计算的是primitive的normal,在进行Lighting计算时,需要乘以M^-1转换到eye space下做计算。
标签:OpenGL相关日志
If you enjoyed this post, please consider to leave a comment or subscribe to the feed and get future articles delivered to your feed reader.
