2017-12-27 21 views
3

OpenGLとGLSLを使用してシーンに指向灯を追加したいと思います。問題は理論的に正しい方法で間違った結果が出るということです。OpenGL指向性ライトシェーダ

光の方向が世界座標で与えられ、カメラ座標にviewMatrixを用いて形質転換される:私は次のない頂点シェーダで

。頂点の法線は、法線行列をカメラ座標に変換して変換されます。

void main() { 
    vary_textureCoord = attribute_textureCoord; 
    vary_normal = mat3(normalMatrix) * attribute_normal; 

    vary_directionalLight_direction = viewMatrix * vec4(lightDir, 1.0); 

    gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(attribute_position, 1.0); 
} 

したがって、両方のベクトルはカメラ座標にあり、フラグメントシェーダに渡されます。フラグメントシェーダは、光の法線と方向を使用して光強度を計算します。

void main() { 
    vec3 normalizedNormal = normalize(vary_normal); 
    vec4 color = texture(tex, vary_textureCoord); 

    float directionalLightIntensity = max(0.0, dot(normalizedNormal, normalize(-vary_directionalLight_direction.xyz))); 

    out_color = color * directionalLightIntensity; 
} 

このシェーダは、光が静的ではなくカメラと共に移動するという結果につながります。代わりに、次の行を使用して頂点シェーダを変更してください。

vary_directionalLight_direction = transpose(inverse(viewMatrix)) * vec4(lightDir, 1.0); 

私は何が間違っているのですか?または私はどこで誤解をしていますか?ここで

フルシェーダコード:

Vertexshader:

# version 330 

layout(location = 0) in vec3 attribute_position; 
layout(location = 2) in vec2 attribute_textureCoord; 
layout(location = 3) in vec3 attribute_normal; 

uniform mat4 projectionMatrix; 
uniform mat4 viewMatrix; 
uniform mat4 modelMatrix; 
uniform mat4 normalMatrix; 
uniform vec3 lightDir; 

out vec2 vary_textureCoord; 
out vec3 vary_normal; 
out vec4 vary_directionalLight_direction; 

void main() { 
    vary_textureCoord = attribute_textureCoord; 
    vary_normal = mat3(normalMatrix) * attribute_normal; 

    vary_directionalLight_direction = viewMatrix * vec4(lightDir, 1.0); 

    gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(attribute_position, 1.0); 
} 

Fragmentshader:あなたはトンをしたい場合

(X-axis.x, X-axis.y, X-axis.z, 0) 
(Y-axis.x, Y-axis.y, Y-axis.z, 0) 
(Z-axis.x, Z-axis.y, Z-axis.z, 0) 
(trans.x, trans.y, trans.z, 1) 

# version 330 

in vec2 vary_textureCoord; 
in vec3 vary_normal; 
in vec4 vary_directionalLight_direction; 

uniform sampler2D tex; 

out vec4 out_color; 

void main() { 
    vec3 normalizedNormal = normalize(vary_normal); 
    vec4 color = texture(tex, vary_textureCoord); 

    float directionalLightIntensity = max(0.0, dot(normalizedNormal, normalize(-vary_directionalLight_direction.xyz))); 

    out_color = color * directionalLightIntensity; 
} 

答えて

1

変換行列は次のようになりますo位置を変換すると、完全な変換行列をその位置に適用する必要があります。

mat4 viewMatrix; 
vec3 pos; 
vec4 viewPos = viewMatrix * vec4(pos, 1.0); 

これは、ビューの向きと位置をposの位置に適用します。

しかし、方向は原点がありません。方向には向きがあります。つまり、ビューによって方向ベクトルを変換する場合は、4 * 4の左上3 * 3部分に掛けなければなりません。viewMatrix

vary_directionalLight_direction = vec4(mat3(viewMatrix) * lightDir, 1.0); 
関連する問題