我刚实现了nVidia的GPU Gems 3书中的“神光”着色器:作为后期处理的体积光散射。总的来说,除了一个缺陷外,它几乎是完美的。不知何故,灯光的位置没有随着场景的变化而移动。下面是图片示例:第一张图片看起来完全正常;然而第二张图片并非如此,从白色球体应该向外辐射光线,但是看起来位置没有从第一张图片改变。在顶点着色器中进行转换:
在这里获取
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_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还比较陌生,所以我有点不确定哪个是做什么的。