alpha textures & blending modes?

Sage
Posts: 1,232
Joined: 2002.10
Post: #1
I'm looking for help with alpha textures and blending modes.

I want to achieve the simple effect of cross-fading two textures. The textures only contain alpha data, and have to be modulated with the underlying geometry color.

(For example, two different "smoke" shaped textures that fade between each other, and are colorized by the polygon vertex colors.)

I am targeting Jaguar, using Cocoa. I'm using a DVI TiBook (Radeon 7500), so I can use multitexturing and GL_COMBINE modes, but not pixel shaders.

Also, this is being drawn into a context and window with the background transparent, so the Finder desktop (or whatever) shows up behind my view.

My problem:

I cannot seem to get the blending to work correctly. What I want is a texture combine mode that does
GL_PRIMARY_COLOR * GL_TEXTURE * GL_CONSTANT
so I can animate the constant to fade in one texture and fade out the other.

But there is no such mode.

So, first I tried leaving the incoming geometry RGB alone and interpolating the alpha between my two textures, like this:

(texture 0)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PRIMARY_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PRIMARY_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);

(texture 1)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_CONSTANT);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_INTERPOLATE);

The problem with this is, no matter what I set glBlendFunc() to, I would get a light fringe around my texture. Anywhere the alpha was less than 1.0 (and my texture contains the whole range, not just 0.0 and 1.0,) the fragment color would be blended with white.

So, I figured that GL wants the RGB to be premultiplied with alpha. I can change texture 0 to GL_MODULATE the incoming RGB with the texture, and that looks fine now. But texture 1 can't do that, because there is no way to iterpolate between GL_PREVIOUS and GL_PRIMARY_COLOR * GL_TEXTURE. The best I can do is GL_PREVIOUS * GL_TEXTURE, and that results in the areas different between texture 0 and texture 1 being multipled twice (too dark...)

So, maybe this is impossible with multitexturing on pre-pixel shader hardware. What if I try it with just one texture, and two passes?

Well now I can just use GL_MODULATE mode for both RGB and ALPHA, and set the geometry vertex alpha appropriately, right?

No, same problem. Now when the geometry alpha is low, the whole texture is blended with white. Drawing one texture at 100% alpha looks fine. Drawing both at 50% each is too light.

This ought to be a very simple effect to achive, what am I doing wrong?!


thanks,
-alex
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #2
Just to clarify the question, you want the results of this formula?

(cv = vertex color, av = vertex alpha, aa = texture 0 alpha, ab = texture 1 alpha, p = arbitrary parameter between 0 & 1, co = output color, ao = output alpha)

co = cv
ao = av * ((p * aa) + ((1 - p) * ab))

Is that right?
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #3
Quote:co = cv
ao = av * ((p * aa) + ((1 - p) * ab))

Yes, that's what I want. The output color is the underlying geometry color. The output alpha is the geometry alpha, modulated with a blend between the two textures.
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #4
I think you're going to need your third texture unit (which you have on the Radeon, but not on GeForce2MX/4MX).

You could then use REPLACE (aa), INTERPOLATE (previous and ab by p) and MODULATE (previous and av) as your alpha texture function. REPLACE with vertex color for all three color ops should be fine.

I have a feeling that you should be able to use a vertex program and two texture units, but I have to admit I can't see how.
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #5
Quote:I have a feeling that you should be able to use a vertex program and two texture units, but I have to admit I can't see how.

Having thought about this a bit more, I'm now pretty sure that you can't do this; that you do actually need the extra combine stage.
Quote this message in a reply
henryj
Unregistered
 
Post: #6
As OneSadCookie said you are going to have to use another texture unit. We've thrashed it out and can't see a way around it UNLESS...

Quote:co = cv
ao = av * ((p * aa) + ((1 - p) * ab))


av = 1 ( The vertex alpha )

then you can do it with 2.
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #7
Thanks, i finally got it working how I want. I ended up using two texture units and two passes. My problem was the pre-multiplied alpha; I had to make sure the RGB color was multiplied by the alpha *EACH TIME* I added a factor to the alpha calculation. So once for the texture, once for the vertex alpha, and again for the opacity fade.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Signed Distance Fields for Alpha Tested Magnification of Vector Textures maximile 2 5,884 Mar 29, 2010 10:59 AM
Last Post: Skorche
  Alpha blending weirdness on GMA 950 akb825 15 9,069 Sep 1, 2009 06:22 PM
Last Post: arekkusu
  Alpha Blending lbtori 1 2,294 May 1, 2008 01:35 PM
Last Post: TomorrowPlusX
  Loading and using textures with alpha in OpenGL with Cocoa corporatenewt 4 6,401 Dec 8, 2007 02:06 PM
Last Post: Malarkey
  general blending versus texture blending questions WhatMeWorry 2 5,199 Dec 7, 2006 02:43 PM
Last Post: arekkusu