OpenGL - 投影后校正曲面法线

时间:2012-11-22 18:12:05

标签: opengl transform projection normals

我目前正在开发一个带有OpenGL的小玩具程序,它在剪辑空间视图中显示一个场景,即它绘制一个立方体来显示规范视图体积,并在立方体内部绘制投影变换模型。要显示模型图的代码段:

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glScalef(1.0f, 1.0f, -1.0f);
glMultMatrixd(projectionMat);
glMultMatrixd(modelviewMat);
glEnable(GL_LIGHTING);
draw_model();
glDisable(GL_LIGHTING);

因此,自然地,绘制的模型是“扭曲的”(这是期望的行为)。然而,光照是错误的,因为表面法线也被投影矩阵变换,因此在变换之后不与它们的表面正交。我想要完成的是在扭曲模型的表面具有正确法线的意义上“正确”的照明。

问题是 - 我该怎么做?我正在玩法线的通常转置 - 逆矩阵规则,但据我所知,这就是OGL默认使用法线做的事情。我想我必须在使用模型视图矩阵转换曲面后重新计算曲面法线,但是如何做到这一点?或者还有另一种方式吗?

2 个答案:

答案 0 :(得分:1)

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glScalef(1.0f, 1.0f, -1.0f);
glMultMatrixd(projectionMat);

投影矩阵进入glMatrixMode(GL_PROJECTION);。变换法线发生在模型视图的逆转置中。如果模型视图中有一个投影组件,则会影响您的正常转换。

正确的代码是

glMatrixMode(GL_PROJECTION);
glLoadMatrixd(projectionMat);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glScalef(1.0f, 1.0f, -1.0f);
glMultMatrixd(modelviewMat);
glEnable(GL_LIGHTING);
draw_model();
glDisable(GL_LIGHTING);

答案 1 :(得分:0)

如果您使用固定功能,则必须将所有这些放在投影矩阵中。 包括投影后发生的缩放,平移和旋转:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glScalef(1.0f, 1.0f, -1.0f);
glMultMatrixd(projectionMat);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMultMatrixd(modelviewMat);
glEnable(GL_LIGHTING);
draw_model();
glDisable(GL_LIGHTING);

这是有效的,因为投影和模型视图矩阵都会转换位置(即:所见),但固定功能照明仅在视图空间中完成(即:在模型视图之后但是之前投影。)

事实上,这正是固定功能GL在两个矩阵之间有所区别的原因。