Normal Mapping and Camera Orientation

Hi all!

I ve been trying to duplicate a normal mapping technique from what I already have in my ffp:

It does pretty much the same logic afaics and I get the same result but when I move the camera around the shading becomes darker, which is not good! Note that I m not adding light computation for simplicity sake.

Here is an hybrid code:

vec3 l_bumpMap = texture2D(u_BumpMap, v_TexCoord.st).rgb;

vec3 l_lightVector = l_lightPosition – vec3(gl_ModelViewMatrix * gl_Vertex);
mat3 l_matrix = mat3(v_Tangent, v_BiTangent, v_Normal);
vec3 l_direction = normalize(l_matrix * l_lightVector);

vec3 l_bumpMap = dot(l_bumpMap, l_direction);
gl_FragColor = vec4(l_bumpMap, 1.0);  

what do I need here to compensate the camera orientation? And why is it different from the ffp?

thx

The light position uniform has to be in view space.

With the fixed function pipeline, the light position is multipiled by the current modelview matrix at the time it is set, so if you set the light position after making the camera transform the result is exactly what one would expect for stationary lightsources.

If you want exactly the same semantics you have to do the same manually when setting the l_lightPosition uniform. But in the simple case where you have only the camera transform on the matrix, setting the light position relative to the camera position should be enough.

Go to

Ultimate Game Programming Tutorials

And download the Glsl Dot3 Bump 2 code.

It is exactly what you are after.

With the fixed function pipeline, the light position is multipiled by the current modelview matrix
yeah, makes sense… I m still a little confused about a detail…

some shaders send camera position via uniform… but is it necessary? is it possible to retrieve camera position without sending it via uniform?

Glsl Dot3 Bump 2 code is pretty much what I post earlier itsnt it? or did you meant Glsl Dot3 Bump 3?

Thx guys

No, I tested your code, and then replaced bits from:

 vec3 l_lightVector = l_lightPosition – vec3(gl_ModelViewMatrix * gl_Vertex);
mat3 l_matrix = mat3(v_Tangent, v_BiTangent, v_Normal);
vec3 l_direction = normalize(l_matrix * l_lightVector); 

with bits from theirs. Basically, they are not using uniforms for the Tangent, BiTangent and Normal, they are calculating them in the shader. I also had the same prob as you, and was able to fix it with help from theirs.

As for the current ‘camera’ position, I am not 100% sure as I am relatively new to shaders, but if gl_Vertex is the vertices from your current object, then seeing as though you multiply it by gl_ModelViewProjectionMatrix to get it to transform correctly, then would the camera be the coordinates in the gl_ModelViewProjectionMatrix? Either that or gl_ModelViewMatrix?

hi,

the first pseudo code ive posted is in fact working… I use attribute to send tangents to the shader…

as for the camera position… I think we must send it through uniform… but im not quite sure it is necessary… for specular, parallax, and/or whatever we think we might need it… still digging, but ill try avoiding any data traffic.

a side question:

GL_MAX_VARYING_FLOATS: 32.

is this means: 8 x uniform vec4 will maxed out my shader VARYING_FLOATS?

Originally posted by Golgoth:
[b]GL_MAX_VARYING_FLOATS: 32.

is this means: 8 x uniform vec4 will maxed out my shader VARYING_FLOATS? [/b]
It means that 8 x varying vec4 will max out this limit. uniform variables are limited by MAX_VERTEX_UNIFORM_COMPONENTS and MAX_FRAGMENT_UNIFORM_COMPONENTS.

ya, varying… indeed :slight_smile:

thx

the first pseudo code ive posted is in fact working… I use attribute to send tangents to the shader…
I have tested your pseudo code and I can assure you that it is not working. It appeared to at first, but then I moved way back from the object the lighting moved as well.

I will post the code I used to get it to work.

Note, I am not sending any uniform variables apart from the textures.

In my vertex shader, I have the variants:
varying vec4 diffuseb, ambientb;
varying vec3 normalb,lightDirb,halfVectorb;

