Okay, I actually think I got this one on my own. I'd still appreciate someone looking it over though, if that's okay:
vertex shader:
attribute vec4 tangent;varying vec3 L, SD, H;varying float distance;void main(void){ // set the vertex position in eye space gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; // create the tangent matrix mat3 tbn; tbn[0] = tangent.xyz; tbn[1] = cross(tangent.xyz, gl_Normal) * tangent.w; tbn[2] = gl_Normal; // get the light position in object space vec4 P = gl_ModelViewMatrixInverse * gl_LightSource[0].position; if(gl_LightSource[0].position.w != 0.0) { // then the vector from the light to the vertex vec4 LV = P - gl_Vertex; distance = length(LV.xyz); // put the light vector into tangent space L = normalize(tbn * LV.xyz); } else { distance = 1.0; // put the light vector into tangent space L = normalize(tbn * P.xyz); } vec4 half = gl_ModelViewMatrixInverse * gl_LightSource[0].halfVector; SD = normalize(tbn * gl_LightSource[0].spotDirection); H = normalize(tbn * half.xyz); // setup the vertex textures gl_TexCoord[0] = gl_MultiTexCoord0;}
fragment shader:
uniform sampler2D detail, normalmap, specmap;varying vec3 L, SD, H;varying float distance;void main(void){ // get the attenuation float attenuation = 1.0; if(gl_LightSource[0].position.w != 0.0) { float distance2 = distance * distance; attenuation = 1.0 / (gl_LightSource[0].constantAttenuation + (gl_LightSource[0].linearAttenuation * distance) + (gl_LightSource[0].quadraticAttenuation * distance2)); } // get the spotlight float spotlight = 1.0; if(gl_LightSource[0].spotCutoff != 180.0) { float value = max(dot(L, SD), 0.0); if(value < gl_LightSource[0].spotCosCutoff) spotlight = 0.0; else spotlight = pow(value, gl_LightSource[0].spotExponent); } // get the normal vec3 normal = normalize(2.0 * texture2D(normalmap, vec2(gl_TexCoord[0])).xyz - 1.0); // get the diffuse amount float diffuse = max(dot(L, normal), 0.0); // get the specular amount float specular = max(dot(H, normal), 0.0); // get the specular color vec4 speccolor = texture2D(specmap, vec2(gl_TexCoord[0])) * gl_LightSource[0].specular; // get the texture color vec4 texcolor = texture2D(detail, vec2(gl_TexCoord[0])); // final color float temp = attenuation * spotlight; gl_FragColor = gl_FrontLightModelProduct.sceneColor; gl_FragColor += temp * (gl_FrontLightProduct[0].ambient + (diffuse * gl_FrontLightProduct[0].diffuse)); gl_FragColor *= texcolor; // seperate specular gl_FragColor += temp * (pow(specular, gl_FrontMaterial.shininess) * speccolor);}
It seems to work. I see a sort of gloss on the metalic sections of the models. I assume that's what I should be seeing? The gloss moves as I move, just as I would expect in the real world. It's really subtle though and I cranked the shininess up to 128. It's a cool effect, I just hope I'm doing it properly.