2013-05-17 36 views
4

我试图让一些简单的漫反射照明在GLSL中工作。我有一个正在传入的立方体作为点阵列,我正在计算我的几何着色器中的面法线(因为我打算在运行时变形网格,所以我需要新的面法线。)片段漫反射值随相机位置/旋转而变化

我的问题是漫反射值正在改变,因为我在世界各地移动相机。所以我的魔方脸上的阴影随着相机的移动而变化。我一直无法弄清楚我错过了什么导致了这一点。我的着色器如下:

顶点:

#version 330 core 

layout(location = 0) in vec3 vertexPosition_modelspace; 

uniform mat4 MVP; 

void main(){  
    gl_Position = MVP * vec4(vertexPosition_modelspace,1); 
} 

几何:

#version 330 

precision highp float; 

layout (triangles) in; 
layout (triangle_strip) out; 
layout (max_vertices = 3) out; 

out vec3 normal; 
uniform mat4 MVP; 
uniform mat4 MV; 

void main(void) 
{ 
    for (int i = 0; i < gl_in.length(); i++) { 
     gl_Position = gl_in[i].gl_Position; 


     vec3 U = gl_in[1].gl_Position.xyz - gl_in[0].gl_Position.xyz; 
     vec3 V = gl_in[2].gl_Position.xyz - gl_in[0].gl_Position.xyz; 

     normal.x = (U.y * V.z) - (U.z * V.y); 
     normal.y = (U.z * V.x) - (U.x * V.z); 
     normal.z = (U.x * V.y) - (U.y * V.x); 

     normal = normalize(transpose(inverse(MV)) * vec4(normal,1)).xyz; 

     EmitVertex(); 
    } 
    EndPrimitive(); 
} 

片段:

#version 330 core 

in vec3 normal; 
out vec4 out_color; 
const vec3 lightDir = vec3(-1,-1,1); 

uniform mat4 MV; 

void main() 
{ 
    vec3 nlightDir = normalize(vec4(lightDir,1)).xyz; 
    float diffuse = clamp(dot(nlightDir,normal),0,1); 

    out_color = vec4(diffuse*vec3(0,1,0),1.0); 
} 

感谢

回答

8

中有很多错误的东西你的代码。你的大部分问题都来自于完全忘记了各种矢量所处的空间。你无法在不同空间中的矢量之间进行有意义的计算。

normal = normalize(transpose(inverse(MV)) * vec4(normal,1)).xyz; 

通过使用1作为正常的第四个组件,您完全打破了这种计算。它导致法线为,翻译为,这是不合适的。

此外,您的normal值基于gl_Position计算。而gl_Position剪辑空间,而不是模型空间。所以你得到的是正常的剪辑空间,这不是你所需要的,想要的,甚至可以使用的。

如果您想计算相机空间法线,然后从相机空间位置计算它。或者从模型空间位置计算模型空间法线,并使用模型/视图矩阵将其转换为相机空间。

另外,对CPU进行反转/转置并将其传递给着色器。哦,把所有正常的计算都拿出来。你只需要每个三角形做一次(将其存储在局部变量中并将其复制到每个顶点的输出中)。并停止手动执行交叉产品;使用内置的GLSL cross功能。

vec3 nlightDir = normalize(vec4(lightDir,1)).xyz; 

这比在你的变换之前使用1作为第四个组件没有任何意义。直接正常化lightDir

同样重要的是,如果你在相机空间做照明,那么光方向的需求,以用相机更改为它在世界保持在同一视方向。所以你将不得不把你的世界空间的灯光位置,并将其转换到相机空间(通常在CPU上,作为制服传入)。