Jump to content

  • Log In with Google      Sign In   
  • Create Account


GLSL Specular Map question


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
1 reply to this topic

#1 Chozo   Members   -  Reputation: 176

Like
0Likes
Like

Posted 07 December 2004 - 04:14 PM

So I finally got normal maps working (and they look fantastic!). My next quest is to get specular maps working. Doom3 specular maps are either RGBA or RGB textures, so my initial guess is to do something like this:
    // final color
    gl_FragColor = gl_FrontMaterial.emission;
    gl_FragColor += gl_LightModel.ambient * gl_FrontMaterial.ambient;
    gl_FragColor += attenuation * spotlight * (gl_FrontLightProduct[0].ambient + (diffuse * gl_FrontLightProduct[0].diffuse) + (specular * gl_FrontMaterial.shi
niness * speccolor));
    gl_FragColor *= texcolor;

Where speccolor is gotten from this:
    // get the specular color
    vec4 speccolor = texture2D(specmap, vec2(gl_TexCoord[0])) * gl_LightSource[0].specular;

I'm putting the half vector into tangent space:
    H = normalize(tbn * gl_LightSource[0].halfVector.xyz);

But, I think I've got a problem in that I don't know if the half-vector starts in object or eye space (I think eye space, which would mean I'm not actually putting it into tangent space). I'm also not sure if I'm applying the specular map correctly (I can't find any GLSL tutorials or non-grayscale tutorials at the moment). I'm also not sure of what to set the shininess factor to since it's not encoded in the specular map. I guess I'm basically asking for any advice or links I can get. I don't see this being as hard to figure out as normal maps, I just don't know if I'm on exactly the right track yet.

Sponsor:

#2 Chozo   Members   -  Reputation: 176

Like
1Likes
Like

Posted 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.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS