2011-12-15 132 views
3

我只是从实现nVidia的GPU可爱宝石网站上的“神线”着色器:http://http.developer.nvidia.com/GPUGems3/gpugems3_ch13.htmlGLSL - 计算屏幕从世界坐标系坐标不能正常工作

不管怎么说,这是近乎完美,除了一个缺陷。不知何故,光线的位置并未随着场景的其他部分而移动。

图片示例:

这看起来应该是这样。

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; uniform 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还是一个​​新鲜的东西,所以我有点不确定它是什么。

回答

4

如果light_coords是在世界空间中,然后由gl_ModelViewProjectionMatrix乘以才有意义,如果gl_Vertex也是世界空间。不知何故,我怀疑它是。

一般而言,您不会通过光线指示或任何light_coords应该在世界空间中。你在视图空间中传递它。您可以从世界空间转换到CPU上的空间,并将视图空间坐标放置在着色器中。

+0

嗯。有没有一种有效的方式来完成这种转变?我使用OpenGL的Python绑定,所以我想尽可能多地保留着色器或OpenGL调用。 – 2011-12-15 07:15:13

相关问题