Crisp edges effect

Forum for plugin, effect and behavior programmers. Please use the Help & Support forum for help using Construct.

Post » Thu Mar 05, 2009 4:49 pm

Unless your sprites are perfectly rectangular, you'll have to deal with alphachannel for them. As you know, Construct has two modes for rendering: point and linear sampling. First one suits well for retro styled games with sprites having (essentially) 1-bit alpha, and the second for pretty much all the rest, with sprites having a smoother alpha channel. (I mean that 1-bit alpha suits point sampling, and full 8-bit alpha goes well with linear sampling)

The problem is that neither is suited for zooming things up a lot. With point sampling you get huge pixels, and with linear sampling you get an ugly blurred mess. And if you, say, double your sprites' resolution to fight that, you'll spend a lot of VRAM, 4 times more than before.

There is a way to get smooth (without huge pixels showing up) but crisp (without messy blurriness) edges. It has some limitations, though, and that's the exact reason why it isn't used every time by everyone.

Here's the original article: http://www.valvesoftware.com/publicatio ... cation.pdf
Hey, if it's good enough for Valve and their Team Fortress 2, then it's good enough for us, right?

Anyway, if you're too lazy to read the article and figure the limitations out by yourself (and you should be! :D), here they are:
The image should be monochrome (not necessarily black, just one flat color), and the result will be aliased.
The upside is that you don't need any shaders, it's basically a 0.0 effect. All it takes is a proper alphachannel, and two render state flags.
Good news: you can also get rid of the aliasing with a very simple shader.

Better yet, if your sprites are cartoony, that is, use a low number of distinct flat colors, you can still benefit from this technique.

You see, according to the four color theorem, you can separate said sprites into four layers each, so that on every layer differently colored areas do not touch. Of course, drawing 4 sprites instead of just one means 4 times greater load on the GPU, but that's still much less of an performance impact than most shaders make.

Examples of usage will hopefully follow soon.
B
4
G
4
Posts: 65
Reputation: 1,305

Post » Fri Mar 06, 2009 9:55 pm

Here are the effects I promised:

