0

I have a very strange behaviour of specular(phong light model) light. It seems to be appering on both sides of all objects. Does anyone know what could be the issue ? The actual calculation seems to be alright, as I can see that the light changes its position as object rotates.

#version 330

in vec4 CameraPos0;
in vec3 Pos0;
in vec4 Colour0;
in vec3 Normal0;

out vec4 FragColor;

 // Ambient light parameters
uniform vec3 gAmbientLightIntensity;

// Directional light parameters
uniform vec3 gDirectionalLightIntensity;
uniform vec3 gDirectionalLightDirection;

// Specular light parameter
uniform vec3 gSpecularLightIntensity;
uniform vec3 gLightSourcePosition;
uniform vec3 gCameraPosition;

// Material constants
uniform float gKa;
uniform float gKd;
uniform float gKs;

void main()
{

    // Calculate the ambient light intensity at the vertex
    // Ia = Ka * ambientLightIntensity
    vec4 ambientLightIntensity = gKa * vec4(gAmbientLightIntensity, 1.0);

    // Setup the light direction and normalise it
    vec3 lightDirection = normalize(-gDirectionalLightDirection);

    //lightDirection = normalize(gDirectionalLightDirection);
    // Id = kd * lightItensity * N.L
    // Calculate N.L
    float diffuseFactor = dot(Normal0, lightDirection);
    diffuseFactor = clamp(diffuseFactor, 0.0, 1.0);
    // N.L * light source colour * intensity
    vec4 diffuseLightIntensity = gKd * vec4(gDirectionalLightIntensity, 1.0f) * diffuseFactor;

    // Phong light
    vec3 L = normalize(gLightSourcePosition - Pos0);   
    vec3 V = normalize(-Pos0); 
    vec3 R = normalize(2 * Normal0 * dot(Normal0, L) - L);

    float specularFactor = pow(dot(R, V), 0.1f);
    vec4 specularLightIntensity = gKs * vec4(gSpecularLightIntensity, 1.0f) * specularFactor;
    specularLightIntensity = clamp(specularLightIntensity, 0.0, 1.0);

    // Final vertex colour is the product of the vertex colour
    // and the total light intensity at the vertex 
    vec4 lightedFragColor = Colour0 * (ambientLightIntensity + diffuseLightIntensity + specularLightIntensity);

    FragColor = lightedFragColor;
}

Vertex Shader

#version 330

layout (location = 0) in vec3 Position;
layout (location = 1) in vec3 Normal;
layout (location = 2) in vec4 Colour;

out vec3 Pos0;
out vec4 Colour0;
out vec3 Normal0;
out vec4 CameraPos0;

uniform mat4 gModelToWorldTransform;
uniform mat4 gWorldToViewTransform;
uniform mat4 gProjectionTransform;

void main()
{  
    vec4 vertexPositionInModelSpace = vec4(Position, 1);
    vec4 vertexInWorldSpace = gModelToWorldTransform * vertexPositionInModelSpace;
    vec4 vertexInViewSpace = gWorldToViewTransform * vertexInWorldSpace;
    vec4 vertexInHomogeneousClipSpace = gProjectionTransform * vertexInViewSpace;
    gl_Position = vertexInHomogeneousClipSpace;

    vec3 normalInWorldSpace = (gModelToWorldTransform * vec4(Normal, 0.0)).xyz;
    normalInWorldSpace = normalize(normalInWorldSpace);

    Normal0 = normalInWorldSpace;
    CameraPos0 = vertexInViewSpace;
    Pos0 = vertexInWorldSpace.xyz;
    Colour0 = Colour;
}

enter image description here

tvoloshyn
  • 407
  • 8
  • 22
  • Are you applying any operation besides rotation in your object->world matrix? If so, then you should not use ***that*** matrix to transform your normals. – Andon M. Coleman Nov 18 '13 at 23:10

1 Answers1

0

you need to clamp the dot result from the saturation calculus because on the back side the result is negative and the pow can return a positive number instead of clamping it to zero.

float specularFactor = pow(clamp(dot(R, V),0.0,1.0), 0.1f);

Edit:

Also the V should be a vector pointing to the camera position, not to the vertex position in world space:

vec3 V = normalize(CameraPos0 - Pos0);

Raxvan
  • 6,257
  • 2
  • 25
  • 46
  • Unfortunatelly, this didn't help. Still same issue. – tvoloshyn Nov 18 '13 at 21:04
  • didn't help either. I think there might be something wrong in vertex shader as well, because I'm not sure what exactly should I pas for Pos0 and CamerPos0. Is it in world space or in model space ? – tvoloshyn Nov 18 '13 at 21:23