Crisp edges effect

This forum is currently in read-only mode.
  • 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! ), 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.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • Here are the effects I promised:

    There are three effects included:

    • Alphatesting.fx - (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. <img src="http://img13.imageshack.us/img13/585/alphatestingscreenshot.png">
    • 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. <img src="http://img12.imageshack.us/img12/5684/smoothalphatestingscree.png">
    • 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. <img src="http://img3.imageshack.us/img3/170/smoothalphatestingpluss.png">

    And in case you're wondering, here's the original image:

    <img src="http://dl.dropbox.com/u/762468/Construct/Demos/DistanceMapProper.png">

    Doesn't look like much, now does it? That's the whole point.

    BTW, I didn't make that image, I found it here: http://www.gamedev.net/community/forums/topic.asp?topic_id=490373

    That's about it for now.

    Coming up next: multi-color images and an easy technique for distance field creation.

  • That's really cool

    Any new effects are good in my book. Good job, man.

  • 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.

  • 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.

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

    <img src="http://www.scirra.com/images/crisp.png">

    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.

  • Hmm, what about semi-transparent objects? If this changes the alpha channel, then they'd be hollowed out?

  • 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.

  • if you enabled it for an entire game, you could double your VRAM requirements

    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.

    As Quazi pointed out, you can probably also achieve this with a shader that quantizes the alpha channel to either 0 or 1.

    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: http://ati.amd.com/developer/gdc/2007/Green-Improved_Alpha-Tested_Magnification_for_Vector_Textures_and_Special_Effects(Siggraph07).pdf

    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.

    Hmm, what about semi-transparent objects? If this changes the alpha channel, then they'd be hollowed out?

    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:

    <img src="http://img25.imageshack.us/img25/5838/yayr.png">

    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.

  • 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.

  • Okay, an explanation seems in order.

    Alphatesting effect does not require a distance field. It can work with any alphachannel the image has. Distance field is used to enhance the image quality for high magnification levels. It is used to achieve vector-like quality for monochrome images, and also to reduce the image size (that 'No trespassing' sign used in Valve's article is as small as 64x64, and it produces an image that can be zoomed in without any limitations).

    All the effects I linked to here work regardless of what kind of alphachannel the image has - distance field, or regular alpha, or just something random.

    Distance field is solely a technique to improve the visual quality of the result by manipulating the alpha of the original texture. And yes, there is a way to generate it automatically. For example, this forum thread has an implementation for Unity. Also, there is a trivial way to generate a distance field from a vector shape in Xara Xtreme (I'm looking for a way to achieve the same result using freeware tools).

    The bottom line is: 1) Alphatesting is just that - a render state. It doesn't care about distance fields or whatever. 2) Distance field is a technique to improve visual quality of monochrome images. Judging by the image you provided, distance field technique is superior to your Crispify effect. The downside is the need for non-trivial edittime image preprocessing.

    All in all, alphatesting is a very trivial and generic thing, and it's widely used in 3d games to render, for example, tree foliage, since alphablended images don't go too well with z-buffering.

    Distance field, however, is a trick to make the most out of alphatesting, and increase the resulting image quality to the level of vector graphics. It is a very niche thing, and I don't expect it to be used a lot. But, for example, Thomas Mahler's platformer likely could benefit from it.

    I apologize for not making myself clear.

  • Okay, guys, here's a simple way of generating distance fields using Photoshop:

    http://www.horde3d.org/wiki/index.php5?title=Preprocessing_Technique_-_Distance_Field_Vector_Textures

    Photoshop is even less freeware than Xara , but it's more widespread and saves you the effort of tracing your raster images.

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)