Butterman, in case you are still fighting with smoothing groups, here is a shader pair that does not care about mesh-supplied normals, and produces a rather faceted shading. on the plus side, it does normal mapping. well, for one light only.
dont forget to set up your standard gl material properties, and pass the attribs of your light as a standard gl light object, as this is where the shader reads all those data from.
CODE
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// tangential space bump mapping, vertex shader
varying vec2 tc_i; // color/bumpmap coords
varying vec3 p_obj_i; // vertex position in in object space
varying vec3 l_obj_i; // light_source vector in object space
varying vec3 h_obj_i; // half-direction vector in object space
void main()
{
gl_Position = ftransform();
tc_i = gl_MultiTexCoord0.xy;
vec4 lp_obj = gl_ModelViewMatrixInverse * gl_LightSource[0].position;
vec4 vp_obj = gl_ModelViewMatrixInverse[3];
vec3 l_obj = normalize(lp_obj.xyz - gl_Vertex.xyz * lp_obj.w);
vec3 v_obj = normalize(vp_obj.xyz - gl_Vertex.xyz * vp_obj.w);
p_obj_i = gl_Vertex.xyz;
l_obj_i = l_obj;
h_obj_i = normalize(l_obj + v_obj);
}
CODE
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// tangential space bump mapping, fragment shader
uniform sampler2D normalMap;
uniform sampler2D diffuseMap;
varying vec2 tc_i; // color/bumpmap coords
varying vec3 p_obj_i; // vertex position in in object space
varying vec3 l_obj_i; // light_source vector in object space
varying vec3 h_obj_i; // half-direction vector in object space
void main()
{
vec3 l = normalize(l_obj_i);
vec3 h = normalize(h_obj_i);
vec2 tc_dx = dFdx(tc_i);
vec2 tc_dy = dFdy(tc_i);
vec3 p_dx = dFdx(p_obj_i);
vec3 p_dy = dFdy(p_obj_i);
vec3 t = normalize(tc_dy.y * p_dx - tc_dx.y * p_dy);
vec3 b = normalize(tc_dy.x * p_dx - tc_dx.x * p_dy); // sign inverted
vec3 n = cross(b, t); // sign inverted
mat3 tbn = mat3(t, b, n);
vec3 l_tan = l * tbn;
vec3 h_tan = h * tbn;
vec3 bump = normalize(texture2D(normalMap, tc_i).xyz * 2.0 - 1.0);
vec3 diffuse = gl_FrontLightProduct[0].diffuse.xyz * max(dot(l_tan, bump), 0.0);
vec3 specular = gl_FrontLightProduct[0].specular.xyz * pow(max(dot(h_tan, bump), 0.0), gl_FrontMaterial.shininess);
vec4 tcolor = texture2D(diffuseMap, tc_i);
gl_FragColor = vec4(tcolor.xyz * (gl_FrontLightModelProduct.sceneColor.xyz + diffuse) + specular,
gl_FrontLightModelProduct.sceneColor.w * tcolor.w);
}
dont forget to set up your standard gl material properties, and pass the attribs of your light as a standard gl light object, as this is where the shader reads all those data from.
CODE
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// tangential space bump mapping, vertex shader
varying vec2 tc_i; // color/bumpmap coords
varying vec3 p_obj_i; // vertex position in in object space
varying vec3 l_obj_i; // light_source vector in object space
varying vec3 h_obj_i; // half-direction vector in object space
void main()
{
gl_Position = ftransform();
tc_i = gl_MultiTexCoord0.xy;
vec4 lp_obj = gl_ModelViewMatrixInverse * gl_LightSource[0].position;
vec4 vp_obj = gl_ModelViewMatrixInverse[3];
vec3 l_obj = normalize(lp_obj.xyz - gl_Vertex.xyz * lp_obj.w);
vec3 v_obj = normalize(vp_obj.xyz - gl_Vertex.xyz * vp_obj.w);
p_obj_i = gl_Vertex.xyz;
l_obj_i = l_obj;
h_obj_i = normalize(l_obj + v_obj);
}
CODE
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// tangential space bump mapping, fragment shader
uniform sampler2D normalMap;
uniform sampler2D diffuseMap;
varying vec2 tc_i; // color/bumpmap coords
varying vec3 p_obj_i; // vertex position in in object space
varying vec3 l_obj_i; // light_source vector in object space
varying vec3 h_obj_i; // half-direction vector in object space
void main()
{
vec3 l = normalize(l_obj_i);
vec3 h = normalize(h_obj_i);
vec2 tc_dx = dFdx(tc_i);
vec2 tc_dy = dFdy(tc_i);
vec3 p_dx = dFdx(p_obj_i);
vec3 p_dy = dFdy(p_obj_i);
vec3 t = normalize(tc_dy.y * p_dx - tc_dx.y * p_dy);
vec3 b = normalize(tc_dy.x * p_dx - tc_dx.x * p_dy); // sign inverted
vec3 n = cross(b, t); // sign inverted
mat3 tbn = mat3(t, b, n);
vec3 l_tan = l * tbn;
vec3 h_tan = h * tbn;
vec3 bump = normalize(texture2D(normalMap, tc_i).xyz * 2.0 - 1.0);
vec3 diffuse = gl_FrontLightProduct[0].diffuse.xyz * max(dot(l_tan, bump), 0.0);
vec3 specular = gl_FrontLightProduct[0].specular.xyz * pow(max(dot(h_tan, bump), 0.0), gl_FrontMaterial.shininess);
vec4 tcolor = texture2D(diffuseMap, tc_i);
gl_FragColor = vec4(tcolor.xyz * (gl_FrontLightModelProduct.sceneColor.xyz + diffuse) + specular,
gl_FrontLightModelProduct.sceneColor.w * tcolor.w);
}