Home:ALL Converter>Implementing Normal Mapping using OpenGL/GLSL

Implementing Normal Mapping using OpenGL/GLSL

Ask Time:2015-03-14T06:13:45         Author:haksist

Json Formatter

I'm learning GLSL and trying to implement some lighting and mapping tricks. I'm working with ShaderDesigner tool. After coding normal mapping I recognized that my model illumination looks not real. Here is my code and some pictures. If it possible tell me what is my problem.

Vertex Shader

#define MAX_LIGHTS 1

struct LightProps
{
    vec3 direction[MAX_LIGHTS];
};

attribute vec3 tangent;
attribute vec3 bitangent;

varying LightProps lights;

void main()
{
    vec3 N = normalize(gl_NormalMatrix*gl_Normal);
    vec3 T = normalize(gl_NormalMatrix*tangent);
    vec3 B = normalize(gl_NormalMatrix*bitangent);

    mat3 TBNMatrix = mat3(T,B,N);

    vec4 vertex = gl_ModelViewMatrix*gl_Vertex;
    for(int i = 0; i < MAX_LIGHTS; i++)
    {
        vec4 lightPos = gl_LightSource[i].position;
        lights.direction[i] = vec3(lightPos.w > 0 ? lightPos-vertex : lightPos);
        lights.direction[i] *= TBNMatrix;
    }

    gl_TexCoord[0] = gl_MultiTexCoord0;
    gl_Position = gl_ModelViewProjectionMatrix*gl_Vertex;
} 

Fragment Shader

#define MAX_LIGHTS 1
struct LightProps
{
    vec3 direction[MAX_LIGHTS];
};

uniform sampler2D textureUnit;
uniform sampler2D normalTextureUnit;
uniform vec4 TexColor;

varying LightProps lights;

void main()
{
    vec3 N = normalize(texture2D(normalTextureUnit,gl_TexCoord[0].st).rgb*2.0-1.0);

    vec4 color = vec4(0,0,0,0);
    for(int i = 0; i < MAX_LIGHTS; i++)
    {
        vec3 L = lights.direction[i];
        float dist = length(L);
        L = normalize(L);

        float NdotL = max(dot(N,L),0.0);

        if(NdotL > 0)
        {
            float att = 1.0;
            if(gl_LightSource[i].position.w > 0)
            {
                att = 1.0/ (gl_LightSource[i].constantAttenuation +
                gl_LightSource[i].linearAttenuation * dist +
                gl_LightSource[i].quadraticAttenuation * dist * dist);
            }
            
            vec4 ambient = gl_FrontLightProduct[i].ambient;
            vec4 diffuse = clamp(att*NdotL*gl_FrontLightProduct[i].diffuse,0,1);
        
            color += att*(ambient+diffuse);
        }
    }

    vec4 textureColor = texture2D(textureUnit, vec2(gl_TexCoord[0]));
    gl_FragColor = TexColor*textureColor + gl_FrontLightModelProduct.sceneColor + color;
}

I set TexColor to (0.3,0.3,0.3,1.0) and take screenshots:

Screenshot

  Screenshot

There is little bit lighting when I rotate camera and light to left, but when I rotate to right the plane got fully illuminated.I think there is something wrong because without normal mapping plane looks same from to sides. Here is normal texture. Thanks in advance.

Normal Map:

  Normal Texture

Author:haksist,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/29042849/implementing-normal-mapping-using-opengl-glsl
yy