Opengl 照明问题,可能与正常相关?

Opengl 照明问题,可能与正常相关?,opengl,shader,lighting,normals,Opengl,Shader,Lighting,Normals,我使用的是OpenGL 3.3,有一些奇怪的照明问题,我将首先以不同的角度显示两个屏幕截图,然后给出着色器代码 第一个角度: 第二个角度: 你在这里看到的是: 一个立方体,中间位于原点上; 从黄点穿过原点的定向光源; 在青色中,可以看到顶点的法线。 我知道顶点的法线是错误的,但我正试图调试它们 我所期望的是:根据太阳和相机的位置,每个人脸从上到下都会有不同的颜色 但我得到的是立方体的上下两部分都有不同的颜色,但不是我想象的那样 着色器中有阴影代码,但我在这里故意禁用了它们以避免混淆 顶点着色器:

我使用的是OpenGL 3.3,有一些奇怪的照明问题,我将首先以不同的角度显示两个屏幕截图,然后给出着色器代码

第一个角度:

第二个角度:

你在这里看到的是:

一个立方体,中间位于原点上; 从黄点穿过原点的定向光源; 在青色中,可以看到顶点的法线。 我知道顶点的法线是错误的,但我正试图调试它们

我所期望的是:根据太阳和相机的位置,每个人脸从上到下都会有不同的颜色

但我得到的是立方体的上下两部分都有不同的颜色,但不是我想象的那样

着色器中有阴影代码,但我在这里故意禁用了它们以避免混淆

顶点着色器:

#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);
    }
}

这里可能出了什么问题?

假设法线在OpenGL坐标系中只指向上/下x=0和z=0,您看到的应该是预期的行为,没有与着色器/图形管道相关的错误

在图形管道中的光栅化阶段,属性在顶点重心坐标之间插值。 假设平面y=0上方的所有法线均为

向量30,1,0 这个平面下面的所有法线都是

vec30,-1,0 然后,对于每个像素,插值法线将为


vec30,*,0,其中*在y=0平面上方>0,从快照中可以明显看出,问题在于法线,而不是着色器。对于这样简单的几何体,应该列出法线并显示如何计算them@a.lasram法线在快照中可见。正如您在问题中提到的,这些法线不好。您应该显示设置法线和几何体的代码,而不是着色器。虫子很可能在那里