• Create Account

## Alpha blending with a color that has no RGB components

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

14 replies to this topic

### #1Shawn619  Members

Posted 27 April 2014 - 05:13 AM

I'm curious what the RGB components are of the alpha part of a PNG texture when it comes to alpha blending.

Given a PNG texture that is completely transparent with no color parts acting as the destination, and a red color {1.0,0.0,0.0,1.0} acting as the source in the glBlendFunc(GL_SRC_ALPHA, GL_ONE) equation:

Final color = (source color*source factor)+(destination color*destination factor)

= ({1.0,0.0,0.0,1.0}*1.0) + ({?,?,?,0.0}*{1.0,1.0,1.0,1.0})

I have no idea what OpenGL uses as the RGB component for a fully transparent texture in order to complete the equation.

### #2Brother Bob  Moderators

Posted 27 April 2014 - 05:29 AM

If you have an RGBA image, then every pixel have a defined RGB value. You cannot have an image where some pixels don't have certain channels at all. At the very least, your PNG loader will fill those with some default value or something if the PNG doesn't have any color information, and that's what OpenGL will see.

Edited by Brother Bob, 27 April 2014 - 05:31 AM.

### #3Shawn619  Members

Posted 27 April 2014 - 05:35 AM

Yeah, i'm just wondering if anyone knows what those default values are for image loaders like SOIL and DevIL.

### #4Hodgman  Moderators

Posted 27 April 2014 - 05:51 AM

