problems with dot3 bump mapping

hi there !
i’m back with another problem : this time is dot3 bump map : how to “disable its effect ?” i first render in one pass the bumped polygon : this one is just working fine, so is the 3D or 2D/1D texture for lighting but the base texture is replace with well nothing, ti’s just pure white. I’m rendering my bumped poly with this :

glActiveTextureARB(GL_TEXTURE1_ARB);
	glBindTexture(GL_TEXTURE_2D, 20);

	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
	glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);

	glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT);
	glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_ALPHA);

	glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_TEXTURE);
	glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);

	glEnable(GL_TEXTURE_2D);


glActiveTextureARB(GL_TEXTURE0_ARB);		// Activate the texture unit
	glBindTexture(GL_TEXTURE_2D, 21);		// Bind the texture

	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);		// Setup the whole thing
	glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_DOT3_RGBA_EXT);

	glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PRIMARY_COLOR_EXT);
	glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);

	glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_TEXTURE);
	glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);
	glEnable(GL_TEXTURE_2D);

which is working just fine.
after this i put a glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); for each texture unit but it didn’t work

so if there are any idea, please let me know.

another point : as i copied the sample code from an ati tutorial, i don’t really know what it does : how to specify a light direction for instance ?

thanks for your help

wizzo

You should disable texturing on the unit if you dont need it. Calling glTexEnv(… modulate) isnt needed.

It looks like you are trying to do DOT3 on stage 1, and then using the result to modulate with base texture RGB.

The light vector needs to be plugged into glColor. You need to compress it

R = (lightvector_x + 1.0) * 0.5
G = (lightvector_y + 1.0) * 0.5
B = (lightvector_z + 1.0) * 0.5

It wont give you the best results cause glColor runs at low precision on everyday hw.
It will work fine however

More importantly, better get rid of _EXT there cause ARB is preferred.

I have to admit that I did not try to understand your code, but this is mine, and it works.

// reset all texture units
glActiveTextureARB(GL_TEXTURE0_ARB);
glDisable(GL_TEXTURE_2D);
glActiveTextureARB(GL_TEXTURE1_ARB);
glDisable(GL_TEXTURE_2D);
glActiveTextureARB(GL_TEXTURE2_ARB);
glDisable(GL_TEXTURE_2D);
glActiveTextureARB(GL_TEXTURE3_ARB);
glDisable(GL_TEXTURE_2D);

// tu 1: normal map
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, normalmap->GetTextureID());

glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);

// tu 2: normalization map
glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_CUBE_MAP_ARB);
glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, tex1);

glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_DOT3_RGB_ARB);

// tu 3: color map
glActiveTextureARB(GL_TEXTURE2_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, colormap);

glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_COMBINE_ARB);

assuming that the textures are set up correctly, and that you transform the light vector to tangent space (just as usual).

after drawing I call

// reset and disable all texture units
glActiveTextureARB(GL_TEXTURE0_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glDisable(GL_TEXTURE_2D);

glActiveTextureARB(GL_TEXTURE1_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
glDisable(GL_TEXTURE_2D);

glActiveTextureARB(GL_TEXTURE2_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glDisable(GL_TEXTURE_2D);

glActiveTextureARB(GL_TEXTURE3_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glDisable(GL_TEXTURE_2D);

and then the “normal” stuff goes on, it works and looks fine.

Jan

to JanHH : thanks i’ll try your code, and in fact its better you didn’t try to understand it… i’m pretty sure the problem is “around” it.
you’re using cube map which i’m not familiar with, though…
what is tex1 ? Does this work with vertex array (there is no glEnableClientState(GL_CUBE_MAP)) ?
sorry for not knowing anything to cube map =(

to V-Man :
i hear you on that, and JanHH’s code is just what i needed =)

thanks to both of you
wizzo

[This message has been edited by wizzo (edited 12-22-2003).]

[This message has been edited by wizzo (edited 12-22-2003).]

you need to compute the dot product of the light vector and the normal vector coming from the normal map, right? to do so, you pass the light vector as an input parameter and it gets linearly interpolated accros the surface. The problem is that it needs to have unit length for a proper computation, or the light will become darker. And exactly this is what happens when you do not use a normalization cube map, the interpolated light vector gets shorter while being interpolated accros the surface.

To solve this, you use a normalization cube map, which is a cube map texture that has the wonderful quality of automatically normalizing everything you pass as a texture coordinate.

So you use the light vector as texture coordinate input for the texture unit that holds the normalization cube map and dot3 this with the texture unit that holds the normal map, and what you get is what you need. and this then you modulate with the decal texture.

Best is you look here:
http://www.paulsprojects.net/tutorials/simplebump/simplebump.html

a very easy to understand tutorial about what we are talking about . althoug it is a little overcome as diffuse-only bump mapping is done in two passes, on gf4 you can do diffuse+specular in one pass, and my code is basically adapted from there and changed so that is does diffuse bump mapping in one pass.

Jan

Thanks A LOT JanHH for the tip and explanation !
the only problem is that it use 2 texture unit : so if you want to render base texture + bump mapping + specular mapping + gloss mapping you need 5 texture units…
how many texture units are there on latest graphic board (Radeon 9800 and GF FX 5xxx) ?

thanks anyway, i’m not going to deal with the specular lighting + gloss map today

wizzo

[This message has been edited by wizzo (edited 12-23-2003).]

I am fighting at the same front at the moment. You cannot do diffuse and specular bump mapping in one pass on hardware with four tu (gf4 has 4, I guess radon and fx also have four) when using only ARB extensions. On Nvidia hardware, there’s another (more powerful) way to do this, the nvidia register combiners, and on ati there’s something equivalent (I don’t know much about ati as I do not own a radeon by now).

WIth register combiners, you can do this in one pass, and do specular with a gloss map in two passes.

Read this:
http://www.opengl.org/discussion_boards/ubb/Forum3/HTML/011147.html

and this:
http://www.ronfrazier.net/apparition/index.asp?appmain=research/per_pixel_lighting.html

and this:
http://www.ronfrazier.net/apparition/index.asp?appmain=research/advanced_per_pixel_lighting.html

for sure all this will be a little too complicated at once, but it contains all the neccessary information you/we need.

I am so happy that after asking so many stupid questions here sometimes I am able to help someone

Jan

hehe it is always good to explain things to other, it really clarify things in your head =)

I read through the thread you pointed out (i already knew ron frazier’s paper) and i copied adress and stuff. I don’t have time to really get into it right now, but thanks a lot.

in your old post, you didn’t use dot3 bump mapping, right ? as you tried both, which is the best ? dot3 without reg, or old bump with the reg

regards
wizzo

I thought that for learning, I start with the oldest/simplest and then proceed. So first ARB dot3, then RC, then (future) fragment program.

The code I posted uses the arb dot3 extension.

Jan

alright, i’m going to try this all
if i have question, i’ll do like you did : stat another thread =)

see ya and thank you very much for your help

wizzo

“best” depends on what you want to do… if you target only at geforce 4, RC is best, if you use old hardware, you will have to use ARB extensions only, and if you target at gf fx/radeon only I would choose fragment shaders.

i’ll start learning shader as soon as i got a graphic board that support them… maybe next year

wizzo

The latest version of Mesa supports ARB vertex and fragment shaders:
http://www.mesa3d.org/

You could dabble with shaders now on any hardware.

sweet !
maybe i’ll have a look at it… so many thing to do…

wizzo