There are three effects included:
[list:3e7ntf8f]
[*:3e7ntf8f][u:3e7ntf8f]Alphatesting.fx[/u:3e7ntf8f] - (Now comes with Construct, thanks to David) as simple as it gets. It's a 0.0 effect, and it simply changes the renderstate: it disables alphablending and enables alphatesting. For whatever reason, it doesn't work for Sprite objects (works just fine for Tiled Backgrounds, though), so there's an object on a separate layer with Alphatesting effect applied to this layer.
[/*:m:3e7ntf8f]
[*:3e7ntf8f]Smooth Alphatesting.fx - this is a full-blown (albeit trivial) PS 2.0 shader, so it works fine, Sprite object or not. It has smooth edges, unlike Alphatesting.fx.
[/*:m:3e7ntf8f]
[*:3e7ntf8f]Smooth Alphatesting Plus.fx - this is slight variation of Smooth Alphatesting, the only difference being that you can specify alpha cutoff values manually (play with the values to see what they do, one picture is worth a thousand words). This is likely what you'd want to use. Smooth Alphatesting is only included because I suspect that it might be slightly faster than this one.
[/*:m:3e7ntf8f][/list:u:3e7ntf8f]
And in case you're wondering, here's the original image:

Doesn't look like much, now does it? That's the whole point.
BTW, I didn't make that image, I found it here: [url:3e7ntf8f]http://www.gamedev.net/community/forums/topic.asp?topic_id=490373[/url:3e7ntf8f]

That's about it for now.
Coming up next: multi-color images and an easy technique for distance field creation.
B
4
G
4
Posts: 65
Reputation: 1,305

Post » Fri Mar 06, 2009 11:32 pm

That's really cool :D

Any new effects are good in my book. Good job, man.
Moderator
B
5
S
2
G
6
Posts: 4,348
Reputation: 10,971

Post » Fri Mar 06, 2009 11:57 pm

hmm this is interesting, and extremely similar to something i had tried before, except i used colourise, and it gave me the excact same effect (minus the thresholding of course).i got the idea form my blob effect which gave crisp edges from a blurry picture, so i tried using it on something like that A. its cool how similar ideas can occur in very different ways.
B
52
S
7
G
6
Posts: 1,945
Reputation: 7,610

Post » Sat Mar 07, 2009 1:26 am

That's cool but how on earth do you make the distance map image? Even if it's easy, if you enabled it for an entire game, you could double your VRAM requirements. As Quazi pointed out, you can probably also achieve this with a shader that quantizes the alpha channel to either 0 or 1.
Scirra Founder
B
359
S
214
G
72
Posts: 22,949
Reputation: 178,554

Post » Sat Mar 07, 2009 1:45 am

Well I tried the alpha channel quantisation idea, tweaked it to slightly smooth out the edges, and here it is:



I've called the shader 'Crispify' and it's in the next build. Note the edges are crisp, but the internal colours are still linear filtered! Better yet, it's shader model 1.1, and no distance map needed. :)
Scirra Founder
B
359
S
214
G
72
Posts: 22,949
Reputation: 178,554

Post » Sat Mar 07, 2009 8:03 am

Hmm, what about semi-transparent objects? If this changes the alpha channel, then they'd be hollowed out?
B
62
S
21
G
12
Posts: 1,910
Reputation: 13,155

Post » Sat Mar 07, 2009 9:04 am

I don't think semi-transparencies will work for this. Think of it like .gifs, it's either transparent, or not transparent, semi-transparencies should just be averaged in.
Image Image
B
161
S
48
G
90
Posts: 7,348
Reputation: 66,751

Post » Sat Mar 07, 2009 10:01 am

[quote="Ashley":2zcl30a8]if you enabled it for an entire game, you could double your VRAM requirements[/quote:2zcl30a8]
No. A regular alpha channel is used for a distance map. Read that Valve's article. So there's absolutely no reason to double the VRAM usage. If the simplest effect is used (the only one that is in fact alphatesting) then even effect buffers won't be allocated, probably. Since it isn't a shader, just a different renderstate.

[quote="Ashley":2zcl30a8]As Quazi pointed out, you can probably also achieve this with a shader that quantizes the alpha channel to either 0 or 1.[/quote:2zcl30a8]
That's exactly what my effects do.

Ashley, that 'distance field' deal serves a single purpose: to provide an way to scale sprites without any performance impact and without detail loss. The 'effect' itself is trivial, as you pointed out. See my Alphatesting.fx. It's a 0.0 effect, for god's sake! Of course you can use it without any distance fields, but distance field's purpose is to provide smooth curves. Try taking that 'a' letter image, blurring it's alphachannel and applying alphatesting to it. All the sharp corners will be lost.

Anyway, here's another presentation about it: [url:2zcl30a8]http://ati.amd.com/developer/gdc/2007/Green-Improved_Alpha-Tested_Magnification_for_Vector_Textures_and_Special_Effects(Siggraph07).pdf[/url:2zcl30a8]

Speaking about distance fields. There is a trivial way to produce one: using Xara Xtreme's Contour tool. I'm yet to find a free alternative to this, since Inkscape can't do it.

[quote="Mipey":2zcl30a8]Hmm, what about semi-transparent objects? If this changes the alpha channel, then they'd be hollowed out?[/quote:2zcl30a8]
Nope, no luck with semitransparent sprites. With alphatesting a pixel is either drawn (if it's alpha is lower than a threshold specified), or not. That's the whole purpose of alphatesting.

Well, actually, you can have semitransparent images with alphatesting. You'll just need a slightly different effect for that, the one that doesn't disable regular alphablending. However, it's a tricky and completely counterintuitive thing to use:

As you can see, you can't avoid having wonky transparency around the edges. David discovered this effect by accident, it was somewhat unexpected that alphablending and alphatesting aren't mutually exclusive. I won't go into details of using this weird effect, play with it yourself, if you absolutely need to.
B
4
G
4
Posts: 65
Reputation: 1,305

Post » Sat Mar 07, 2009 3:55 pm

Your shader may be just renderstates, but isn't it considerably easier to use a 1.1 effect than to use an external program to generate a distance map for every texture you want crisped up in the game? Unless there's some library or effect we can plug in to automatically generate distance maps, it's a lot of boring legwork if you want to crisp up a lot of the graphics in your game.
Scirra Founder
B
359
S
214
G
72
Posts: 22,949
Reputation: 178,554

Next

Return to Construct engineering

Who is online

Users browsing this forum: No registered users and 0 guests