Multiply Blending Problem

Moderator
Posts: 3,579
Joined: 2003.06
Post: #1
I don't understand blending very well, and/but I haven't been able to figure out why this isn't working for me (this is OpenGL ES, BTW):

Code:
glBlendFunc(GL_DST_COLOR, GL_ZERO);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);

I can do a wide variety of different kinds of blending instead, but "multiply" just doesn't draw my texture at all! I *thought* this should be:

RsRd + 0, GsGd + 0, BsBd + 0, AsAd + 0

but nothing shows up. Like I said, other blending modes work just fine, so I'm mystified as to why this isn't working as I expected.
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #2
what's the TexEnv for ( come to that, why on earth do you want to multiply src by dst color Rasp )
Quote this message in a reply
Moderator
Posts: 3,579
Joined: 2003.06
Post: #3
Because, I am trying to do a "multiply" blend, not just a normal blend.

The TexEnv is because normally I'm using:

Code:
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

and

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

or maybe

glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

But the way this particular texture (sprite) overlays the background, it looks best with "multiply" [going off how it looks in illustrator/p-shop]. So I'm just dipping into GL_ADD temporarily for the multiply. Yes, it's an odd-ball. I've never tried "multiply" blending before, which may be why I'm lost.
Quote this message in a reply
Sage
Posts: 1,482
Joined: 2002.09
Post: #4
I'd agree with the idea the multiply blending is handy. I've used it in a number of ways, but I'm also lost as to why you are doing an add instead of modulate.

Multiply blending is as simple as setting glBlendFunc(GL_DST_COLOR, GL_ZERO); as you've already done.

Scott Lembcke - Howling Moon Software
Author of Chipmunk Physics - A fast and simple rigid body physics library in C.
Quote this message in a reply
Moderator
Posts: 3,579
Joined: 2003.06
Post: #5
But if I use GL_MODULATE for the env mode, the transparent parts of the overlying image are black! [Edit] Looks exactly the same as if using GL_REPLACE for the env mode. [/Edit]

Also, if I use modulate instead of add, the formula isn't a straight diffuse multiply anymore is it? Although, I don't understand exactly what modulate does to the blend formula. I should try to sit down and noodle on the spec a little more there...

Again, with ADD, I thought that this is what it would be if I'm doing (GL_DST_COLOR, GL_ZERO):

(Rs * Rd) + (Rd * 0), (Gs * Gd) + (Gd * 0), (Bs * Bd) + (Bd * 0), (As * Ad) + (Ad * 0)

Which should simplify to:

(Rs * Rd), (Gs * Gd), (Bs * Bd), (As * Ad)

Which is what I want for "multiply", right? How would modulate change that?

Also, I have a thought somewhere in the back of my mind that I should mention that I'm not using lighting.
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #6
the texture environment doesn't affect blending at all, it affects the source color that's an input to blending. For example, MODULATE multiplies the [interpolated] vertex color by the texture color, and REPLACE just takes the texture color unaltered. I can't see why you would want either.

You'll be getting black where you expect transparent because your blending function doesn't include a _SRC_ALPHA anywhere...
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #7
try glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALHPA);
Quote this message in a reply
Moderator
Posts: 3,579
Joined: 2003.06
Post: #8
OneSadCookie Wrote:the texture environment doesn't affect blending at all, it affects the source color that's an input to blending. For example, MODULATE multiplies the [interpolated] vertex color by the texture color, and REPLACE just takes the texture color unaltered. I can't see why you would want either.

That would explain why MODULATE and REPLACE look identical for all the blend funcs I've tried -- since I'm not using lighting, there's not any shading to interpolate a color with (just white) when using MODULATE. But I'm still unclear about why I would want to use GL_DECAL, GL_BLEND, or GL_ADD instead. Which one would be best? I thought MODULATE was the best general-purpose env mode (plus, importantly, you'll get shading if you're using lighting because of the interpolation).

[Adding] MODULATE is the default too, so I shouldn't even have to specify it, right? [/Adding]

Quote:You'll be getting black where you expect transparent because your blending function doesn't include a _SRC_ALPHA anywhere...

That's what I was thinking earlier, which is why I already tried (many hours ago, amongst the myriad permutations I've run):

Code:
glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

