opengllwjglfragment-shaderlightingphong

Specular lighting in LWJGL 3 not working [Phong Shading]


I implemented lighting in my engine. But there is some problem the object does not lights up properly The object that gets rendered The specular lighting does not work at all

Here is the vertex shader :

#version 330

layout (location = 0) in vec3 position;
layout (location = 1) in vec2 tex_coords;
layout (location = 2) in vec3 normals;

uniform mat4 projectionMatrix;
uniform mat4 worldMatrix;
uniform mat4 viewMatrix;

out vec2 coords;
out vec3 vertexNormals;
out vec3 vertexPos;

void main() {
    vec4 mVerPos = worldMatrix * vec4(position, 1.0);
    gl_Position = projectionMatrix * viewMatrix * worldMatrix * vec4(position, 1.0);
    coords = tex_coords;
    vertexNormals = normalize(worldMatrix * vec4(normals, 0.0)).xyz;
    vertexPos = mVerPos.xyz;
}

Here is the fragment shader :

#version 330

struct Material {
    vec4 ambient;
    vec4 diffuse;
    vec4 specular;
    int hasTexture;
    float reflectance;
};

struct PointLight {
    vec3 color;
    vec3 position;
    float intensity;
    float constant;
    float linear;
    float exponent;
};

struct DirLight {
    vec3 position;
    vec3 color;
    float intensity;
};

out vec4 fragColor;

in vec2 coords;
in vec3 vertexNormals;
in vec3 vertexPos;

uniform sampler2D sampler;
uniform vec3 ambientColor;
uniform Material material;
uniform PointLight pointLight;
uniform float specularPower;
uniform DirLight dirLight;

vec4 ambientC;
vec4 diffuseC;
vec4 specularC;

void setUpColor(Material material, vec2 coords) {
    if (material.hasTexture == 1) {
        ambientC = texture(sampler, coords);
        diffuseC = ambientC;
        specularC = ambientC;
    }
    else {
        ambientC = material.ambient;
        diffuseC = material.diffuse;
        specularC = material.specular;
    }
}

vec4 calcLightColor(vec3 lightColor, float lightIntensity, vec3 position, vec3 to_light_dir, vec3 normal) {
    vec4 diffuseColour = vec4(0, 0, 0, 0);
    vec4 specColour = vec4(0, 0, 0, 0);

    // Diffuse Light
    float diffuseFactor = max(dot(normal, to_light_dir ), 0.0);
    diffuseColour = diffuseC * vec4(lightColor, 1.0) * lightIntensity * diffuseFactor;

    // Specular Light
    vec3 camera_direction = normalize(-position);
    vec3 from_light_dir = -to_light_dir;
    vec3 reflected_light = normalize(reflect(from_light_dir, normal));
    float specularFactor = max(dot(camera_direction, reflected_light), 0.0);
    specularFactor = pow(specularFactor, specularPower);
    specColour = specularC * lightIntensity * specularFactor * material.reflectance * vec4(lightColor, 1.0);
    
    return (diffuseColour + specColour);
};


vec4 calcPointLight(PointLight light, vec3 position, vec3 normal)
{
    vec3 light_direction = light.position - position;
    vec3 to_light_source  = normalize(light_direction);
    vec4 lightColor = calcLightColor(light.color, light.intensity, position, to_light_source, normal);

    // Attenuation
    float distance = length(light_direction);
    float attenuationInv = light.constant + light.linear * distance +
        light.exponent * distance * distance;
    return lightColor / attenuationInv;
}

vec4 calcDirLight(DirLight light, vec3 position, vec3 normal) {
    return calcLightColor(light.color, light.intensity, position, normalize(light.position), normal);
}

void main() {

    setUpColor(material, coords);
    vec4 diffuseSpecularComp = calcDirLight(dirLight, vertexPos, vertexNormals);
    diffuseSpecularComp += calcPointLight(pointLight, vertexPos, vertexNormals);
    fragColor = ambientC * vec4(ambientColor, 1) + diffuseSpecularComp;
    
}

Here is the source code : https://www.dropbox.com/scl/fo/hwlnz913jm6c9xli2dsb6/h?dl=0&rlkey=b2zj0w6kttwu3b1di9rejwnq3

When I changed the value of zero at float diffuseFactor = max(dot(normal, to_light_dir ), 0.0); and at float specularFactor = max(dot(camera_direction, reflected_light), 0.0); the to something above like 0.1 this what I get Later result but the specular does not work at all.


Solution

  • There are a couple of problems in your code, but I'm not entirely sure which causes the problem.

    Problems

    Other random observations

    Joey de Vries has amazing tutorials, including the Phong shading (using C++). In the One last thing section he also explains why it's important to use the inverse transposed matrix to transform the normal.