环境光和高光照明在GLSL中无法正常工作

时间:2015-06-13 20:07:31

标签: opengl glsl lighting phong

在我的照明场景中,由于某种原因,环境照明根本不起作用。无论面向哪个方向,整个模型都是相同的亮度。我试图摆脱衰减,但它仍然有相同的结果。除此之外,无论相机在哪里,镜面照明总是闪亮的。它应该根据球员的位置发光。 以下是环境问题的屏幕截图:Imgur.com

如您所见,球体背离光线的部分(位于[0.0,4.0,0.0])与面向光线的部分颜色相同。环境因子应该是片段颜色的0.2。

顶点着色器源:

layout(location = 0) in vec3 positions;
layout(location = 1) in vec2 texCoords;
layout(location = 2) in vec3 normals;

out vec3 new_normal;
out vec3 worldPos_out;
out vec2 pass_texCoords;

struct Matrices {
    mat4 projection;
    mat4 worldMatrix;
    mat4 modelMatrix;
    mat3 normalMatrix;
};

uniform Matrices mat;

void main(void)
{
    pass_texCoords = texCoords;

    vec4 newPosition = vec4(positions, 1);

    vec4 worldPos = (mat.modelMatrix * newPosition);
    mat4 Camera = mat.projection * mat.worldMatrix;
    gl_Position = (Camera *  worldPos);

    new_normal = mat.normalMatrix * normals;
    worldPos_out = worldPos.xyz;
}

片段着色器源:

in vec3 new_normal;
in vec3 worldPos_out;
in vec2 pass_texCoords;

out vec4 outColor;
uniform vec3 viewPos;

#define MAX_LIGHTS 50

struct Material {
    sampler2D diffuseMap;
    sampler2D specularMap;
    vec3 specular;
    float shininess;
};
uniform Material material;

struct Light {
    vec3 position;
    vec3 color;

    vec3 ambient;
    vec3 diffuse;
    vec3 specular;

    float radius;
};
uniform Light Lights[MAX_LIGHTS];
uniform int numLights;

struct Math {
    float constant;
    float linear;
    float quadratic;
} math;

vec3 applyPointLight(Light light, vec3 normal, vec3 fragPos, vec3 viewDir, vec3 surfaceColor, vec3 surfaceSpecular) {
    vec3 lightDir = normalize(light.position - fragPos);
    //Diffuse shading
    float diff = max(dot(normal, lightDir), 0.0);
    //Specular shading
    vec3 reflectDir = reflect(-lightDir, normal);
    float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
    //Attenuation
    float distance = length(light.position - fragPos);
    float attenuation = 5.0 / (math.constant + math.linear * distance +
                        math.quadratic * (distance * distance));

    vec3 ambient = light.ambient * surfaceColor;
    vec3 diffuse = light.diffuse * surfaceColor * light.color;
    vec3 specular = light.specular * surfaceSpecular * light.color;
    ambient *= attenuation;
    diffuse *= attenuation;
    specular *= attenuation;

    return (ambient + diffuse + specular);
}

void main(void)  {
    vec3 surfaceColor = vec3(texture(material.diffuseMap, pass_texCoords));
    vec3 surfaceSpecular = vec3(texture(material.specularMap, pass_texCoords));

    vec3 unitNormal = normalize(new_normal);
    vec3 viewDir = normalize(viewPos - worldPos_out);

    math.constant = 1.0;
    math.linear = 0.09;
    math.quadratic = 0.032;

    vec3 linearColor;
    for(int i = 0; i < numLights; i++)
        linearColor += applyPointLight(Lights[i], unitNormal, worldPos_out, viewDir, surfaceColor, surfaceSpecular);

    float gamma = 2.2;
    vec3 fragColor;
    fragColor.rgb = pow(linearColor.rgb, vec3(1.0/gamma));

    outColor = vec4(linearColor, 1.0);
}

1 个答案:

答案 0 :(得分:1)

applyPointLight函数中,您未使用diffspec变量,这些变量可能是与光线相关的漫反射和镜面反射变化。看看以下是否有效:

vec3 diffuse = light.diffuse * surfaceColor * light.color * diff;
vec3 specular = light.specular * surfaceSpecular * light.color * spec;