Problems with alpha channel in Textures.

Started by
3 comments, last by ill 13 years, 6 months ago
So I did a bunch of reading on this and still don't fully know how to fix this...

Before I was using png images and was getting an ugly whitish border around the edges after saving them for web with Photoshop CS5 just like this guy: Why do my PNG textures have a whitish thin border?



Then I switched to tgas saved with GIMP and started getting a similar blackish border. So in Photoshop it fills the transparent pixels with white, and GIMP does with black so as I understand the border pixels outside are being blended with, even when OpenGL is showing the image with no transformation.

You can see an annoying blackish border around every texture. The character is drawn from multiple sprites, so you can see a black border around the head, arm, and legs.


Then I tried using a different blend mode according to all the posts. Before I was using glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); and I swithced to glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

It seems to work on the character as the blackish parts seem to dissapear. The bodyparts now look perfectly blended together.


But notice the ugly pink on the corners of the crosshair. It's very subtle but it doesn't seem to blend that transparent part correctly anymore. BTW it looks magenta pinkish even with a black background.

There's a bunch of stuff about alpha premultiplying and as I can understand, I don't want my images alpha premultiplied so I can use glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); It properly blends the transparent parts.


I'm using DevIL to have my engine load the images and I can't find anywhere whether or not it premultiplies the alpha. Also I can't find any info specifically whether or not GIMP and Photoshop CS5 do this when exporting the images.

I just want the texture edges to blend perfectly and get on with the game development. It's times like this I just wanna give up UGHGHGHG...
Advertisement
You can disable linear interpolation on the texture (use GL_NEAREST). This gives a pixelated look though. A common way to deal with transparent images:

1.) Use a background color that is nearly the same as the average sprite texture. Your green space marine could have a greenish background as well. If you use black, pink or another different color, you risk the edges getting blended with the sprite-background as well if you use (linear)texture interpolation. And that is probably what you want to prevent a pixelated look. Interpolation means that each pixel also grabs somewhat color from it's neighbors (thus also the background at the edges) to smoothen the look. Older games like Doom didn't do this, which is why you didn't get the edges either.

2.) Use an alpha channel to mask the background:
- Copy your sprite to another (grayscale) texture
- Use a very different background color this time. In case the sprite is pretty bright, use a black background. The trick is to make a 2 colored black/white image first. You can use threshhold / stretch filters for this.
- Now that you have a perfect mask, you can blend the edges inwards. With a small gaussian blur for example. But be careful not to generate grayish pixels outside the mask. What you could do BEFORE blurring is removing 1 pixel at the edges. Maybe with a "narrow" / "shrink" filter or something.
- Now the edge pixels are somewhat grayish, meaning that they fade out.
- Depending on how your painting program works, import the grayscaled alpha texture into your original sprite.
- Save as a 32 bit TGA, PNG or DDS (make sure it supports alpha channels)
- Do NOT use compression! Compression messes the edges up again due quality loss.

3.) Import the texture. Make sure the import and output formats are RGBA, not RGB! You'll need to load and store that alpha channel as well. Enable interpolation on the texture (GL_LINEAR, mipmap, or something else).

4.) When rendering, enable blending.

That should do the job
Rick
Yeah so I have Trilinear or Bilnear filtering, forget which, on all the sprite textures.

And they have RGBA for sure, at least I'm sure about tgas. Pngs are weird apparently and I'm not 100% sure but it usually works with everything else I've ever done.

How do other people cleanly display sprites in hardware accelerated engines? I used to use Game Maker and since the 6th one it used Direct 3D for hardware acceleration and all the sprites looked very clean without any of the problems I'm having with OpenGL.

Also there are DooM source ports like GZdoom that have OpenGL mode and are able to render sprites without annoying border bleeds.



Cyan is the transparency color in DooM and there seem to be no signs of cyan border pixels. Of course maybe when they load the images they just replace the cyan with black or something because I've seen screenshots with black border problems like I'm having.

I just found this article and LOL'ed when I got to the bottom of the article. Ugly magenta border edges...
Rendering Efficient 2D sprites
you could always put on alpha testing, and thatll cut the edges of the sprites off in a hard fashion, thatll get rid of all the errors but its in an either completely off or completely on fashion.
I tried alpha testing and it doesn't really give good results unfortunately.

What I was really wondering is if anyone knows about how the programs I mentioned handle alpha channel. Do they premultiply it? If so how would I go about disabling it.

This topic is closed to new replies.

Advertisement