首页 > 解决方案 > opengl点光源phong镜面反射问题

问题描述

phong着色中的点光镜面反射显示不正确,假设存在一些着色器问题?高光显示旋转并倾斜到渲染目标的中心

以前用几乎相同的着色器代码完成它,找不到问题所在,有人可以调查吗?

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

在片段着色器中, f_input.position是片段的世界空间位置。 u_view_pos是相机的世界空间原点。

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

场景 场景 场景

标签: c++openglglslphong

解决方案


推荐阅读