[edit #2] Apparently I should be ranting at PNG exporters, rather than the PNG format itself! Thanks for the correction [/edit]

PNG is stupid in that it's authors made the assumption that the RGB values of transparent pixels aren't required.
If an artist tries to have pixels that have a particular colour value, but a zero alpha value, PNG jumps in and turns their colours into garbage.
AFAIK, the RGB values of invisible pixels in a PNG file are *undefined*, they're just garbage.

If you need this feature, which games very often do, then PNG isn't a suitable file format...
I personally deal with this problem by using a pair of two non-transparent files: one contains the RGB values, and the other contains the alpha values in the R channel... :-(

 if you don't need artist-authored values, and are ok with just some constant colour, then you can do this yourself after loading the PNG and before passing the pixel data to GL. Just loop over each pixel, check if alpha is zero, and if so, set RGB to your constant.

Edited by Hodgman, 27 April 2014 - 07:28 PM.

### #53TATUK2  Members

Posted 27 April 2014 - 08:03 AM

I'm pretty sure PNG "supports" having a proper RGB value. Obviously - there is still data there, regardless of whether it's "garbage" or not.

What determines whether it IS "garbage", is the editing application you use.

For example, I just tested with GIMP and it preserves the RGB just fine when you turn something into alpha.

### #6eppo  Members

Posted 27 April 2014 - 08:21 AM

You can make sure all pixels in a texture have a valid RGB value by setting the RGB value of zero-alpha pixels to the RGB value of the nearest pixel that has a non-zero alpha value.

One simple way is to do it during mipmap creation. At the pixel position, sample downwards to the lower detail maps until you find a sample that has some alpha value. Use the RGB value of that sample while leaving the alpha at zero.

### #7C0lumbo  Members

Posted 27 April 2014 - 08:28 AM

PNG is stupid in that it's authors made the assumption that the RGB values of transparent pixels aren't required.
If an artist tries to have pixels that have a particular colour value, but a zero alpha value, PNG jumps in and turns their colours into garbage.
AFAIK, the RGB values of invisible pixels in a PNG file are *undefined*, they're just garbage.

If you need this feature, which games very often do, then PNG isn't a suitable file format...
I personally deal with this problem by using a pair of two non-transparent files: one contains the RGB values, and the other contains the alpha values in the R channel... :-(

 if you don't need artist-authored values, and are ok with just some constant colour, then you can do this yourself after loading the PNG and before passing the pixel data to GL. Just loop over each pixel, check if alpha is zero, and if so, set RGB to your constant.

For some time, I also blamed the .png file format for this problem, but apparently it's not a deficiency of .png, but a deficiency of Photoshop's png exporter.

### #8BGB  Members

Posted 27 April 2014 - 11:12 AM

PNG is stupid in that it's authors made the assumption that the RGB values of transparent pixels aren't required.
If an artist tries to have pixels that have a particular colour value, but a zero alpha value, PNG jumps in and turns their colours into garbage.
AFAIK, the RGB values of invisible pixels in a PNG file are *undefined*, they're just garbage.

If you need this feature, which games very often do, then PNG isn't a suitable file format...
I personally deal with this problem by using a pair of two non-transparent files: one contains the RGB values, and the other contains the alpha values in the R channel... :-(

 if you don't need artist-authored values, and are ok with just some constant colour, then you can do this yourself after loading the PNG and before passing the pixel data to GL. Just loop over each pixel, check if alpha is zero, and if so, set RGB to your constant.

For some time, I also blamed the .png file format for this problem, but apparently it's not a deficiency of .png, but a deficiency of Photoshop's png exporter.

yeah, there is nothing in PNG itself to actually cause such an issue.

basically, it just stores raw RGBA data with some predictive filtering and Deflate compression, which works the same regardless of whether or not the pixel is transparent.

it is then up to the exporting application to determine what to save in these pixels.

some programs will just save whatever would have been present in the pixel if the pixel were not transparent.

some others will simply just clamp transparent areas to black, or maybe flood-fill with some other color.

"garbage" could be one of several varieties depending on the exporter:

is could just stupidly leak uninitialized memory values, which would be bad (not good for compression, ...);

or, it could be the encoder being clever, and forcing all prediction deltas to 0 in an attempt to get better compression (this being most likely to cause sort of a smeared-banding or rainbow-like patterns in transparent areas).

I don't personally have any experience with Photoshop (mostly just with GIMP or Paint.NET), and don't really know what it does in this case.

### #9Servant of the Lord  Members

Posted 27 April 2014 - 01:19 PM

RGBA values hold the RGB_ part of the value the same when you change the ___A channel. This is actually useful in an image editor, where you can adjust the transparency of certain pixels independently of you adjusting the color. It's also useful in games, where you might use all four RGBA channels to carry data other than image data.

For the PNG file format (or for OpenGL) to erase the RGB channels if the A channel is 0 would be terrible, at least to me.

If you need your RGB to be (0,0,0) if your A channel is (0), then run your images through a tool to pre-process them for your game.

It's perfectly fine to abbreviate my username to 'Servant' or 'SotL' rather than copy+pasting it all the time.
All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.
Of Stranger Flames -

### #10Shawn619  Members

Posted 27 April 2014 - 06:49 PM

Thanks for your very knowledgeable opinions, guys.

I believe that my opengl setup(SOIL+GIMP as PNG exporter) produces {1,1,1} RGB default values for color values that are unspecified.

For anyone interested in how i arrived at {1,1,1}, you can do you're own test if you're using a different texture loader and/or exporter than mine by doing the following:

Use the following blending equation,

glBlendFunc(GL_DST_ALPHA, GL_SRC_ALPHA);

with an opaque source color(a color with alpha=1, ie:{0,0,1,1}) and whatever transparent texture destination for testing.

Which will simply eliminate the srccolor and leave us with the unaltered destcolor,

Final color = (srccolor*srcfactor)+(destcolor*destfactor)

= (srccolor*Da)+(destcolor*Sa)

= ({Sr, Sg, Sb, 1}*0)+(destcolor*1)

=(0)+(destcolor)

=destcolor

My opengl render left me with a white color.

### #11Chris_F  Members

Posted 27 April 2014 - 08:01 PM

It makes perfect sense for a PNG encoder to set the RGB value to zero when the alpha value is zero because it allows it to compress the image better without changing the result. How were they supposed to know you would be using a RGBA image for something other than RGBA.

### #12Hodgman  Moderators

Posted 27 April 2014 - 08:29 PM

It makes perfect sense for a PNG encoder to set the RGB value to zero when the alpha value is zero because it allows it to compress the image better without changing the result. How were they supposed to know you would be using a RGBA image for something other than RGBA.

The problem with that is that they assume you'll only ever display the RGBA data with nearest-neighbor filtering / square pixels. Pixels aren't squares, but points, so it's not a valid assumption -- even on a web-page, the image might be rescaled, printed, etc.

Filling transparency with black is basically just using pre-multiplied alpha -- if they do that, they should also pre-multiply partially transparent areas. Then, programs displaying the PNG can compose it using pre-multiplied alpha blending, and everything is fine and dandy (any filter will work).

The Photoshop exporter seems to produce unpredictable RGB values in transparent areas though, so it's impossible to ever filter it with anything but nearest-neighbor (unless you modify the image first to correct for the exporter's mistakes)...

An ideal exporter would leave these as options for the user to choose

### #13C0lumbo  Members

Posted 28 April 2014 - 12:11 AM

Rather than thinking: "How were they supposed to know you would be using a RGBA image for something other than RGBA"

I think: "How dare they assume that my alpha value represents transparency!" - There are a million things you might want to use an alpha channel for.

Sure, have a tick box in the .png encoder settings to zero out the RGB for transparent texels, but don't turn it on by default, and don't do destructive actions without consent.

### #14LorenzoGatti  Members

Posted 28 April 2014 - 05:15 AM

Given a PNG texture that is completely transparent with no color parts acting as the destination, and a red color {1.0,0.0,0.0,1.0} acting as the source in the glBlendFunc(GL_SRC_ALPHA, GL_ONE) equation:

Final color = (source color*source factor)+(destination color*destination factor)

= ({1.0,0.0,0.0,1.0}*1.0) + ({?,?,?,0.0}*{1.0,1.0,1.0,1.0})

I have no idea what OpenGL uses as the RGB component for a fully transparent texture in order to complete the equation.

As already mentioned by others, if a pixel has an alpha component it necessarily has RGB components. But the error runs deeper: PNG compositing makes sense only with a fully opaque background, not with a fully transparent background. The bKGD chunk provides a reference colour that a transparent image is going to be composited over if not composited over some other opaque image.
This is completely different from pretending the transparent pixels are opaque: the red paint in the original question would be composited over the bKGD colour (unaffected by a whole image of fully transparent pixels), not over garbage RGB data that is harmless by design because it can only be non-drawn with zero opacity, never "resurrected" by pretending it's not transparent.

The PNG specification is unambiguous:

10.7 Background color

The background color given by bKGD will typically be used to fill unused screen space around the image, as
well as any transparent pixels within the image. (Thus, bKGD is valid and useful even when the image does
not use transparency.) If no bKGD chunk is present, the viewer will need to make its own decision about a
suitable background color.

Viewers that have a specific background against which to present the image (such as Web browsers) should
ignore the bKGD chunk, in effect overriding bKGD with their preferred background color or background
image.

The background color given by bKGD is not to be considered transparent, even if it happens to match the
color given by tRNS (or, in the case of an indexed-color image, refers to a palette index that is marked as
transparent by tRNS). Otherwise one would have to imagine something “behind the background” to composite
against. The background color is either used as background or ignored; it is not an intermediate layer
between the PNG image and some other background.

Indeed, it will be common that bKGDand tRNS specify the same color, since then a decoder that does not implement
transparency processing will give the intended display, at least when no partially-transparent pixels
are present.

In practical terms, what's wrong is putting meaningful RGB data but alpha=0 in all pixels of the original image: it should have either fully opaque alpha (255 or 65535 depending on bit depth) or RGB format (Color Type 2 rather than 6).

Omae Wa Mou Shindeiru

### #15Kaptein  Prime Members

Posted 29 April 2014 - 05:24 AM

Why use photoshop? It costs money, is bloated and is it really required these days?

GIMP 2 has alot of features too, even if its shit by my standards. At least its PNG exporter works.

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.