3
\$\begingroup\$

Hello I wrote a simple OpenGl program using GLSL to render a simple uv mapped plane using the normal mapping technics.

Here's the display with a simple phong shading (without normal mapping) :

enter image description here

Now with normal mapping with the same camera angle :

enter image description here

And from an other position :

enter image description here

As you can see only the specular light is rendered (in my example I have no ambient light). So the problems seems to comes from the diffuse light computation.

Here's my vertex shader (I want to precise that the variables with the extensions *_ns, *cs and *_ts mean 'normal space', 'camera space' and 'tangent space'. Plus, for a sake of simplicity I wrote in hard the values of the normal, tangent and bitangent vectors -> my plane being described horizontaly so the normals for each vertex are vec3(0.0f, 1.0f, 0.0f). In this example the tangent and bitangent vectors can be deducted very easily) :

#version 400

layout (location = 0) in vec4 VertexPosition;
layout (location = 1) in vec2 VertexTexture;

uniform mat3 NormalMatrix;
uniform mat4 ModelViewMatrix;
uniform mat4 MVP;

uniform int LightCount;

struct Light
{
    vec4 Position;
    vec3 La, Ld, Ls;
};

uniform Light LightInfos[1];

out vec2 TexCoords;

out vec3 lightDir_ts;
out vec3 viewDir_ts;

void main(void)
{
    TexCoords = VertexTexture;

    vec3 Normal_ns = NormalMatrix * vec3(0.0f, 1.0f, 0.0f);
    vec3 Tangent_ns = NormalMatrix * vec3(1.0f, 0.0f, 0.0f);
    vec3 Bitangent_ns = NormalMatrix * vec3(0.0f, 0.0f, -1.0f);

    mat3 TBN =  mat3(
        Tangent_ns.x, Bitangent_ns.x, Normal_ns.x,
            Tangent_ns.y, Bitangent_ns.y, Normal_ns.y,
                Tangent_ns.z, Bitangent_ns.z, Normal_ns.z);

    vec4 Position_cs = ModelViewMatrix * VertexPosition;

    lightDir_ts = TBN * (vec3(LightInfos[0].Position) - Position_cs.xyz);
    viewDir_ts = TBN * -Position_cs.xyz;

    gl_Position = MVP * VertexPosition;
}

And the fragment shader :

#version 400

in vec2 TexCoords;

layout (location = 0) out vec4 FragColor;

uniform sampler2D ColorMapSampler;
uniform sampler2D BumpMapSampler;

in vec3 lightDir_ts;
in vec3 viewDir_ts;

struct Light
{
    vec4 Position;
    vec3 La, Ld, Ls;
};

struct Material
{
    vec3 Ka, Kd, Ks;
    float Shininess;
};

uniform Light LightInfos[1];
uniform Material MaterialInfos;

vec3 Basic_Phong_Shading(vec3 bumpNormalDir, vec3 lightDir, vec3 viewDir, vec3 texDiffuseColor)
{
    vec3 reflectDir = reflect(-lightDir, bumpNormalDir);

    vec3 Ambient = LightInfos[0].La * MaterialInfos.Ka;
    vec3 Diffuse = LightInfos[0].Ld * MaterialInfos.Kd * max(dot(lightDir, bumpNormalDir), 0.0f) * texDiffuseColor;
    vec3 Specular = LightInfos[0].Ls * MaterialInfos.Ks * pow(max(dot(reflectDir, viewDir), 0.0f), MaterialInfos.Shininess);

    return (Ambient + Diffuse + Specular);
}

void main(void)
{
    vec3 LightIntensity = vec3(0.0f);

    vec4 texDiffuseColor = texture2D(ColorMapSampler, TexCoords);

    vec3 bumpNormalDir_ts = normalize(texture2D(BumpMapSampler, TexCoords).xyz * 2.0f - 1.0f);

    LightIntensity = Basic_Phong_Shading(
        -bumpNormalDir_ts, normalize(lightDir_ts), normalize(viewDir_ts), texDiffuseColor.rgb
    );

    FragColor = vec4(LightIntensity, 1.0f);
}

Now I noticed if I remove the code 'max(dot(lightDir, bumpNormalDir), 0.0f)' in the diffuse light evaluation in the function 'Basic_Phong_Shading' I have the following display:

enter image description here

So it looks like a simple ambient light plus the specular light but of course the diffuse light is not correct. So it means that the code 'max(dot(lightDir, bumpNormalDir), 0.0f)' return the 0 value. So I don't understand why my vector 'lightDir' or 'bumpNormalDir' should not be correct. However, the specular light seems to be correct so it should not comes from the normal extracted from the normal map. Does the problem comes from the lightDir vector or other one ? Does my TBN matrix is correct ?

I'm really lost. I tried everything I could without success. I have already the same display with just the specular light and the rest of the geometry in black. Does anyone can help me please ? Thanks a lot in advance for your help.

\$\endgroup\$

closed as off-topic by Josh Aug 1 '14 at 15:31

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Questions about debugging a problem in your project must present a concise selection of code and context so as to allow a reader to diagnose the issue without needing to read all of your code or to engage in extensive back-and-forth dialog. For more information, see this meta thread." – Josh
If this question can be reworded to fit the rules in the help center, please edit the question.

  • 2
    \$\begingroup\$ you probably have the normal flipped, so max(dot, 0) will always return 0 because the dot is less than zero. if I were you, I will use a pen and paper to visualize the vector directions. Also use a debugger to check the vector components. \$\endgroup\$ – concept3d Mar 4 '14 at 11:25
  • 1
    \$\begingroup\$ also check this line vec3 reflectDir = reflect(-lightDir, bumpNormalDir); you are flipping the lightDir maybe you are not supposed to, because it's passed in the correct direction. \$\endgroup\$ – concept3d Mar 4 '14 at 11:29
  • 1
    \$\begingroup\$ Thank you very much. The normal vector was effectively flipped because I passed -bumpNormalDir_ts instead of bumpNormalDir_ts for the first argument of the 'Basic_Phong_Shading' function. This is stupid. So effectively the normal was heading down. Thanks so much again. Bye. \$\endgroup\$ – user1364743 Mar 4 '14 at 12:40