Opengl GLSL-从世界坐标计算屏幕坐标无法正常工作

Opengl GLSL-从世界坐标计算屏幕坐标无法正常工作,opengl,glsl,shader,Opengl,Glsl,Shader,我刚刚实现了nVidia可爱的GPU Gems 3书中的“god ray”着色器: 不管怎样,它几乎是完美的,除了一个缺陷。不知何故,灯光的位置不会随场景的其余部分一起移动 图片示例: 这看起来正是它应该做的 但事实并非如此。光线应该是从白色球体向外辐射的,但看起来位置与第一张图片没有改变 我正在顶点着色器中进行变换: uniform vec4 light_coords; varying vec2 light_pos; void main() { gl_Position = gl_

我刚刚实现了nVidia可爱的GPU Gems 3书中的“god ray”着色器:

不管怎样,它几乎是完美的,除了一个缺陷。不知何故,灯光的位置不会随场景的其余部分一起移动

图片示例:

这看起来正是它应该做的

但事实并非如此。光线应该是从白色球体向外辐射的,但看起来位置与第一张图片没有改变

我正在顶点着色器中进行变换:

uniform vec4 light_coords;
varying vec2 light_pos;

void main()
{
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
    gl_TexCoord[0] = gl_MultiTexCoord0;
    light_pos = vec2(gl_ModelViewProjectionMatrix * light_coords) * 0.5 + 0.5;
}
这是正确的吗

灯光在世界坐标系中的位置是(0,0,-2)。错误完全可能在代码中的其他地方,但我想在深入研究其余部分之前确保顶点着色器中的计算是正确的

编辑:我根据Nicol Bolas下面的建议做了一些更改,虽然更好,但仍然不对

当摄影机处于其原始位置时,它看起来仍然很好,但当我旋转场景时,计算的灯光位置现在看起来太向左了

以下是我使用的GLSL代码:

uniform vec4 light_coords;
uniform mat4 light_modelview;
varying vec2 light_pos;

void main()
{
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
    gl_TexCoord[0] = gl_MultiTexCoord0;
    light_pos = vec2(gl_ProjectionMatrix * light_modelview * light_coords) * 0.5 + 0.5;
}
light\u modelview
在此处获得:

glPushMatrix()
glTranslatef(self.position[0], self.position[1], self.position[2])
glScalef(2, 2, 2)       
self.modelview = glGetFloatv(GL_MODELVIEW_MATRIX)
glCallList(self.sphere) 
glLightfv(self.light_id, GL_POSITION, self.position)
glPopMatrix()
位置
[0,0,-2]
。它作为
light\u-coords

理想情况下,如果在屏幕上,我希望
light\u pos
位于(0,0)到(1,1)中的任何位置,如果在屏幕外,则大于或小于该位置


知道我做错了什么吗?我对OpenGL还是有点陌生,所以我有点不确定什么是做什么的。

如果世界空间中有
light\u coords
,那么将其乘以
gl\u ModelViewProjectionMatrix
只有当
gl\u Vertex
也在世界空间中时才有意义。不知怎的,我怀疑这是真的


一般来说,您不会传递灯光方向或世界空间中应该存在的任何
灯光坐标。您可以在视图空间中传递它。在CPU上从世界空间转换到视图空间,并将视图空间坐标放入着色器中。

Hmm。有没有有效的方法进行转换?我使用的是OpenGL的Python绑定,所以我希望在着色器或某些OpenGL调用中保留尽可能多的内容。@DaneLarsen:每帧执行一次。我相信您的CPU可以处理每帧一次的矩阵乘法,即使在Python中也是如此。我会告诉你如何在着色器中实现它,但我担心你会这样做,而不是将它放在CPU上,看看它对任何东西的影响有多小。此外,它还需要明确使用世界空间矩阵,这在GPU上从来都不是一件好事。我明天试试看。谢谢你的帮助!