PDA

View Full Version : Bad specular highlight when applying rotation



niko
10-20-2005, 12:10 AM
Hello,

I am implementing normal map bump mapping and until now everything looked fine. My light source is howering above my scene of four objects, diffuse looks good, specular and bumps ditto. When I apply rotation to the scene diffuse and bumps are ok but the specular highlight starts wondering around in wrong places. I am pretty sure that I mess up my eye direction vector (which is used to calculate halfangle and later on specular contribution), I just can't figure out how. I provide eye position to vertex shader in world coordinates and calculate eye_dir = eye_pos - gl_Vertex.xyz.

I appreciate any comments on this, as I'm sure I'm not the first poor sod going nuts over this ;)

/niko

Relic
10-20-2005, 02:50 AM
Sounds like your mixing coordinate systems.
gl_Vertex is in object coordinates (model space).
OpenGL skips "world" coodinates and modelview goes directly to eye coordinates (eye in the origin).
The vector from vertex to eye in that coordinate system is -(gl_ModelViewMatrix * gl_Vertex).xyz.
There are some gotchas with vertices behind the viewer (negative w after transformation) when simplifying it this way.
Did you transform the normals correctly?

niko
10-20-2005, 04:19 AM
Relic,

thank you for replying. If I use -(gl_ModelViewMatrix * gl_Vertex).xyz as my eye_dir the specular lighting goes wrong. It's almost correct but not quite. I must be doing something wrong elsewhere as well, perhaps fumble up the normals as you suggested.

Vertex shader I am using:


varying vec3 vlight_dir;
varying vec3 vhalf_angle;
varying vec2 vUV;
varying vec2 veye_dir;

uniform vec3 eye_pos;

attribute vec4 tangent_normal;

void main(void)
{
gl_Position = ftransform();

vec3 light_dir = (gl_ModelViewMatrixInverse * gl_LightSource[0].position).xyz - gl_Vertex.xyz;
vec3 eye_dir = eye_pos - gl_Vertex.xyz; //-(gl_ModelViewMatrix * gl_Vertex).xyz;

vec3 tangent = tangent_normal.xyz;
vec3 binormal = normalize(cross(tangent, gl_Normal));
mat3 rot = mat3(tangent, binormal, gl_Normal);
light_dir = normalize(light_dir * rot);
eye_dir = normalize(eye_dir * rot);

vlight_dir = light_dir;
vhalf_angle = normalize(eye_dir + light_dir);
vUV = gl_MultiTexCoord0.st;
veye_dir = eye_dir.xy;
}If just before rendering an object, after all the transforms done, I glGet the modelview matrix and compute the 'worldspace position of eye' and provide that to uniform eye_pos, specular highlights are correct. Still, I would rather not use this method I suspect is a cheap patch for an error elsewhere. Also if I have hundreds of objects, the fetching and inversing modelview will provide unnecessary overhead.

I think it would not be a bad idea to get Eric Lengyel's book 'Mathematics for 3D game programming and computer graphics' ;)

/niko

jide
10-20-2005, 04:48 AM
I'd do the lighting stuff in the fragment shader: it's the common place for it.
And use gl_LightSource[i] structures instances for the half vector and such. Doing so you won't have to multiply the light position by the modelview matrix and the eye direction will always be the same (0,0,-1).

Hope that helps.

Fitz
10-23-2005, 06:57 PM
Hello Niko I think I have some similar problems, anyway I have used this for eye vector

vec4 vertPos = gl_ModelViewMatrixInverse*vec4(0.0,0.0,0.0,1.0);
vec3 eyeVec = vertPos.xyz-gl_Vertex.xyz ;

tanEyeVec.x = -dot(Tangent, eyeVec);
tanEyeVec.y = -dot(BiTangent, eyeVec);
tanEyeVec.z = -dot(gl_Normal, eyeVec);

It seems to work ok for eye vector but my probem is my light vector seems screwed up and I'm doing the same thing you are to get light vector.