yuris89
yuris89

Reputation: 63

opengl point-light phong specular reflection problem

Point light specular reflections in phong shading displayed incorrectly, assume some shader issues? Specular highlights displayed rotated and skewed to the center of the render target

Done it before with almost equal shader code, cant find where problem is, can anyone investigate?

 #version 450 core

// input
layout (location = 0) in vec4 v_position;
layout (location = 1) in vec4 v_color;
layout (location = 2) in vec4 v_normal;
layout (location = 3) in vec2 v_uv;

// output
out Vertex
{
    vec4 position;
    vec4 color;
    vec4 normal;
    vec2 uv;
} f_input;

// uniorm
uniform mat4 u_projection_matrix;
uniform mat4 u_view_matrix;
uniform mat4 u_model_matrix;

//

// main
void main()
{
    f_input.position = u_model_matrix * v_position;
    f_input.color = v_color;
    f_input.normal = transpose(inverse(u_model_matrix)) * v_normal;
    f_input.uv = v_uv;

    gl_Position = u_projection_matrix * u_view_matrix * f_input.position;
}

In fragmen shader f_input.position is world space position of a fragment. u_view_pos is world space origin of a camera.

#version 450 core

// input
in Vertex
{
    vec4 position;
    vec4 color;
    vec4 normal;
    vec2 uv;
} f_input;

// output
out vec4 color;

// uniform
layout(binding = 0) uniform sampler2D u_texture_unit_0;
layout(binding = 1) uniform sampler2D u_texture_unit_1;

//

struct Material
{
    sampler2D diffuse;
    sampler2D specular;
    float shininess;
}; 

struct DirectionalLight
{
    vec3 direction;

    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
};

struct PointLight
{
    vec3 position;

    vec3 ambient;
    vec3 diffuse;
    vec3 specular;

    float constant;
    float linear;
    float quadratic;
};

#define DIRECTIONAL_LIGHT_COUNT 1
#define POINT_LIGHT_COUNT 3

// uniform
uniform vec3 u_view_pos;

uniform Material u_material;

uniform DirectionalLight u_dir_light[DIRECTIONAL_LIGHT_COUNT];
uniform PointLight u_point_light[POINT_LIGHT_COUNT];

// function prototypes
vec3 calc_directional_light(DirectionalLight light, vec3 normal, vec3 viewDir);
vec3 calc_point_light(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir);

// main
void main()
{    
    // properties
    vec3 norm = normalize(f_input.normal.xyz);
    vec3 viewDir = normalize(u_view_pos - f_input.position.xyz);
    vec3 fragColor;

    // phase 1: directional lighting
    for(int i = 0; i < DIRECTIONAL_LIGHT_COUNT; i++)
        fragColor += calc_directional_light(u_dir_light[i], norm, viewDir);

    // phase 2: point lights
    for(int i = 0; i < POINT_LIGHT_COUNT; i++)
        fragColor += calc_point_light(u_point_light[i], norm, f_input.position.xyz, viewDir);

    color = vec4(fragColor, 1.0f);
}

// calculates the color when using a directional light
vec3 calc_directional_light(DirectionalLight light, vec3 normal, vec3 viewDir)
{
    vec3 lightDir = normalize(-light.direction);

    // diffuse shading
    // lambertian = diff
    float diff = max(dot(normal, lightDir), 0.0);
    float spec = 0.0;

    // specular shading
    // phong
    //vec3 reflectDir = reflect(-lightDir, normal);
    //spec = pow(max(dot(viewDir, reflectDir), 0.0), u_material.shininess);

    // blinn-phong
    vec3 halfwayDir = normalize(lightDir + viewDir);
    spec = pow(max(dot(halfwayDir, normal), 0.0), u_material.shininess);

    // combine results
    vec3 ambient = light.ambient * vec3(texture(u_material.diffuse, f_input.uv));
    vec3 diffuse = light.diffuse * diff * vec3(texture(u_material.diffuse, f_input.uv));
    vec3 specular = light.specular * spec * vec3(texture(u_material.specular, f_input.uv));

    return (ambient + diffuse + specular);
}

// calculates the color when using a point light
vec3 calc_point_light(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir)
{
    vec3 lightDir = normalize(light.position - fragPos);

    // diffuse shading
    // lambertian = diff
    float diff = max(dot(normal, lightDir), 0.0);
    float spec = 0.0;

    // specular shading
    // phong
    //vec3 reflectDir = reflect(-lightDir, normal);
    //spec = pow(max(dot(viewDir, reflectDir), 0.0), u_material.shininess);

    // blinn-phong
    vec3 halfwayDir = normalize(lightDir + viewDir);
    spec = pow(max(dot(halfwayDir, normal), 0.0), u_material.shininess);

    // attenuation
    float distance = length(light.position - fragPos);
    float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance));

    // combine results
    vec3 ambient = light.ambient * vec3(texture(u_material.diffuse, f_input.uv));
    vec3 diffuse = light.diffuse * diff * vec3(texture(u_material.diffuse, f_input.uv));
    vec3 specular = light.specular * spec * vec3(texture(u_material.specular, f_input.uv));

    ambient *= attenuation;
    diffuse *= attenuation;
    specular *= attenuation;

    return (ambient + diffuse + specular);
}

scene scene scene

Upvotes: 1

Views: 486

Answers (0)

Related Questions