It's not bad, but that doesn't quite achieve the same "multiply" that I see in Photoshop. The difference appears to be that the GL_ONE_MINUS_SRC_ALPHA is darkening the destination areas where they should be brighter (multiplied).
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #9
As far as I can see, where the source texture is opaque, this should be exactly "multiply" blending, since the second term goes to zero. Where the source texture is transparent black, it'll be exactly "normal" blending since the first term goes to zero. In between those two extremes... who knows.

What are you really trying to achieve? What is photoshop doing? Are you loading your textures with premultiplied alpha?

And please, leave TexEnv out of it Rasp
Quote this message in a reply
Moderator
Posts: 3,579
Joined: 2003.06
Post: #10
Yes, never mind the TexEnv, I had no idea what I was doing with it, sorry. I had it stuck in the head that it would somehow affect the blendfunc, which as you pointed out: does not. I got thrown off by the way I read a bit in the Red Book.

Quote:What is photoshop doing?

Since you mentioned it, I just double-checked what it looks like in Photoshop on my end and it is indeed exactly what I get in OpenGL! Blink I can't even reproduce the original artwork that the artist sent a screenshot of. I will have to discuss this with him.

So "multiply" is multiplying after all, and I've been on a wild goose chase after something that ain't what it's supposed to be!

... very sorry for wasting everyone's time here -- including my own Sad

The artist told me it was supposed to be a multiply, and the screenshot he sent shows that multiply was indeed selected... But it ain't a multiply now that I think of it because the pixels must logically be the same or dimmer as a result of the multiplication, and in the screenshot he sent me, some of the pixels are actually brighter.

Quote:Are you loading your textures with premultiplied alpha?

No. But I'm now wondering if that somehow got into the mix on the artist's end, in Illustrator. I don't even know how to premultiply with Photoshop. And AFAIK, it always exports non-premultiplied (I think).
Quote this message in a reply
Member
Posts: 446
Joined: 2002.09
Post: #11
AnotherJake Wrote:... I don't even know how to premultiply with Photoshop. And AFAIK, it always exports non-premultiplied (I think).
If you export PNG with "Save for Web" it does indeed premultiply. It also ignores your alpha channel and relies on layer transparency, which can be a PITA. If you need better alpha control it's best to save as TGA or TIFF and convert to PNG with another tool (assuming your final format is PNG of course).
Quote this message in a reply
Moderator
Posts: 3,579
Joined: 2003.06
Post: #12
Frank C. Wrote:If you export PNG with "Save for Web" it does indeed premultiply.

Thanks, I was totally unaware of that. That could be useful!

Yeah, I know about Photoshop's desire to use layer transparency instead of an alpha channel. I use the tiff trick, er workaround (later converted to PNG elsewhere) if I need fine control over alpha.
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #13
Remember, if you use CoreGraphics/UIImage/NSImage to load, you're almost certainly getting premultiplied alpha, since those will premultiply on load. You're probably only getting nonpremultiplied alpha if using libpng (directly, or indirectly via eg. SDL_image or FreeImage).
Quote this message in a reply
Moderator
Posts: 3,579
Joined: 2003.06
Post: #14
Oh man, I totally forgot about that... Thanks for the reminder. Yeah, I'm using the ever-popular Texture2D class from the iPhone sample code. I normally use libpng on the Mac. You'd think it'd be burned into memory that I can't rely on CG for non-premultiplied PNGs by now. Rolleyes

That sucks. Might file it as a bug when I get a chance...
Quote this message in a reply
Apprentice
Posts: 8
Joined: 2008.12
Post: #15
Hi, first post. Did this ever get resolved, because I think I'm having the same problem.

[Image: GLBug.png]

So, it looks like it's blending the black from the alpha channel in with the pixel data, whilst at the same time actually using the alpha channel for correct blending with the destination pixels. The problem, as you can see, is the colour.

The above is using;

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

If I change this to;
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

Then it looks right (like the photoshop image), but I lose the ability to do blending on the actual vertices, so it's not an ideal solution.

Strangely, when I put the images into the example apps, they look fine, but I can't seem to pinpoint the exact point that my own project differs from it. Most of the code I'm using is lifted directly from the eaGL 'lander' example.

I'm tearing my hair out, any help would be graciously recieved!

Stu
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  pbuffer blending problem on macmin g4 madjerry 4 3,896 Nov 27, 2009 03:14 AM
Last Post: madjerry
  general blending versus texture blending questions WhatMeWorry 2 5,240 Dec 7, 2006 02:43 PM
Last Post: arekkusu