Sign in to follow this  
AaronWizardstar

Handling transparency for sprites with holes in them

Recommended Posts

[attachment=13429:grafix.png]

 

My game's look is inspired by raycaster shooters like Wolfenstein and first-person-perspective RPGs like the Might & Magic series. Instead of models I'm going to have flat textured quads. That means I'm going to have to handle transparencies just to accommodate sprites with holes in them.
 
So far I'm able to get by with the discard command in my fragment shader, though since that leaves jagged edges I'm forced to adopt a heavily pixelated look. The heavily pixelated look would likely match the flatish structure of my scenes, but I was hoping for something a bit more...linear filtered. Not that this would apply to my low-res placeholder graphics.
 
In this case I believe my options are either to buckle down and sort the transparent quads, or do some kind of fullscreen anti-aliasing. Sorting might be easy due to the fact that it's just quads all the time, while fullscreen anti-aliasing may be something I want to support anyway. Are there any other options I'd have?

Share this post


Link to post
Share on other sites

Since you don't want partial translucency: just discard pixels with an alpha of less than 0.5. As a bonus you won't even need to sort quads since there isn't any blending involved, the depth buffer by itself is enough.

 

EDIT: oh, I see what you mean. But the method still works for linear filtered textures (for example, look at the trees in Super Mario 64 - yes, it's the same method). If you want partial translucency then you have no option but to do proper blending.

Edited by Sik_the_hedgehog

Share this post


Link to post
Share on other sites

There's a method of computing a "distance field" from the texture to give the texture an edge that's sharp but not blocky. Here's a paper discussing how to use the method for textured fonts/decals:

 

http://www.valvesoftware.com/publications/2007/SIGGRAPH2007_AlphaTestedMagnification.pdf

 

I'm not sure how easily it can be applied to full-color sprites, but I think it could be done.

Edited by BLM768

Share this post


Link to post
Share on other sites

can't alpha blend them?

Not really unless I want to also use the depth buffer. Here's a scene with proper sorting and linear filtering:

[attachment=13478:right_sorting.png]

 

And the scene without proper sorting and no use of discard in the fragment shader:

[attachment=13479:block_no_alpha.png]

 

And the scene where I discard pixels with alphas of 0.5 or less:

[attachment=13480:block_50_alpha.png]

Share this post


Link to post
Share on other sites

Yeah, you need to make sure that the pixels that are supposed to be transparent still have the same colors as the surrounding ones that aren't, or color bleeding like in the last pic will happen. Also you need to make the borders of the texture translucent if you don't want sudden clipping (if you want a texture to wrap around (e.g. a wall) then by all means make the borders opaque though).

 

There isn't really any workaround for the jagged edges, that comes with bitmaps. Either make them a higher resolution, or resort to vector graphics (at least to cut the borders). Although remember that most of the time you won't have sprites that close to the camera anyway, so the texels won't look as big in practice.

Edited by Sik_the_hedgehog

Share this post


Link to post
Share on other sites

Yeah, you need to make sure that the pixels that are supposed to be transparent still have the same colors as the surrounding ones that aren't, or color bleeding like in the last pic will happen

I thought the bleeding was caused by the depth buffer in my picture.

 

In my last two examples I'm drawing the slug before the wall behind it. That draws a big square to the depth buffer. In the picture where I don't discard any fragments at all I get the big blue square surrounding the slug and blocking the wall behind. In the picture where I discard fragments with alpha less than 0.5 there are still fragments that, while having an alpha less than zero, still block the wall behind since they're drawn to the depth buffer.

Edited by AaronWizardstar

Share this post


Link to post
Share on other sites

The discard method (last picture) doesn't have any blending at all, pixels are always either opaque or missing, so the depth buffer never gets in the way (it's exactly the same as drawing a normal triangle). It's when you have blending that the depth buffer becomes an issue (first image).

 

The "bleed" pixels have alpha > 0.5, the reason they have the wrong color is because the texture filtering is being applied between the solid and transparent texels (this is true even for the alpha channel, which is why the borders are rounded). The behavior is entirely correct, the textures need to take this into account.

Share this post


Link to post
Share on other sites
I think the blue border is not from texture filtering but from combining the half transparent pixels with the blue background pixel thats already in the framebuffer. Then its written back into the framebuffer and the depth of the sprite is put into the depth buffer so it blocks the later drawing of the wall. You need to change the alpha to 1 for all pixels you dont discard inside the fragmentshader to prevent this.
A more exact method would be draw everything back to front and only discard pixels with alpha==0. Or clear framebuffer to black not blue, draw front to back, discard everything with apha!=1 to make use of the depth buffer for solid objects, then draw anything thats transparent back to front and this time discard alpha==0 and alpha==1. Edited by wintertime

Share this post


Link to post
Share on other sites

I think the blue border is not from texture filtering but from combining the half transparent pixels with the blue background pixel thats already in the framebuffer. Then its written back into the framebuffer and the depth of the sprite is put into the depth buffer so it blocks the later drawing of the wall. You need to change the alpha to 1 for all pixels you dont discard inside the fragmentshader to prevent this.

 

Or just disable alpha blending.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this