我刚从nVidia可爱的GPU Gems网站上实现了“神光”着色器:http://http.developer.nvidia.com/GPUGems3/gpugems3_ch13.html
无论如何,它几乎是完美的,除了一个缺陷。不知何故,灯光的位置不会随着场景的其余部分而移动。
图片示例:
这看起来应该如此。
这不是。光应该从白色球体向外辐射,但看起来位置没有从第一张照片改变。
我在顶点着色器中进行转换:
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代码:
制服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的新手,所以我有点不确定是什么。
答案 0 :(得分:4)
如果light_coords
位于世界空间中,那么只有gl_ModelViewProjectionMatrix
在世界空间中 时才会将其乘以gl_Vertex
。不知怎的,我怀疑它是。
一般情况下,你不会传递光线方向或light_coords
应该在世界空间中的任何方向。你在视图空间中传递它。您可以从世界空间转换到CPU上的视图空间,并将视图空间坐标放在着色器中。