Implementing Phong reflection modell with Gouraud Shading in vertex shader

Hello my Friends!

As you can see in the title I am trying to implement. As far as I understood the Phong refelction modell, the final light is calculated as follows:

final Light = ambient + diffuse + specular
ambient = Intensity of light * constant_Ambient
diffuse = Intensity of light source * constant_Diffuse * dotProduct(-lightDirection * normal of face)
specular = Intensity of light source * constant_Specular * dotProduct(viewVector, reflectionVector of lightDirection)
final Color of Vertex = Color of Vertex * finalLight

I’ve tried to implement that in my vertex shader:

#version 430 core

layout(location = 0) in vec3 position;
layout(location = 1) in vec3 normal;

out VertexData {
    vec3 position_world;
} vert;
out vec3 fragColor;

uniform vec3 diffuseColor; //is set as vec3(1.0f, 0.0f, 0.0f)
uniform mat4 modelMatrix;
uniform mat4 viewProjMatrix;

uniform vec3 IAmbient; //is set as vec3(1.0f, 1.0f, 1.0f)
uniform float kAmbient; //is set as 0.1f
uniform vec3 Intensity; //is set as vec3(0.8f, 0.8f, 0.8f)
uniform float kDiffuse; //is set as 0.9f
uniform float kSpecular; //is set as 0.3f
uniform float alpha; //is set as 10.0f

uniform vec3 lightDirection; //is set as vec3(0.0f, -1.0f, -1.0f)
uniform vec3 lightPosition; //not used yet, only directional light is implemented
uniform vec3 view; //cameraPosition, I am using a camera orbiting around the zero point, so cameraPosition as viewVector should be right I guess

void main() {
    gl_Position = viewProjMatrix * modelMatrix * vec4(position, 1);

    vec4 transformedNormal = transpose(inverse(modelMatrix)) * vec4(normal, 1);
    vec3 newNormal = normalize(;
    vec3 r = reflect(normalize(lightDirection), newNormal);

    vec3 ambient = IAmbient * kAmbient;
    vec3 diffuse = Intensity * kDiffuse * dot(-lightDirection, newNormal);
    vec3 specular = Intensity * kSpecular * pow(dot(normalize(view), normalize(r)), alpha);
    vec3 light = ambient + diffuse + specular;

    fragColor = diffuseColor * light;

My Problem: Without adding specular in vec3 light, so just vec3 light = ambuse + diffuse, I get something right, I hope… :slight_smile:

With specular in vec3 light added, so vec3 light = ambuse + diffuse + specular, I get something weird, what I don’t understand… :frowning:

My Fragment shader looks like this:

#version 430 core

in VertexData {
    vec3 position_world;
} vert;
in vec3 fragColor;

out vec4 color;

void main() {    
    color = vec4(fragColor, 1);

I hope somebody can help me since I have been trying to implement that for the first time and really cannot see what I am missing. :doh:

You need to clamp the results of the dot products to avoid negative intensities, e.g.

max(0.0, dot(...));

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.