我使用的是OpenGL 3.3并且有一些奇怪的灯光问题,我首先会以不同的角度显示两个截图,然后给出着色器代码。
第一个角度:
第二个角度:
你在这里看到的是:
我知道顶点的法线是"错误",但我正在尝试调试它们。
我的期望是:A(从上到下)各种颜色的变化,取决于" sun"的位置。和相机。
但我得到的是立方体的两个部分(上部和下部)都有不同的颜色,但不符合我的预期。
着色器中有阴影代码,但我故意在这里禁用它们以避免混淆。
顶点着色器:
#version 430 core
layout(location = 0) in vec4 position;
layout(location = 1) in vec3 normal;
layout(location = 0) uniform mat4 model_matrix;
layout(location = 1) uniform mat4 view_matrix;
layout(location = 2) uniform mat4 proj_matrix;
layout(location = 3) uniform mat4 shadow_matrix;
out VS_OUT {
vec3 N;
vec3 L;
vec3 V;
vec4 shadow_coord;
} vs_out;
uniform vec4 light_pos = vec4(-20.0, 7.5, -20.0, 1.0);
void main(void) {
vec4 local_light_pos = view_matrix * light_pos;
vec4 p = view_matrix * model_matrix * position;
//normal
vs_out.N = normalize(normal);
//light vector
vs_out.L = local_light_pos.xyz - p.xyz;
//view vector
vs_out.V = -p.xyz;
//light space coordinates
vs_out.shadow_coord = shadow_matrix * position;
gl_Position = proj_matrix * p;
}
片段着色器:
#version 430 core
out vec4 color;
in VS_OUT {
vec3 N;
vec3 L;
vec3 V;
vec4 shadow_coord;
} fs_in;
layout(binding = 0) uniform sampler2DShadow shadow_tex;
uniform vec3 light_ambient_albedo = vec3(1.0);
uniform vec3 light_diffuse_albedo = vec3(1.0);
uniform vec3 light_specular_albedo = vec3(1.0);
uniform vec3 ambient_albedo = vec3(0.0, 0.2, 0.0);
uniform vec3 diffuse_albedo = vec3(0.2, 0.7, 0.2);
uniform vec3 specular_albedo = vec3(0.0, 0.0, 0.0);
uniform float specular_power = 128.0;
vec3 rgb_to_grayscale_luminosity(vec3 color) {
float value = color.r * 0.21 + color.g * 0.71 + color.b * 0.07;
return vec3(value);
}
void main(void) {
//normalize
vec3 N = normalize(fs_in.N);
vec3 L = normalize(fs_in.L);
vec3 V = normalize(fs_in.V);
//calculate R
vec3 R = reflect(-L, N);
//calcualte ambient
vec3 ambient = ambient_albedo * light_ambient_albedo;
//calculate diffuse
vec3 diffuse = max(dot(N, L), 0.0) * diffuse_albedo * light_diffuse_albedo;
//calcualte spcular
vec3 specular = pow(max(dot(R, V), 0.0), specular_power) * specular_albedo * light_specular_albedo;
//apply shadow and write color
float shadow_value = textureProj(shadow_tex, fs_in.shadow_coord);
if (shadow_value > 0.0001 || true) {
//no shadow
color = vec4(ambient + diffuse + specular, 1.0);
}
else {
//in shadow
//color = vec4(rgb_to_grayscale_luminosity((ambient + diffuse) * (1 - shadow_value)), 0.5);
//color = vec4(vec3(shadow_value), 0.5);
color = vec4((ambient + diffuse) * (1 - shadow_value) * 0.5, 1.0);
}
}
这里可能出现什么问题?
答案 0 :(得分:0)
假设您的法线仅指向上/下(在OpenGL坐标系中x = 0且z = 0),您看到的应该是预期的行为(没有关于着色器/图形管道的错误)。
在图形管道的光栅化阶段,属性在顶点(重心坐标)之间进行插值。 假设平面“y = 0”以上的所有法线都是
此平面下方的所有法线均为
然后对于每个像素,插值法线将为
在片段着色器中,您将所有法线标准化,因此它们将再次成为
这将为“y = 0”平面下方和上方的所有顶点产生相同的颜色。
如果您要删除片段着色器中的正常“标准化”,或者如果您向某些法线的x或z坐标添加最小偏移,则可以检查此项,例如