Improved Alpha Magnification

Published April 13, 2008
Advertisement
As mentioned in this post, I've been having a crack at Valve's Improved Alpha Tested Magnification technique. I've mostly just been hacking around to see what the results are, so it's all rather special-cased and hard-coded at the moment, but it's enough to see if it's worth carrying on further.

Here's the current results:



Now you're (hopefully) thinking "that's a mighty fine looking 'a'", but the really neat part is how little resources it takes to draw it - a single 32x32 sprite on a single quad with a tiny ~25 line shader. [grin] Yup, even enlarged sixteen times it retains the smooth curves even though the actual texture data is miniscule. In fact I've found it can be enlarged pretty much indefinately and still look awesome.

The shader is a bit too complicated for my liking (two texture samples, a fwidth() screen-space derivative, three smoothstep() calls and a couple of branches) but compared to Ysaneya's 250+ line and 10+ texture sampling shader behemoths it's pretty light weight. I suspect I'm being a little too old-skool and worrying too much about it.

The fixed-function fallback is just done with an appropriate alpha-test value, and so won't give soft drop shadows or antialiasing but the shape is the same. And outlining can be done by drawing it twice with different alpha test values.

At the other end of the scale, small text isn't too bad either:



That's shrunk down to half size (16x16), and still comparable in quality to a bitmap font renderer at the same size. Drop shadows will work, but at that scale outlining tends to get pixely due to not having enough physical space to fit a proper outline into.

The Dilemma
Now I have a dilemma - do I write a proper text renderer using this and replace my current bitmap font rendering method? For people with shader capable cards (GF FX and up) it's better in all areas. For shaderless people (ie. people with those crappy intergrated intel chips) it means they'll get scalable aliased text instead of unscalable, antialiased text. I'm not sure that's a tradeoff I'm willing to make, as much as I'd love the greater flexibility.

Is it about time to say "screw it" to people with crappy graphics cards and just go for GL2.0 features as a baseline (FBOs, VBOs and proper GLSL shaders)? On the one hand that goes all the way back to the GeForce FX, which is five years old now - a long time in graphics hardware. On the other hand theres a lot of people with lousy intergrated intel chips (laptop people mostly), and I'm not sure if I want to shut them out. And I'd rather not try and maintain two completely different renderers for the different paths because I've only one pair of hands (and fundamentally, want to concentrate on writing games, not hardware specific workarounds).

So what do you people aim for, hardware-wise? As high as your development machine? An arbitrary base line spec? As low as possible? Comments highly appreciated.
0 likes 12 comments

Comments

dcosborn
That's really, really cool! Good job implementing it.

I would personally go for Value's technique, with alpha-testing as an acceptable fallback for shaderless cards. Someone with an older card can't expect optimal image quality, including antialiasing IMHO.

I can't believe I went through the trouble of writing a cached FreeType scalable-text renderer only for it to be obsoleted by something as elegant as this.

[bawling]
April 14, 2008 12:14 AM
Gaiiden
Quote:Original post by OrangyTang
but compared to Ysaneya's 250+ line and 10+ texture sampling shader behemoths...

Oooh you calling out Ysaneya? Fight! Fight! Fight!

Yea I'm such a grade schooler I know [grin]
April 14, 2008 08:38 PM
OrangyTang
Quote:Original post by Gaiiden
Quote:Original post by OrangyTang
but compared to Ysaneya's 250+ line and 10+ texture sampling shader behemoths...

Oooh you calling out Ysaneya? Fight! Fight! Fight!

Heh, I guess I phrased that wrong. What I mean is if Ysaneya can write 250+ line shaders and still have it run in realtime, then trying to trim a 20 line shader down further is probably being overly paranoid. I suspect I underestimate current graphics hardware considerably - I thought my original hacky shader would run at about 1fps but it flew along with no problems.
April 15, 2008 03:27 AM
Stani R
Cool looking "a" :)

Not like I have much to show so far, but my goal has always been OpenGL 2.0 support as baseline. No point in wasting time on workarounds and alternative paths when I can spend that time on game code. A one man army is always on a tight schedule. Then again, by the time I'm done, we'll be five years or more into OpenGL 3.0 already...
April 15, 2008 10:09 AM
chrisward81
Can we see the shader source please?
April 15, 2008 02:21 PM
PlayfulPuppy
Another request for shader source! :D

