Unwanted Effect w AlphaBlend

Hello,

I earlier posted some stuff on motion-blur, and followed the instructions I received. I’m generating about 4 texture-mapped quads per scene, each with a different alpha-level from 0.25 to 1.0. Here’s a snip:

glEnable glcBlend
glBlendFunc sfSrcAlpha, dfOneMinusSrcAlpha

For i = 1 To 4
glColor4f 255, 255, 255, 0.25 * i
glBegin GL_QUADS

And this is the effect:

Anyone recognize what’s going on (read: wrong) there?

Thanks!

Tom

A few things. One, I would use the accumilation buffer if you really want to do motion blur. The next is that you need to make sure that the Z buffer is set to less or equal (or less for the first pass, equal for the second three). Third, I think your math may be wrong. I think it’s supposed to blend with 1alpha, .5 alpha, .3333alpha, .25 alpha…

Oh, well, I did not complete all the fields, the board sent me back to this page, and my message was gone. My comments:

I tried the accumulation-buffer, but it didn’t work. It’d instead of rotating the cube, show my a still of like 30 frames (blurred and all) when I closed the application.

I don’t understand what you mean about Z-buffers. I thought there was one Z-buffer? And I thought that was it painted last in the buffer is what comes up at front? Thus, painting first a 25% opaque image, then 50%, 75%, 100% would result in the opaque ones being behind the fully visible 100%-painted one.

About the alpha, 0 made a completely opaque image, and 1.0 made a completely visible. Unless my call to glColor4f is wrong, I don’t see what it. And unless my idea of how the Z-buffer painitng works is wrong, too …

Feel free to elaborate on the points where I am confused.

You should draw then in the other order, from 100% to 25% alpha, as he said.

The alpha-thing did produce a better looking effect. I’ll have to meditate on that one for a while, why it’s that way. Doesn’t make sense to me right now. :slight_smile:

Issues:

(*) Motionblur looks crappy without accumulation

(*) That black rectangle on the image I posted above is still there in the alpha-revised version, but it’s now black with an alpha level of roughly 50%. :wink:

I know you probably get the kinds of questions, such as above, pretty often. Newbies tend to ask the same questions (and, I did search the archives), so I’d like to ask if there are any tutorials for stupid people on alpha-blending and that accum-stuff ?

Per regards for different Z-indexes, it works to do:

glLoadIdentity
glTranslatef 0#, 0#, -7.5
glbegin … glend

'** Onto the next object

glLoadIdentity
glTranslatef 0#, 0#, -7
glbegin … glend

Is this the “right” way of doing it?

Originally posted by Sebaot:

I don’t understand what you mean about Z-buffers. I thought there was one Z-buffer? And I thought that was it painted last in the buffer is what comes up at front? Thus, painting first a 25% opaque image, then 50%, 75%, 100% would result in the opaque ones being behind the fully visible 100%-painted one.

About the alpha, 0 made a completely opaque image, and 1.0 made a completely visible. Unless my call to glColor4f is wrong, I don’t see what it. And unless my idea of how the Z-buffer painitng works is wrong, too …

Feel free to elaborate on the points where I am confused.

Let’s see:

  1. Your call to glColor4f IS wrong - I think you want (1.0f,1.0f,1.0f,{alpha}) as params rather than (255,255,255,{alpha}) - but I don’t think that’s your problem, since GL will clamp your color components. Won’t hurt to fix it though.

  2. “Opaque” - you keep using this word, I do not think it means what you think it means. “Opaque” is the OPPOSITE of “transparent”. 100% alpha = opaque, equivalent to blend being disabled. 0% alpha = transparent, i.e. invisible.

  3. I think you’re a bit confused about how Z-buffering works. Your “drawn last = drawn front” description is known as Painter’s Algorithm; that’s the default if you DON’T have a Z-buffer. Z-buffering is based on the Z-coordinate of what you’re drawing. As well as drawing color values into frame buffer pixels, you’re also drawing depth values into depth buffer pixels; these values record how far it is from the viewer to the closest thing drawn on that pixel. When you draw something with depth-test enabled, GL checks each fragment (a fragment is a sort of potential pixel) to see whether it’s closer than the current closest thing as recorded in the Z buffer. If not, it doesn’t draw that pixel at all. What MIGHT have been happening in your original problem is that you draw the 25%-alpha quad, then the 50%-alpha quad, but GL thinks “ah, the pixels for this second quad aren’t any closer than what I’ve got in my depth buffer already, so I’m not going to bother drawing them again.” Hence the importance of your depth test function, and why your later code with different Z-coords seems to work.

