我想使用OpenGL和GLSL向我的场景添加定向光。问题在于,理论上正确的方法会得到错误的结果。
在顶点着色器中,我做了以下操作:
光的方向以世界坐标给出,并使用viewMatrix转换为相机坐标。顶点的法线使用normal-matrix转换为相机坐标。
所以这两个向量都是相机坐标系下的,并被传递到片元着色器中。片元着色器使用法线和光线方向计算光照强度。
这个着色器会导致光线不是静态的,而是随着相机移动而移动。使用以下这行代码更改顶点着色器:
有期望的结果。 那么我做错了什么或者我哪里有误解呢?
这里是完整的着色器代码:
顶点着色器:
片元着色器:
在顶点着色器中,我做了以下操作:
光的方向以世界坐标给出,并使用viewMatrix转换为相机坐标。顶点的法线使用normal-matrix转换为相机坐标。
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);
有期望的结果。 那么我做错了什么或者我哪里有误解呢?
这里是完整的着色器代码:
顶点着色器:
# 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);
}
片元着色器:
# 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;
}