Also, I wouldn't worry about integrated graphics chips that much anymore. Hell, my $500AU Eee laptop can do Pixel Shader 2.0!

That said, though, an alpha-tested fallback shouldn't be too hard to do. If you're worried about aliasing, just draw the character several times with a low opacity and jitter the positions slightly, but when it comes to older systems (Older than 5 years, for sure), I generally just think "Make it work, don't worry about making it pretty".
April 15, 2008 10:21 PM
supagu
+1 shader source request
April 16, 2008 01:00 AM
Ysaneya
Quote:Original post by OrangyTang
Quote:Original post by Gaiiden
Quote:Original post by OrangyTang
but compared to Ysaneya's 250+ line and 10+ texture sampling shader behemoths...

Oooh you calling out Ysaneya? Fight! Fight! Fight!

Heh, I guess I phrased that wrong. What I mean is if Ysaneya can write 250+ line shaders and still have it run in realtime, then trying to trim a 20 line shader down further is probably being overly paranoid. I suspect I underestimate current graphics hardware considerably - I thought my original hacky shader would run at about 1fps but it flew along with no problems.


If 30 fps on a GF8 is real time, then yes, my 250-lines shader is real time :) But I don't want to test it on a less powerful card :) (of course it's scalable, so I wouldn't even try it "as is" on a slower card). Plus you make it sound like I'm happy with it, while in reality I'm dreaming of getting a better quality for a lower amount of instructions.

But yes, a 20 lines shader is peanuts for any less-than-5-years-old card. As long as it's one designed for gaming. I give no guarantee on integrated, Intel-based chips :)

As for this "Improved Alpha Tested Magnification" technique, it's very interesting. The shader only performs additional special effects like those glows/outlines as I understand it; the basic effect works by taking special care when building the texture, and using an alpha test of 0.5. No shader needed for it.

The confusing part is when building the texture from the signed distance. One texel in the low-res/final texture maps to a lot of texels in the high-res. How do you compute the squared distance for that low-res ? Is it just simply a matter of computing the squared distances for all the high-res texels, then downsample (average) it until the low-res target is reached ?
April 16, 2008 04:06 AM
OrangyTang
I've posted the source in a new journal entry. Please stick any new questions in the comments there or I get confused and probably won't see your reply.

Quote:Original post by Ysaneya
The confusing part is when building the texture from the signed distance. One texel in the low-res/final texture maps to a lot of texels in the high-res. How do you compute the squared distance for that low-res ? Is it just simply a matter of computing the squared distances for all the high-res texels, then downsample (average) it until the low-res target is reached ?

This was the part I had most problems with - the Valve paper really doesn't explain it very well (in particular it tends to use "texel" and "pixel" interchangably and doesn't indicate when it's talking about the source image or the output distance map.

You can see it in the new source posted, but basically:
for each texel in output distance map:
find the pixel in the input map which is at the exact center of this texel
if this pixel is white, we're inside, otherwise we're outside
find the nearest pixel of the opposite colour
find the distance between these two pixels
if the first pixel was inside, then the distance is +itive, otherwise -itive.

Once you've done that for all output texels you can go over it and normalise it to [-1..+1] scale, and then map that onto the [0..255] range for actual alpha values.

Hope that helps.
April 16, 2008 07:57 AM
rollo
Unless you do this for work and have to support old hardware I say this: People with crappy intel graphics cards DON'T DESERVE nice graphics.

damn, it felt good saying that....
April 18, 2008 12:14 PM
skullfire
Screw people with crappy graphics cards :D


Speaking seriously though, I would like to see the difference of this kind of text versus the crappy bitmap font one (both on the same UI for example). I suppose saying "screw it" is good enough if the rest of the features of the game you are developing will only run ok on decent graphic cards, otherwise you should probably stick with support :P
April 18, 2008 04:54 PM
NineYearCycle
You can't support everyone forever and 5 years seems like a reasonable cutting off point! That said we're supposedly still targetting GF3 (<-- 3!!!) as our min-spec'. Our case is however more an example of the ridiculous leading the stupid.

I.e: Time to cut-off those Intel onboard graphics cards methinks ;)

As for the technique itself, I think it looks really good! Though I'm sure you've already realised that much yourself.

Andy
April 22, 2008 08:55 AM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Advertisement
Advertisement