2011-11-14 11 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

シェーダの法線を "計算"するポイントはありません。サーフェスポイントの位置から法線を推測できるのは1つの形状だけです。これは原点の周りの球です。その他のすべてのシェイプでは、ローカル頂点の位置から決定できないため、ノーマルを明示的に指定する必要があります(一部のトリックでは、フラグメントシェーダでファセットノーマルを抽出できますが、結果は悪くなります)。シェーダの法線をまったく計算しないでください。それは無意味です。 – datenwolf

答えて

3

2つのベクトルのスカラー(=ドット)製品がすでに提供しますあなたはそれらのベクトルの角度の余弦です。だからあなたのcos(angle)は全く余分です。

また、通常、サーフェス法線と、光源からサーフェス上のポイントまでの正規化されたベクトルとの間のドット積を計算します。しかし、ライト位置と法線ベクトルの間にドットプロダクトを作成しますが、これは正しくありません。あなたは頂点がモデルビューのみ(ないmodelviewprojection)と乗算されていることを

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

ノートのようなものをしたいです。

真剣に、いくつかのまともなチュートリアルで作業する必要があります、あなたの試みに多くの間違いがあります。

+0

ありがとうございます。問題はちょうど「アングル」問題でした –

+2

問題は「角度問題」ではありませんでした。誰もがこれまでに何百万回も言いましたが、チュートリアル、基本的な数学と幾何学を読んでみましょう!ちょうど正規化したベクトルの大きさを計算します(ヒント:それは定義によるものです)。また、GLSLにはlength()関数があります。 –

関連する問題