Sign in to follow this  

Feathering with Alpha Blending

This topic is 4270 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've been looking into ways to render vegetation and make it look good. On grass I tried alpha blending which looks great, but the sorting was a headache. I tried alpha testing, but the edges are so aliased it looks like crap from up close. So then I read in the GPU Gems 2 article "Toward Photorealism in Virtual Botany" of what the author calls 'feather the edges' into the scene. I got this working and I wanted to show the results. First, take a look at this grass with alpha testing only. And here is the result with the 'feathered edges'. This shot shows the difference in red. The good thing about this technique is that it looks just like alpha blending only, and it is effective even when only applied to nearby vegetation. The bad thing is that it takes an extra pass. But it's definately a step toward getting away from the ugly alpha tested look.

Share this post


Link to post
Share on other sites
Oops I forgot to show the implementation. The technique sums it up nicely.

technique SM11
{

pass P0
{
VertexShader = compile vs_1_1 vs11();
PixelShader = compile ps_1_1 ps11();

AlphaBlendEnable = true;
SrcBlend = SrcAlpha;
DestBlend = InvSrcAlpha;
ZWriteEnable = false;

}

pass P1
{
VertexShader = compile vs_1_1 vs11();
PixelShader = compile ps_1_1 ps11();

AlphaTestEnable = true;
AlphaRef = 0x00000040;
AlphaFunc = GreaterEqual;
ZWriteEnable = true;

}
}

Share this post


Link to post
Share on other sites
Hmm, I really have to pay more attention to what I'm reading. I've had that book for quite a while, but I completely missed the feathered edges thing and was planning on using plain alpha testing myself for a project. Thanks for pointing it out & showing the results [smile]

Share this post


Link to post
Share on other sites
Isn't the passes defined in the wrong order? The way I see the technique it would work best by rendering opaque vegetation geometry first which would setup a correct depth buffer and then render alpha blended parts. The idea is that only minor artifacts are visible where alpha blended plant edges overlap.

Share this post


Link to post
Share on other sites
I tried it the other way around and noticed more obvious artifacts. I can't think of a good explanation for this though, the way you described seems to make more sense.

Share this post


Link to post
Share on other sites
The order seems to be correct from the way I understand this technique. Basically you use alphablending first to render the geometry. This step would normally suffer from sorting issues, but since we're only interested in the outer edges, we don't care about these artifacts.

Next we render the opaque geometery on top of the alphablended meshes with the alpha test. This will cover the areas where the 'no sorting artifacts' were apparent, effectively leaving only the featered outer edges of the first alphablending render pass visible.

Share this post


Link to post
Share on other sites
That seems to make sense too, I just thinking that it does involve alot of unnecessary overdraw. Why draw the alpha blended areas with sorting artifacts in the first place if they are going to be covered up in the following pass by opaque geometry?

Share this post


Link to post
Share on other sites
Yep, you're indeed stuck with at least one overdraw in the best case of a simple quad, but I guess that's both easier and generally more efficient than sorting for alphablending, especially when it comes to sorting mesh subsets like branches.

The overdraw doesn't seem unnecessary though, since it serves to cover up the noticable sorting artifacts on the opaque parts of the geometry. The transparent regions of the 1st alphablend pass will be preserved because of the alpha-test in the 2nd pass, giving the geometry it's feathered look... You could reduce the overdraw by using an alpha test on the 1st pass as well (to draw only for Less than the alpha threshold) but I think the testing is probably less efficient than just drawing it twice.

Share this post


Link to post
Share on other sites
My point was that sorting the geometry is not needed in either case. I think they should look more or less the same with only the overdraw being the difference.

Share this post


Link to post
Share on other sites
Sorry about the confusion, I already had a feeling I was missing your point [smile]

Share this post


Link to post
Share on other sites
I'm thinking an even better approach would be to render all my vegetation with alpha testing first(before i was doing two passes on each object consecutively), and then re-render the close stuff with alpha blending. This way the only blending glitches will be edge-edge, instead of edge-entire object, if you know what I mean. It will also cut down on fill rate since only the edges in the second blending pass will pass the test, like donnie said. What do you guys think?

Share this post


Link to post
Share on other sites
You should try alpha to coverage.

It's screen door transparency with dithering and when MSAA is enabled the dithering is almost invisible (unless you have large parts of the images covered with it, and that you shouldn't anyway).

Enabling Alpha to coverage is explained there :
Antialiasing with transparency
(it's called transparency multisampling in this document but it's really alpha to coverage).

Advantages : feathered borders, single pass, no sorting
Drawbacks : dithering, you need at least 4x MSAA to enable the effect (but then if you rendered without antialiasing you probably didn't care about your vegetation aliasing..). Not available on all hardwares (geforce 7 and later, it should be integral part of the D3D10 API).

LeGreg

Share this post


Link to post
Share on other sites
I tried a technqiue where the passes are reversed a slightly mofified. It seems to work fine and theres no overdraw.

Btw. is there any performance benfit from reducing overdraw with depth buffer over alpha test?


technique Foliage
{
pass P0
{
AlphaBlendEnable = False;
AlphaTestEnable = True;
AlphaRef = 255;
AlphaFunc = Equal;

VertexShader = compile vs_1_1 vs();
PixelShader = compile ps_2_0 psTex();
}

pass P1
{
AlphaTestEnable = False;
AlphaBlendEnable = True;
SrcBlend = SrcAlpha;
DestBlend = InvSrcAlpha;

ZFunc = Less;
ZWriteEnable = False;

VertexShader = compile vs_1_1 vs();
PixelShader = compile ps_2_0 psTex();
}
}

Share this post


Link to post
Share on other sites

This topic is 4270 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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