Lighting 3D models in OpenGL

  • Sack TV
    Likes 0

    Problem Description

    I’m following the OpenGL-tutorial on YouTube and i’m having a problem with 3D models and lighting. The tutorial doesn't say how to apply light, so i tried it by my self and came up with this:

    Vertex-Shader:

    #version 330 core

    layout (location = 0) in vec3 position;

    layout (location = 1) in vec3 normal;

    layout (location = 2) in vec2 texCoords;

     

    out vec3 Normal;

    out vec3 FragPos;

    out vec2 TexCoords;

     

    uniform mat4 model;

    uniform mat4 view;

    uniform mat4 projection;

     

    void main() {

        gl_Position = projection * view * model * vec4(position, 1.0f);

        FragPos = vec3(model * vec4(position, 1.0f));

        Normal = mat3(transpose(inverse(model))) * normal;

        TexCoords = texCoords;

    }

     

    Fragment-Shader:

    #version 330 core

     

    #define NUMBER_OF_POINT_LIGHTS 24

     

    struct Material {

        sampler2D diffuse;

        sampler2D specular;

        float     shininess;

    };

     

    struct PointLight {

        vec3 position;

        

        vec3 ambient;

        vec3 diffuse;

        vec3 specular;

        

        float constant;

        float linear;

        float quadratic;

    };

     

    struct SpotLight {

        vec3 position;

        vec3 direction;

        float cutOff;

        float outerCutOff;

        

        float constant;

        float linear;

        float quadratic;

        

        vec3 ambient;

        vec3 diffuse;

        vec3 specular;

    };

     

    in vec3 FragPos;

    in vec3 Normal;

    in vec2 TexCoords;

     

    out vec4 color;

     

    uniform vec3 viewPos;

    uniform Material material;

    uniform PointLight pointLight[NUMBER_OF_POINT_LIGHTS];

    uniform SpotLight spotLight;

     

    vec3 CalcPointLight(PointLight pointLight, vec3 normal, vec3 fragPos, vec3 viewDir);

    vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir);

     

    void main() {

        vec3 norm = normalize(Normal);

        vec3 viewDir = normalize(viewPos - FragPos);

        

        vec3 result;

        

        for (int i = 0; i < NUMBER_OF_POINT_LIGHTS; i++) {

            result += CalcPointLight(pointLight[i], norm, FragPos, viewDir);

        }

        

        result += CalcSpotLight(spotLight, norm, FragPos, viewDir);

        

        color = vec4(result, 1.0f);

    }

     

    vec3 CalcPointLight(PointLight pointLight, vec3 normal, vec3 fragPos, vec3 viewDir) {

        vec3 lightDir = normalize(pointLight.position - fragPos);

        

        float diff = max(dot(normal, lightDir), 0.0);

        

        vec3 reflectDir = reflect(-lightDir, normal);

        float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);

        

        float distance = length(pointLight.position - fragPos);

        float attenuation = 1.0f / (pointLight.constant + pointLight.linear * distance + pointLight.quadratic * (distance * distance));

        

        vec3 ambient = pointLight.ambient * vec3(texture(material.diffuse, TexCoords));

        vec3 diffuse = pointLight.diffuse * diff * vec3(texture(material.diffuse, TexCoords));

        vec3 specular = pointLight.specular * spec * vec3(texture(material.specular, TexCoords));

        

        ambient *= attenuation;

        diffuse *= attenuation;

        specular *= attenuation;

        

        return (ambient + diffuse + specular);

    }

     

    vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir) {

        vec3 lightDir = normalize(light.position - fragPos);

        

        float diff = max(dot(normal, lightDir), 0.0);

        

        vec3 reflectDir = reflect(-lightDir, normal);

        float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);

        

        float distance = length(light.position - fragPos);

        float attenuation = 1.0f / (light.constant + light.linear * distance + light.quadratic * (distance * distance));

        

        float theta = dot(lightDir, normalize(-light.direction));

        float epsilon = light.cutOff - light.outerCutOff;

        float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0, 1.0);

        

        vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));

        vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));

        vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords));

        

        ambient *= attenuation * intensity;

        diffuse *= attenuation * intensity;

        specular *= attenuation * intensity;

        

        return (ambient + diffuse + specular);

    }

    It is working, but the colors are strange, here are a few screenshots:

     

    https://www.pic-upload.de/view-35904414/Blender.png.html

    https://www.pic-upload.de/view-35904422/Shader.png.html 


  • Sonar Systems admin
    Likes 0

    That is weird, what video was you on?

  • Sack TV
    Likes 0

    From part 1 to 16.

  • Sack TV
    Likes 0

    I fixed it, the shader has the texture in a struct and i didn’t update the mesh and model classes to the struct.

  • Sonar Systems admin
    Likes 0

    Great to hear.

     

    Feel free to post anymore questions you have.

Login to reply