GLSL - 来自世界坐标的计算屏幕坐标不正常

时间:2011-12-15 07:02:50

标签: opengl glsl shader

我刚从nVidia可爱的GPU Gems网站上实现了“神光”着色器:http://http.developer.nvidia.com/GPUGems3/gpugems3_ch13.html

无论如何,它几乎是完美的,除了一个缺陷。不知何故,灯光的位置不会随着场景的其余部分而移动。

图片示例:

这看起来应该如此。

enter image description here

这不是。光应该从白色球体向外辐射,但看起来位置没有从第一张照片改变。

enter image description here

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

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在下面提出的建议进行了一些更改,但它更好,但仍然不对。

当相机处于原始位置时它仍然看起来很好,但是当我旋转场景时,看起来好像计算出的光位置现在太远了。

enter image description here

这是我正在使用的GLSL代码:

制服vec4 light_coords; 制服mat4 light_modelview; 改变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_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()

position[0, 0, -2]。它作为light_coords

传递到着色器

理想情况下,我希望light_pos在(0,0)到(1,1)的任何地方(如果它在屏幕上),并且大于或小于它在屏幕外的位置。

任何线索我做错了什么?我仍然是OpenGL的新手,所以我有点不确定是什么。

1 个答案:

答案 0 :(得分:4)

如果light_coords位于世界空间中,那么只有gl_ModelViewProjectionMatrix在世界空间中 时才会将其乘以gl_Vertex。不知怎的,我怀疑它是。

一般情况下,你不会传递光线方向或light_coords应该在世界空间中的任何方向。你在视图空间中传递它。您可以从世界空间转换到CPU上的视图空间,并将视图空间坐标放在着色器中。