0

When implementing PhongModel shading. The Specular term appears on both sides of the geometry. The specular term is being computed using the Half Vector.

In the front output image it seems that it's computed correctly. The light is behind the camera and the object is in front of the camera.

[Light... camera... object]

But when going to the other side, even if there is no diffuse term, I still get some specular, which I am not sure I should. In the pictures following pictures, both object and light are in front of the camera, and the light is behind the object.

[Camera... object... light]

I thought that maybe should the specular by multiplied by sign(fLDotN)? But the results don't seem fine. How is it usually handled?

My guess is that I am

The light uniform position is set in camera space:

vec3 ptLightPos_CS=vec3(matLookAt*vec4(ptLightPos, 1));

Result image with normals and halfvector: Phong Specular+Diffuse Results

VertexShader

// Input layouts
in vec3 vertexPosition;
in vec3 vertexNormal;
in vec2 vertexTexCoord;
in vec3 vertexTangent;
in vec3 vertexBitangent;

// Output layouts

// Uniform variables
uniform VertexUniforms
{
    mat4 uniform_Projection;
    mat4 uniform_ModelView;
    mat4 uniform_NormalMatrix;
};

// In variables

// Out variables
out vec2 vs_uv;
out vec3 vs_normal;
out vec3 vs_tangent;
out vec3 vs_bitangent;
out vec3 vs_pos;
// Global variables

/*************/

void main()
{
    // Convert the vertex to clip space
    vec3 vcPos=vec3(uniform_ModelView*vec4(vertexPosition, 1.0f));
    vec4 vertexProj = uniform_Projection * vec4(vcPos, 1.0f);

    ///--- Tangent space
    vs_normal=normalize(vec3(uniform_NormalMatrix * vec4(vertexNormal, 0)));
    vs_tangent=normalize(vec3(uniform_NormalMatrix * vec4(vertexTangent, 0)));
    vs_bitangent=normalize(vec3(uniform_NormalMatrix * vec4(vertexBitangent, 0)));

    ///---
    vs_pos=vcPos;

    // UV
    vs_uv=vertexTexCoord;

    gl_Position = vertexProj;   
}

FragmentShader

// Output layouts
out vec4 outColor;

// Uniform variables
uniform vec3 uniform_v3LightDiffuseColor;
uniform vec3 uniform_v3LightSpecularColor;
uniform sampler2D uniform_tDiffuse;
uniform sampler2D uniform_tNormal;
uniform vec3 uniform_v3LightPos;

// In variables
in vec2 vs_uv;
in vec3 vs_normal;
in vec3 vs_tangent;
in vec3 vs_bitangent;
in vec3 vs_pos;
// Out variables

// Global variables

/*************/
#define PI 3.141592

void main()
{   
    const vec3 T=normalize(vs_tangent);
    const vec3 B=normalize(vs_bitangent);
    const vec3 N=normalize(vs_normal);
    const mat3 mTBN=mat3(T, B, N);  
    vec3 vNormal=mTBN*((texture2D(uniform_tNormal, vs_uv).xyz*2.0-1.0));    
    vNormal=normalize(vNormal);

    const vec3 vEye=normalize(-vs_pos);
    const vec3 vLightDir=normalize(uniform_v3LightPos-vs_pos);
    const vec3 vLightDiffuse=vec3(0.5,0.5,0.5);//uniform_v3LightDiffuseColor;
    const vec3 vLightSpecular=vec3(0.5,0.5,0.5);//uniform_v3LightSpecularColor;
    const vec3 vMatDiffuse=vec3(0.5,0.5,0.5);//texture2D(uniform_tDiffuse, vs_uv).xyz;
    const vec3 vMatSpecular=vMatDiffuse;
    const float fMatSpecularPower=0.8;
    const float fLDotN=max(dot(vLightDir, vNormal), 0);

    //-- Diffuse
    float fDiffuseContrib = fLDotN;

    //-- Specular
    vec3 v3HalfVect=normalize(vEye+vLightDir);
    float fSpecularContrib=pow(clamp(dot(v3HalfVect, vNormal), 0.0, 1.0), fMatSpecularPower);
    vec3 vDiffuse=fDiffuseContrib*vMatDiffuse*vLightDiffuse;
    vec3 vSpecular=fSpecularContrib*vMatSpecular*vLightSpecular;

    vec3 vcFinal=vDiffuse+vSpecular;    
    outColor = vec4(vcFinal, 1);    

    //outColor = vec4(vNormal.xyz, 1);
    //outColor = vec4(vEye.xyz, 1);
    //outColor = vec4(vLightDir.xyz, 1);
    //outColor = vec4(v3HalfVect.xyz, 1);
}
Eder
  • 78
  • 8

1 Answers1

0

You do not compute specular reflection if (dot(vNormal, vLightDir) < 0) and set it to 0.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
Ondrej
  • 503
  • 3
  • 21