2017-12-27 296 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:

# 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

的轉換矩陣是這樣的:

(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) 

如果你想牛逼o轉換某個位置,然後必須將完整轉換矩陣應用於該位置。

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

這將視圖的方向和位置應用到位置pos

但是一個方向沒有起源。一個方向只有一個方向。這意味着,如果您想要轉換方向矢量,那麼您必須將其乘以左上方的3 * 3部分4 * 4 viewMatrix

vary_directionalLight_direction = vec4(mat3(viewMatrix) * lightDir, 1.0);