PDA

View Full Version : Render the alpha channel as non-black



bobdevis
01-25-2010, 01:53 AM
Hi all!

I have a simple question. If you have an RGBA texture, you can render all the non-transparent pixels as black by setting
glColor4f(0.0, 0.0, 0.0, 1.0);
.....right?

Well, what if you wanted the same effect, but rendered as red, or white, or anything else then black?

glBlendFunc() doesn't seems to help because it multiplies the RGB channels, and those not the ones I want here.
So I just want the alpha-values rendered as some specific color that is not black.
What should I do?


Thanks in advance!

BionicBytes
01-25-2010, 05:06 AM
Seems fairly trivial if you use a shader....

The output of the fragment shader would be the texture's alpha multuplied by your chosen colour passed as a uniform value....

gl_FragColor = vec4 (your_colour_uniform.rgb * yourTexture.a, 1.0);

If you don't use shaders...then one of the blend mode allows the use of a constant color, so you could use that and specify SRC_ALPHA as one of the blend function parameters.

Abdallah DIB
01-25-2010, 05:09 AM
u should use texture combiners to combine( multiply ) ur texture color 'RGBA' with the fragment's one . or u can simply use an opengl shader to do so . here some tutorials on texture combiners :
http://www.opengl.org/wiki/Texture_Combiners
http://www.opengl.org/sdk/docs/man/xhtml/glTexEnv.xml
and here how to do emulate fixed function pipeline with a shader :
http://www.lighthouse3d.com/opengl/glsl/index.php?textureComb

Iulian B
01-25-2010, 08:17 AM
BionicBytes, what you are doing is just multiply some uniform color with some alpha sampled from the texture and then adding the alpha component set to 1 and output that. I'm pretty sure he didn't want that, because in his original example he was outputing that constant color in the color bits and the sampled alpha in the alpha component, probably to use it further down the blending stage. so your example might not get him what he wants. This, on the other hand

gl_FragColor = vec4(your_color_uniform.rgb, yourTexture.a)

might be it.

Also, in those cases, maybe it makes sense to only use a one-channel texture, but that's just an optimization.

On the other hand, bobdevis, depending on what you need that for, it could be an simpler way, from manipulating the blend functions (they are quite flexible in some common cases) to just doing that something completely different. It's quite weird that you only need an alpha mask with a solid color, but you need what you need :D. On the other hand, if you need that thing as an intermediate part of something that has something to do with multitexturing, blend functions can't help you that much, as they only blend the final pixel color and alpha with the existing one from the framebuffer. In that case, texture combiners (a thing of the past, if you ask me) is the way to go.

Iulian B
01-25-2010, 08:26 AM
BionicBytes, what you are doing is just multiply some uniform color with some alpha sampled from the texture and then adding the alpha component set to 1 and output that. I'm pretty sure he didn't want that, because in his original example he was outputing that constant color in the color bits and the sampled alpha in the alpha component, probably to use it further down the blending stage. so your example might not get him what he wants. This, on the other hand

gl_FragColor = vec4(your_color_uniform.rgb, yourTexture.a)

might do the trick.

Also, in those cases, maybe it makes sense to only use a one-channel texture, but that's just an optimization.

On the other hand, bobdevis, depending on what you need that for, it could be an simpler way, from manipulating the blend functions (they are quite flexible in some common cases) to just doing that something completely different. It's quite weird that you only need an alpha mask with a solid color, but you need what you need :D. On the other hand, if you need that thing as an intermediate part of something that has something to do with multitexturing, blend functions can't help you that much, as they only blend the final pixel color and alpha with the existing one from the framebuffer. In that case, texture combiners (a thing of the past, if you ask me) is the way to go.

BionicBytes
01-25-2010, 10:36 AM
So I just want the alpha-values rendered as some specific color that is not black.
What should I do?


I read this to mean the incomming alpha needs to be multiplied by some constant colour...hence the shader code i suggested.
Might be wrong though as the original request is a bit vauge.

Texture combiners are a good second choice though as Lulian suggests...

Iulian B
01-25-2010, 12:32 PM
My name starts with an I (capital i), not an L ... :D