In the main function I have the following to do with the light. This is similar to the tutorial code I told you to visit earlier.

 	vec3 vVertex = vec3(gl_ModelViewMatrix * gl_Vertex);

    vec3 lightDir = vec3(gl_LightSource[0].position) - vec3(gl_Vertex);

	vec3 sTangent = gl_Color.xyz;

	vec3 binormal = cross(sTangent, gl_Normal);

	mat3 tbnMatrix = mat3(sTangent, binormal, gl_Normal);

	lightDirb = tbnMatrix * lightDir; 

In my fragment shader, I have the same variants:
varying vec4 diffuseb, ambientb;
varying vec3 normalb,lightDirb,halfVectorb;

And the uniform:
uniform sampler2D texturebump;

And in the main function:

 	vec3 bump = texture2D(texturebump, vec2(gl_TexCoord[0])*bumpscale);
	bump = (bump - 0.5f) * 2;
vec3 lightT = normalize(lightDirb);
diffuseb = dot(bump, lightT); 
gl_FragColor = color * diffuseb

I can assure you this is working 100% and is based on the code I told you to visit earlier.

BTW, I know the code isn’t the best, I have a habit of being lazy when it comes to easy to understand code, I put stuff everywhere. :smiley:

Alright, I m about to go nuts…

I ve been testing relief mapping… but I didnt know my basic normalmap was a failure… I ve tried a zillion possibilities… still, with swiftness technic, the light effect looks reversed and it changes when I move the camera around… sigh… I ll post my shaders in case anyone can figure what I m doing wrong…

vert

varying vec3 v_Normal;
varying vec3 v_Tangent;
varying vec2 v_TexCoord;
varying vec4 v_Vertex;
varying vec3 v_WorldSpace;

attribute vec3 a_Tangent;

void main()
{
	gl_Position	= ftransform();

	v_Normal	= normalize(gl_NormalMatrix * gl_Normal);
	v_Tangent	= a_Tangent;
	v_Vertex	= gl_Vertex;
	v_WorldSpace	= vec3(gl_ModelViewMatrix * gl_Vertex);

	vec4 l_coord = gl_TextureMatrix[0] * gl_MultiTexCoord0;
	v_TexCoord = vec2(l_coord / l_coord.w);
}

frag

varying vec3 v_Normal;
varying vec3 v_Tangent;
varying vec2 v_TexCoord;
varying vec4 v_Vertex;
varying vec3 v_WorldSpace;

uniform sampler2D u_NormalMap;
void main()
{
	vec3 l_lightVector = gl_LightSource[0].position.xyz - v_Vertex.xyz;
	vec3 l_biTangent = cross(v_Tangent, v_Normal);
	mat3 l_tbnMatrix = mat3(v_Tangent, l_biTangent, v_Normal);
	vec3 l_direction = normalize(l_tbnMatrix * l_lightVector);

	vec4 l_normalMap = texture2D(u_NormalMap, v_TexCoord);
	l_normalMap = (l_normalMap - 0.5) * 2.0;

	vec3 l_color = dot(l_normalMap.xyz, l_direction);

	gl_FragColor = vec4(l_color, 1.0);
}

That is quite simple… it must be in my face… just cant see it…

thx

The line:
mat3 l_tbnMatrix = mat3(v_Tangent, l_biTangent, v_Normal);

Is different.

Your v_Normal = normalize(gl_NormalMatrix * gl_Normal);

While I just use gl_Normal.

Try it with:

mat3 l_tbnMatrix = mat3(v_Tangent, l_biTangent, gl_Normal);

My only other guess is that it is something outside of the shader. What are the values you are sending to a_Tangent?

Also, how have you set up your lighting?

Golgoth, it seems to me that there is mismatch in spaces used in your calculations.

There is likely mismatch in spaces used by v_Tangent and v_Normal during calculation of the l_biTangent, unless you are sending a_Tangent in eye space.

Unless you have stored the gl_LightSource in object space (for FF lighting it is expected to be in eye space so you have set the modelview matrix appropriatelly to store it in object space) there is also mismatch during calculation of the l_lightVector.

Check all calculations to ensure that they are operating in expected space.

never mind all of this…

vec3 l_biTangent = cross(v_Normal, v_Tangent);

sigh… at once, dot3, parallax and relief are kicking in… I m quite happy…

thx again!

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.