您的位置:首页 > 运维架构

无意中在网上看到的opengl光照位置问题 BY 豆子

2010-10-28 12:00 211 查看
光源的位置就应该是其在世界坐标系中的位置,不管经过什么变换,光源和场景中物体的相对位置是不应该变的。openGL中的这个现象是openGL的一个bug,跟坐标变换没有关系。

在openGL中,顶点每被提交一次,就被模型视图矩阵变换一次,而变换后的坐标,即,眼睛坐标系中的坐标,被存储起来,用以绘图。所谓“提交”就是指调用说明顶点坐标的函数,比如glVertex3d。对于光源,这个提交函数就是glLightfv函数。如果在MyInit函数中指定光源位置,提交的坐标值就是世界坐标值。如果在此之后才调用gluLookAt函数,则在提交光源坐标时,模型视图矩阵是单位阵。经此单位阵变换后的光源坐标被存储起来。假如在MyDisplay函数中不再设置光源的位置,也就是不再“提交”光源的位置,则openGL不会再重新计算光源的眼睛坐标值,仍然使用MyInit中计算出来的值。那么,就会出现这种现象:在MyInit后,调用gluLookAt设置了眼睛坐标系,从而也修改了模型视图矩阵,按道理来讲,光源的眼睛坐标值应该随着模型视图矩阵而变,但因为没有再次“提交”光源坐标,openGL仍然沿用使用单位矩阵计算出来的光源位置,这就造成了眼睛(坐标系)移动,光源也移动的现象发生。因为openGL中存储的光源坐标不随着眼睛位置的变化而被重新计算,总是一个定值。在绘图时,不管眼睛在哪里,openGL总是在当时的眼睛坐标系中按照一个固定的坐标值安置光源,所以,光源就随着眼睛移动了。
而,网上流行的什么光源随眼睛移动是因为被模型视图矩阵变换了坐标值的说法是完全错误的。试想,世界坐标系中的一个有固定坐标的点,不论经过了怎样的坐标变换,只是对这个点的位置的描述变了,但这个点在空间中的位置不会变。而引起大家疑惑的现象是:光源的位置在空间中发生了变化,这决不是模型视图矩阵能够做到的。

我前边说了一句:“在glLightfv之后,调用gluLookAt”,好像这个顺序有什么要紧,其实

无所谓。我这次特地来说明这点。

其实,不管是在gluLookAt之前还是之后调用glLightfv函数,只要是程序中在MyDisplay()

之外指定了光源位置,那么光源位置都会按照当时的模型视图矩阵的值被计算为一个固定的

值。那么当眼睛位置变换时,光源总会按照这个固定坐标值被绘制到当前的眼睛坐标系中,

因此光源就会随着眼睛移动了。而MyDisplay函数由于会被不断地调用,因此如果在该函数

中制定光源位置,则每次光源坐标都会被重新提交,与之对应的眼睛坐标也会被重新计算,

这就可以反映当前最新的模型视图矩阵的变化。因此光源位置就固定了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