To provide a little more detail, here’s the code
VS
varying vec4 diffuse, ambient, globalAmbient;
varying vec3 normal, lightDir, halfVector, sd;
varying float dist;
void main()
{
vec3 v_Normal = normalize(gl_NormalMatrix*gl_Normal); // normal to eye space
vec3 v_Tangent = normalize(gl_NormalMatrix*gl_MultiTexCoord2.xyz); // tangent to eye space
vec3 v_Binormal = normalize(gl_NormalMatrix*gl_MultiTexCoord3.xyz); // binormal to eye space
mat3 tangentBasis = mat3( // in column major order
v_Tangent.x, v_Binormal.x, v_Normal.x,
v_Tangent.y, v_Binormal.y, v_Normal.y,
v_Tangent.z, v_Binormal.z, v_Normal.z);
vec4 ecPos;
vec3 aux;
ecPos = gl_ModelViewMatrix * gl_Vertex;
aux = vec3(gl_LightSource[0].position-ecPos);
lightDir = aux;
dist = length(aux);
normal = normalize(gl_NormalMatrix * gl_Normal);// vertex to eye coordinates
halfVector = normalize(gl_LightSource[0].halfVector.xyz);
lightDir = tangentBasis * lightDir;
halfVector = tangentBasis * halfVector;
sd = tangentBasis * gl_LightSource[0].spotDirection;
/* Compute the diffuse, ambient and globalAmbient terms */
diffuse = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse;
ambient = gl_FrontMaterial.ambient * gl_LightSource[0].ambient;
globalAmbient = gl_LightModel.ambient * gl_FrontMaterial.ambient;
/* pass texture coords to fragment shader */
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
}
FS
varying vec4 diffuse, ambient, globalAmbient;
varying vec3 normal, lightDir, halfVector, sd;
varying float dist;
//uniform sampler2D tex;
uniform sampler2D decalMap;
uniform sampler2D normalMap;
void main()
{
vec3 n,l,halfV;
vec4 texel;
float NdotL,NdotHV;
float att;
float spotEffect;
/* The ambient term will always be present */
vec4 color = globalAmbient;
/* a fragment shader can't write a varying variable, hence we need
a new variable to store the normalized interpolated normal */
vec2 tuv = vec2(gl_TexCoord[0].s, -gl_TexCoord[0].t);
n = 2.0 * (texture2D(normalMap, tuv).rgb - 0.5);
n = normalize(n);
l = normalize(lightDir);
/* compute the dot product between normal and ldir */
NdotL = max(dot(n,l),0.0);
if (NdotL > 0.0)
{
spotEffect = dot(normalize(sd), normalize(-l));
if (spotEffect > gl_LightSource[0].spotCosCutoff)
{
spotEffect = pow(spotEffect, gl_LightSource[0].spotExponent);
att = spotEffect / (gl_LightSource[0].constantAttenuation +
gl_LightSource[0].linearAttenuation * dist +
gl_LightSource[0].quadraticAttenuation * dist * dist);
color += att * (diffuse * NdotL + ambient);
halfV = normalize(halfVector);
NdotHV = max(dot(n,halfV),0.0);
color += att * gl_FrontMaterial.specular *
gl_LightSource[0].specular *
pow(NdotHV, gl_FrontMaterial.shininess);
}
}
else
{
//color = vec4(n.x, n.y, n.z, 1.0);
}
texel = texture2D(decalMap,gl_TexCoord[0].st);
color *= texel;
gl_FragColor = color;
}
Here’s a screenshot describing the issue. Notice the black borders. This artefact DOESN’T show up on the ATI board…
Screenshot