I would suggest drawing from 100% to 25% alpha as Bob suggested, but rather than changing the Z coordinates for successive quads as in your last post, try disabling GL_DEPTH_TEST altogether. If you’ve got other things in your scene, draw them BEFORE your motion-blurred object. If you’ve got multiple alpha-blended objects in your scene, there’s a good chance you’ll need to sort them by depth before drawing; you can find lots of stuff about this if you have a search through the archives.

Hope some of that helped, or even made sense. (It’s late, and I’m drunk.)

  1. Your call to glColor4f IS wrong - I think you want (1.0f,1.0f,1.0f,{alpha}) as params rather than (255,255,255,{alpha}) - but I don’t think that’s your problem, since GL will clamp your color components. Won’t hurt to fix it though.

Ah, okay. That’s one point I sorta wondered about.

  1. “Opaque” - you keep using this word, I do not think it means what you think it means. “Opaque” is the OPPOSITE of “transparent”. 100% alpha = opaque, equivalent to blend being disabled. 0% alpha = transparent, i.e. invisible.

No wonder I’ve been mixed up. Thanks for clearing that one up. Both points very clear so far, not much to ask about. :slight_smile:

What MIGHT have been happening in your original problem is that you draw the 25%-alpha quad, then the 50%-alpha quad, but GL thinks “ah, the pixels for this second quad aren’t any closer than what I’ve got in my depth buffer already, so I’m not going to bother drawing them again.” Hence the importance of your depth test function, and why your later code with different Z-coords seems to work.

Makes sense it would be that way. With depth test, I just run the:

glEnable glcDepthTest glDepthFunc cfLEqual

I would suggest drawing from 100% to 25% alpha as Bob suggested, but rather than changing the Z coordinates for successive quads as in your last post, try disabling GL_DEPTH_TEST altogether.

[QUOTE]

Shall do.

BTW, the quad-examples in my last post was from me adding a background image to the whole thing behind the cube. :slight_smile:

[QUOTE]
Hope some of that helped, or even made sense. (It’s late, and I’m drunk.)

Made plenty of sense and help to me. Alcohol in some forms is good. :slight_smile:

I take back what I said (about the Z) if you’re doing motion-blur (I was thinking if you were blending several textures). But this does present a new problem, unless all the objects are sorted from farthest to nearest. The reason is that there is no way to use a z buffer when the objects are moving. That is why I mentioned the accumilation buffer. And as for the 100,50,33,25…it’s just 1/1 1/2 1/3 1/4 (the first time there is a total of 1 passes, and so the first texture should be 100% there…but then the second pass half is the original texture, half the new one. The third time 2/3 is what was already there, so 1-2/3=1/3…and so on…) hope that helps.

I just saw that I repeated some of what has already been said, but as for the accumilation buffer, I’ll see if I can get all the functions for you tonight (I don’t have MSDN on this computer)

That’d be really nice, because when I use the accumulation buffer, everything slows down to a stop. :slight_smile:

The accumulation buffer is very slow. There is no consumer-level card that supports it in hardware, so it’s all done in software. If you don’t mind the slowdown, use it. If you need fast framerates, don’t expect too much from it.

I think what I see when using the accum-buffer – in a way so shameful and convincingly erronous I will never post the code – would probably run smooth first way above my 1.2Ghz, 512 MB RAM. . :slight_smile:

Not figured out those push- popmatrix things I see in every accumulator example. There’s something about my motherboard, too, so I’m getting new ones tomorrow. 3DMark 2001 gave me a score of 991. (I’ve got a GeForce 2 GTS, 32MB.)

HFAFriend, buddy, did you find those functions? :slight_smile: Got my motherboards exchanged and ready to rock!

try using the glScissor function with any accumulation buffer stuff u do though its still gonna give you piss poor performance :< )