How to add a Specular Map on this specific OpenGL 2.0 Normal/Parallax Shader

#1

Hi, I am trying to add specular mapping on an existing GLSL 2.0 Normal/Parallax Mapping implementation by dhpoware here:

I’m not really that familiar with GLSL shaders and would like to get some help in setting this up and making it work with the GLSL code below.

Here is the Vertex shader

#version 110

varying vec3 lightDir;
varying vec3 halfVector;

void main()
{
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
    gl_TexCoord[0] = gl_MultiTexCoord0;

    vec3 n = normalize(gl_NormalMatrix * gl_Normal);
    vec3 t = normalize(gl_NormalMatrix * gl_MultiTexCoord1.xyz);
    vec3 b = cross(n, t) * gl_MultiTexCoord1.w;

    mat3 tbnMatrix = mat3(t.x, b.x, n.x,
                          t.y, b.y, n.y,
                          t.z, b.z, n.z);

    lightDir = gl_LightSource[0].position.xyz;
    lightDir = tbnMatrix * lightDir;

    halfVector = gl_LightSource[0].halfVector.xyz;
    halfVector = tbnMatrix * halfVector;
}

then the Fragment Shader

#version 110

uniform sampler2D colorMap;
uniform sampler2D normalMap;
uniform sampler2D heightMap;

uniform bool enableParallax;
uniform float scale;
uniform float bias;

varying vec3 lightDir;
varying vec3 halfVector;

void main()
{
    vec2 newTexCoord;
    vec3 h = normalize(halfVector);

    if (enableParallax == true)
    {
        float height = texture2D(heightMap, gl_TexCoord[0].st).r;

        height = height * scale + bias;
        newTexCoord = gl_TexCoord[0].st + (height * h.xy);
    }
    else
    {
        newTexCoord = gl_TexCoord[0].st;
    }

    vec3 n = normalize(texture2D(normalMap, newTexCoord).rgb * 2.0 - 1.0);
    vec3 l = normalize(lightDir);

    float nDotL = max(0.0, dot(n, l));
    float nDotH = max(0.0, dot(n, h));
    float power = (nDotL == 0.0) ? 0.0 : pow(nDotH, gl_FrontMaterial.shininess);

    vec4 ambient = gl_FrontLightProduct[0].ambient;
    vec4 diffuse = gl_FrontLightProduct[0].diffuse * nDotL;
    vec4 specular = gl_FrontLightProduct[0].specular * power;
    vec4 color = gl_FrontLightModelProduct.sceneColor + ambient + diffuse + specular;

    gl_FragColor = color * texture2D(colorMap, newTexCoord);
}
#2

By “specular mapping”, do you mean an environment map (i.e. a texture containing light sources, rather than a single point)? Or do you mean storing the specular reflectance parameters (colour and/or shininess) in a texture rather than using values which are constant for the surface?

#3

Yes, it is the specular reflectance in a texture.

#4
uniform sampler2D specularMap;
...

    vec4 specParams = texture2D(specularMap, newTexCoord);

    float power = (nDotL == 0.0) ? 0.0 : pow(nDotH, specParams.a);

    vec4 specular = gl_LightSource[0].specular * vec4(specParams.rgb, 1) * power;
#5

Thanks GClements, I’m getting a white overlay of the texture instead of the specular hilights, so it’s not the result that I am looking for and hoping to get.