on the other hand, what he was doing was multiplying the incoming texture sample (texR,texG,texB,texA) with the color (0,0,0,1), therefore he would get (0,0,0,texA). Now, he wanted to get
(uniformColorR, uniformColorG, uniformColorB, texA) and,
in the code you proposed, for the same input (now passing through your shader), the output would be(uniformColorR*texA, uniformColorG*texA,uniformColorB*texA,1) which is different from what he wanted in the 1st place, that's why I said that your example is not what he wants . I'm just talking about what he posted and what you posted, not what I or you think he wanted. On that subject, though, I agree, it's a strange behaviour, but there might be cases when it would be valid.

bobdevis
01-25-2010, 12:51 PM
Ok first of all, thanks for the replies.

I guess I should clarify myself a bit. The effect I am looking for is this;

http://i177.photobucket.com/albums/w213/bobdevis/battlesuitbj6.png

Some game character is at some point represented with an GRBA texture, like on the left.
When the character is selected by the player, like on the right, he gets a solid color halo that is not modified by lighting. This is so it is clear for the gamer what is selected.

Now I thought it would be easy to get this solid color halo by taking the alpha mask, making it bright red (and not black) and rendering it 3 times with slight offsets and then rendering the 'proper' texture on top of it.

There is bound to be some super-easy way to do this, right?
I am hesitant to touch shaders as I am using libSDL and I am nut sure how they are up to speed with newer OpenGL API.

Iulian B
01-25-2010, 02:36 PM
since we're talking about a 2d representation of something that you want highlighted, the super ultra mega easy thing to do would be to have 2 textures, one normal and one selected. That would allow you (or the artist) to do whatever highlight effect you want.

Now, onto more OGL centric stuff, I think that if you render that image 3 times (maybe you meant 4?) with slight offsets, I'm not sure you're going to get that smooth of an highlight. An ok effect would be to render the red alpha thing just slightly enlarged (1.1, maybe 1.2 times) once (but make sure the center of the images is aligned) and then the normal image. Should be enough.

Also,do touch shaders, they don't bite. Or, if you don't, register combiners are still your best friends (even though they are obsolete friends). Just read the specs and then ask more questions :D

bobdevis
01-25-2010, 05:12 PM
since we're talking about a 2d representation of something that you want highlighted, the super ultra mega easy thing to do would be to have 2 textures, one normal and one selected. That would allow you (or the artist) to do whatever highlight effect you want.


Yeah. The issue is that I have a couple of thousand of those textures. Haven't counted them, but it wouldn't surprise me if it's close to 3K that need that red highlight.

The good news is that I use my own decoder to go from a file to a char* raster that I feed into gluBuild2DMipmaps().
So it would be easy generate that extra flat-red texture but I would prefer not to do that since there are so many textures to keep track of as it is.



Now, onto more OGL centric stuff, I think that if you render that image 3 times (maybe you meant 4?) with slight offsets, I'm not sure you're going to get that smooth of an highlight. An ok effect would be to render the red alpha thing just slightly enlarged (1.1, maybe 1.2 times) once (but make sure the center of the images is aligned) and then the normal image. Should be enough.

Ooh, I'm not so worried about smoothness. I turn off bilinear filtering and mipmapping on purpose so the result looks nice and pixely.
That red outline is only supposed to be one pixel (in texture space) wide.

You must be wondering wtf it is I am building, right? Sorry, not disclosing right now, but it has something to do with supporting legacy games on new computers.



Also,do touch shaders, they don't bite. Or, if you don't, register combiners are still your best friends (even though they are obsolete friends). Just read the specs and then ask more questions :D

Yeah I will. No more excuses to shy away from learning that stuff now ;)

Iulian B
01-26-2010, 01:22 AM
Actually, I'm not that curious, because I know that if you can't say, you can't say. For example, I can't tell you what title are we working on right now, either. And I'm preety sure the title I'm working on now is more known than yours :p

Anyhow, good luck with your effect and with your project. But, to reiterate, I just meant, draw the ORIGINAL texture, but with the enabled <red_where_alpha> effect behind your own texture, but slightly enlarged. that way you only need to do one more draw and the effect might just be what you want.