ARB_texture_env_combine and destination alpha

Hello again,

I want to do dot3 bump mapping with ARB_texture_env_combine. So far, that’s no problem. I also got the gloss map working for the specular pass, so now four texture units are in use, the gloss map bound to unit four.

But after the specular pass, I would like to do some blending by destination alpha, but somehow, the alpha value doesn’t make it into the framebuffer, no blending occurs (and it WORKS when drawing a third pass with glColorMask and so only drawing to the alpha component of the framebuffer, the blending works fine, so that’s not the problem for sure). The gloss map texture has an alpha value which would be suitable, but I do not really know how the code should be, at the moment it is

// tu 4: gloss map
glActiveTextureARB(GL_TEXTURE3_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, glossmap);

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);

glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_PRIMARY_COLOR_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE);

and I tried several other parameters (due to the lack of a good tutorial it’s more or less trial and error), but nothing seems to work.

any idea? I guess it’s absolutely trivial once you know how to…

Thanks
Jan

[This message has been edited by JanHH (edited 12-25-2003).]

[This message has been edited by JanHH (edited 12-25-2003).]

>>> glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_COMBINE_ARB);<<<

the above line should be giving an error.

I didnt understand what you are doing overall, but you want alpha from the gloss map, then you can just use GL_REPLACE for the alpha.
That will put the alpha into your framebuffer.

COMBINE is not a proper combine function. You probably want REPLACE or MODULATE in this case, for the color part.

What happens is probably that the driver detects that the texture environment is incorrectly configured, and makes it disabled (causing white as output) as per the specification regarding inconsistent texture units.

PS: You could have caught this by sprinkling assert(!glGetError()) all over your code. I suggest you start by putting this at the start of each function, and add more where necessary.

tracking errors is a good idea .

I guess that when using GL_COMBINE_ARB as combine function, it uses default mode, which seems to be GL_MODULATE, which is what my program does (there is/was GL_COMBINE_ARB in another line where GL_MODULATE is right, fixed that, looks exactly as before).

but after changing the code to

// tu 4: gloss map
glActiveTextureARB(GL_TEXTURE3_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, glossmap);

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_MODULATE);

glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);

still the alpha value does not reach the framebuffer…

What I want to do with texture unit 4 is to modulate the color result of the previous three texture unit operations with the color of the map which is bound to texture unit 4 (which means that the specular part is modulated with the gloss map), and replace the alpha value of the previous operations by the alpha value of the gloss map (so that it becomes the alpha value in the framebuffer and can afterwards be used for blending by destination alpha).

Jan

OK, but are you remembering to tell what operand you want?

Example:
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);

Other than that, you have to have an alpha layer in the framebuffer but you probably do.

I don’t understand this.

for colors, you say

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_MODULATE);

so I would find the code I posted above logical. Why use SOURCE for color and OPERAND for alpha??

How do the lines regarding alpha have to look so that it will work? please help…

thanks
Jan

further explanation:

texture unit four is in GL_COMBINE_ARB mode. with the colors, everything seems to work fine. With the alpha value, what I want to do is:

“take the alpha value from the previous steps, and the alpha value coming from the texture of this unit, and do the REPLACE operation, so that what comes out is the alpha value of the texture”. In code, I think, this should look like

// tu 4: gloss map
glActiveTextureARB(GL_TEXTURE3_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, glossmap);

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_MODULATE);

glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);

(as I posted before).

Alpha blending is enabled with GL_ONE, GL_ONE as blend func, which should the add the incoming fragment to what is already in the framebuffer. (hm what comes to my mind at the moment is, maybe there is already 1.0 in the framebuffer, so adding does nothing? could be a clue…)

sorry for posting so much on this rather trivial topic…

Jan

[This message has been edited by JanHH (edited 12-27-2003).]

[This message has been edited by JanHH (edited 12-27-2003).]

thanks guys (and girls), got it working, my guess was right (and my code was also right ). I only had to change color to

glColor4f(1.0, 1.0, 1.0, 0.0)

Jan

You have to tell it what operand you want used . Something like this :

==============
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_OPERAND0_RGB, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);

glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);

Exactly. The “OPERAND” stuff is similar to the input mapping in NV_rc, if that rings a bell.

Just look at the possible values:
SRC_COLOR
ONE_MINUS_SRC_COLOR
SRC_ALPHA
ONE_MINUS_SRC_ALPHA

OK good to know that. although it seems to be working without OPERAND as well. maybe COLOR is the default operand for RGB and ALPHA is the default operand for ALPHA.

At least, it works, and it rocks (at lesat, I think so). I will post a screenshot (or some) if you’d like to see. The road is tiled with bathroom tiles g and it’s bump mapped, with reflecting puddles on it. Might not be a large step for mankind, but at least a large step for the program I am working on (before: single texturing with standard vertex lighting) .

Jan

ok you didn’t ask for it but I am posting it anyway:
http://de.geocities.com/westphj2003/bumpmap.html

I’d be happy about any comments

Jan

I love the very last screenshot - looks like a bumped mirror, very nice, really.

Still not sure about fixed function-based bump mapping. What about performance?

Looks good, you actually managed not to ruin you brand new bump mapping by making it too strong

The reflections look very nice too, they add a lot to the scene. Do they have to be planar or can you have puddles everywhere on the terrain?

For an easy improvement, start creating antialiased puddle maps (or whatever you call them). The reflections could also use some fresnel (less reflection in places that face the viewer), but that’ll take some more work.

-Ilkka

thanks .

The part of the scene that is the “road” on the screenshots is a fact a river, so it is a planar reflection of the whole scene (simply drawn upside-down mirrored at the water level), but it is masked by the gloss map (where there is glossiness(specular), there is no puddle, this is what the destination alpha is for. the alpha values of the gloss map are the inverted color values). I am planning to have reflections (puddles) possible everywhere, but there only the sky will be reflected, not the objects and the ground, as this would become to complicated.

Performance is no problem, the only drawback comes from the need to render the scene twice (mirror), single-pass bump mapping is as fast as no bump mapping at all, and two-pass bump mapping is half the speed, due to a second rendering pass . But as only a few parts of the scene will have specular higlights (sand and grass etc are not very glossy), I think it will be fine.

Jan