2011-11-14 35 views
0

我有一个以C(0,0,0)为中心的球体。现在我计算顶点着色器内的法线。我没有把它传递给它。为什么我的照明不对?

#version 330 

layout(location = 0) in vec3 in_Position; //declare position 
layout(location = 1) in vec3 in_Color; 

// mvpmatrix is the result of multiplying the model, view, and projection matrices */ 
uniform mat4 MVP_matrix; 

vec3 constant_col; 
vec3 normal_pos,normal_light_pos; 
vec3 Light_Pos = vec3(3.0f, 2.0f, 4.0f); //Light Source 
float light_magn,norm_magn; 
float dot_prod; 
float angle; 
float Light_in; 

out vec3 ex_Color; 

void main(void) { 

// Multiply the MVP_ matrix by the vertex to obtain our final vertex position (mvp was created in *.cpp) 
gl_Position = MVP_matrix * vec4(in_Position, 1.0); 

//normalizing vectors 
normal_pos = normalize(in_Position); 
normal_light_pos = normalize(Light_Pos); 

//calculating the vector's magnitude 
light_magn = sqrt(pow(normal_light_pos.x,2) + pow(normal_light_pos.y,2) + pow(normal_light_pos.z,2)); 
norm_magn = sqrt(pow(normal_pos.x,2) + pow(normal_pos.y,2) + pow(normal_pos.z,2)); 

dot_prod = dot(normal_light_pos, normal_pos); //getting the dot product 
angle = dot_prod/ (light_magn*norm_magn); //getting angle in radians 

angle = clamp(angle, 0, 1); 

Light_in = cos(angle); // here I calculate the light intensity 

constant_col = vec3(1.0f,0.0f,0.0f); //set the sphere's color to red 

ex_Color = constant_col * Light_in ; //for sphere 

} 

我的代码是基于朗伯余弦定律,基本上都是从这里: http://en.wikipedia.org/wiki/Lambertian_reflectance

我得到的是这样的: enter image description here

+1

不完全确定这会修复它,但是,由于点积被定义为A *的长度,B *的长度是向量之间角度的余弦,在您的情况下A和B的长度为1, dot_prod'和'Light_in'应该是相同的值,你可以削减一堆计算。 – slugonamission

+0

具体有什么问题?除了中心的突出亮点外,其余的看起来都不错。 – NickLH

+0

在着色器中“计算”法线没有意义。只有一种形状可以从表面点位置推导出法线,这是围绕原点的球体。对于其他所有形状,必须明确给出法线,因为无法从局部顶点位置确定法线(有些技巧可能能够提取片段着色器中的正常面,但结果很差)。只是不要尝试在着色器中计算正常值。没有用。 – datenwolf

回答

3

两个向量的标量(=点)的产品已经给你是那些矢量角度的余弦。所以你的cos(角度)是完全多余的。

另外一个通常计算表面法线和从光源到表面点的归一化矢量之间的点积。然而,你在光照位置和法线向量之间做点积,这是不正确的。你想要类似

dot_prod = dot(normalize(normal_light_pos - MV * gl_Vertex, normal_pos); 

请注意,顶点仅与modelview(不是modelviewprojection)相乘。

说真的,你应该通过一些体面的教程,只是有很多错误的尝试。

+0

非常感谢。问题只是“角度”问题 –

+2

问题不是“只是角度问题”。到目前为止,每个人都已经说过一百万次,但要阅读教程,以及一些基本的数学和几何学!计算你刚刚归一化的矢量的大小(提示:这是一个定义)。此外,GLSL还有一个length()函数。 –

相关问题