英文:
Legacy openGL - light is wrongly moving with glulookat orientation
问题
我正在寻求帮助,因为我在尝试在我的网格渲染器中绘制固定聚光灯时遇到了困难。我目前正在做类似于以下的事情:
gluLookAt(...)
DrawMesh(...)
float pos[] = {0, 500, 0, 1};
glLightfv(GL_LIGHT0, GL_POSITION, pos);
其中,我使用以下方式初始化光照:
float ambient_light[] = {1, 1, 1, 1.0};
glLightfv(GL_LIGHT0, GL_AMBIENT, ambient_light);
GLfloat cutoffAngle = 30.0f;
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, cutoffAngle);
GLfloat spotDirection[3] = {0.0f, -1.0f, 0.0f};
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, spotDirection);
GLfloat exponentValue = 10.0f; // 示例值
glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, exponentValue);
在变换之后定义光照应该提供一个相对于我的摄像机视点的固定光照。问题在于,聚光灯仍然相对于相机的平移而变化,但随着相机的旋转/方向而变化!这里是一个gif,显示了发生的情况。我已经尝试了两天,但还没有能够解决这个问题!如果需要,我将愿意分享更多代码。谢谢您阅读这篇文章。
(请注意,由于这是一个学术项目,我被迫坚持使用传统的OpenGL)
我已经尝试过更改模型视图函数和光照调用的顺序,设置不同的光照属性,并调整网格法线。期望的行为应该是光在移动相机方向时保持不变。
英文:
I'm seeking help as I'm having a hard time trying to draw a fixed spot light in my mesh renderer. I'm currently doing something like:
gluLookAt(...)
DrawMesh(...)
float pos[] = {0, 500, 0, 1};
glLightfv(GL_LIGHT0, GL_POSITION, pos);
where I init the light with:
float ambient_light[] = {1, 1, 1, 1.0};
glLightfv(GL_LIGHT0, GL_AMBIENT, ambient_light);
GLfloat cutoffAngle = 30.0f;
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, cutoffAngle);
GLfloat spotDirection[3] = {0.0f, -1.0f, 0.0f};
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, spotDirection);
GLfloat exponentValue = 10.0f; // Example value
glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, exponentValue);
Defining the light after transformations should provide a fixed light relative to my camera PoV. The problem is that the spot light is still with respect to camera traslations, but changes with camera rotation/orientation!. Here's a gif of whats happening.
It's been 2 days and I haven't been able to get over this issue!
I will happily share more code if needed. Thanks for reading this.
(note that I'm forced to stick to legacy opengl due to this being an academic project)
I already tried changing the order of modelview function and light calls, setting different light properties and playing with mesh normals.
The expected behaviour should consist of the light staying still even when moving the camera orientation.
答案1
得分: 2
根据规范:
当调用glLight时,光源位置会被模型视图矩阵转换(就像它是一个点一样),并且它以眼坐标存储。
所以你的问题在于光源位置会被你的模型视图矩阵转换,该矩阵是由gluLookAt()
创建的。你可以通过调用glLoadIdentity()
来重置你的模型视图矩阵。如果之后要渲染更多内容,你可以使用glPushMatrix()
和glPopMatrix()
来恢复矩阵。
假设在你的模型视图矩阵中有一些平移操作,将对象放入眼空间,例如使用非零眼坐标的gluLookAt()
。在调用glLoadIdentity()
后,你可能需要恢复该平移操作。
英文:
According to the specification:
> 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.
> Blockquote
So your issue here is that the light position gets transformed by your modelview matrix, which is created by gluLookAt()
. You can reset your modelview matrix by calling glLoadIdentity()
. You may want to use glPushMatrix()
and glPopMatrix()
to restore the matrix if you want to render more stuff later.
Suppose there are some translations in your modelview matrix to get the objects into eye space, eg. gluLookAt()
with non-zero eye coordinate. You might need to restore that translation after glLoadIdentity()
.
答案2
得分: 0
以下是reddit上一个解决了我的问题的回答:
我认为问题在于所有接受矢量的glLightfv()调用都使用当前的ModelViewMatrix。由于你设置聚光灯方向的调用位于绘制循环之外,MVM 在那个时候可能是单位矩阵。尝试将GL_SPOT_DIRECTION设置移到draw()函数中,与设置位置的地方相邻。或者也许这两个调用都必须在外部进行,我不确定在这种模式下矩阵是如何工作的。无论如何,在不同位置设置它们几乎肯定是问题的一部分。
英文:
Quoting an answer from reddit which solved my problem:
> I think the problem is that all of the glLightfv() calls that take a vector use the current ModelViewMatrix. Since your call that sets the
> spotlight direction is outside the draw loop, the MVM is likely
> identity at that time. Try moving the GL_SPOT_DIRECTION setting inside
> draw() next to where you set the position. Or maybe both calls have to
> be outside, I'm not sure how the matrices work in this mode. In any
> case, having them set at different places is almost certainly part of
> the problem.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论