alpha textures & blending modes?
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
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
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?
(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: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.
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.
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: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.
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...
av = 1 ( The vertex alpha )
then you can do it with 2.
Quote:co = cv
ao = av * ((p * aa) + ((1 - p) * ab))
av = 1 ( The vertex alpha )
then you can do it with 2.
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.
Possibly Related Threads...
Thread: | Author | Replies: | Views: | Last Post | |
Signed Distance Fields for Alpha Tested Magnification of Vector Textures | maximile | 2 | 8,571 |
Mar 29, 2010 10:59 AM Last Post: Skorche |
|
Alpha blending weirdness on GMA 950 | akb825 | 15 | 13,582 |
Sep 1, 2009 06:22 PM Last Post: arekkusu |
|
Alpha Blending | lbtori | 1 | 3,374 |
May 1, 2008 01:35 PM Last Post: TomorrowPlusX |
|
Loading and using textures with alpha in OpenGL with Cocoa | corporatenewt | 4 | 9,387 |
Dec 8, 2007 02:06 PM Last Post: Malarkey |
|
general blending versus texture blending questions | WhatMeWorry | 2 | 7,400 |
Dec 7, 2006 02:43 PM Last Post: arekkusu |