Jump to content

  • Log In with Google      Sign In   
  • Create Account

Chozo

Member Since 21 Nov 2002
Offline Last Active May 17 2012 09:11 PM

#2806711 GLSL Specular Map question

Posted by Chozo on 07 December 2004 - 06:09 PM

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.


PARTNERS