Page 1 of 2

Techniques for improved font rendering?

Posted: Fri Jul 08, 2011 12:01 pm
by VilleK
I read this thread on stackoverflow and it provides an interesting discussion on how to render nice fonts in OpenGL:

http://stackoverflow.com/questions/5262 ... ersion-4-1

It mentions this paper which describes a technique of rendering fonts using a signed distance field with superb results:

http://www.valvesoftware.com/publicatio ... cation.pdf

And there is a tool that helps creates distance fields textures for fonts:

http://www.gamedev.net/topic/491938-sig ... font-tool/

Anyone up for attempting this in ZGE? :)

Posted: Fri Jul 08, 2011 1:27 pm
by Kjell
Hmm,

Not quite sure how they prevent the false curved contours ( without the use of shaders ). It looks quite janky when I try it ( 128x128 distance field with aliased rendering ).

K

Posted: Fri Jul 08, 2011 2:10 pm
by Kjell
:)

Never mind, guess it really depends on the resolution of the original source how well the scaling performs ( makes sense ). Screenshots use a 128x128 distance field again, but this time with anti-aliasing.

I'll try the double distance field to preserve sharp edges trick some other time.

K

Posted: Fri Jul 08, 2011 2:38 pm
by VilleK
Looks awesome Kjell :)

I'm impressed with how quick you got that working.

It would be great if you can provide a working example. We could use this for improved text rendering in ZgeViz and it could be included as a sample project in the standard ZGE distribution too.

Posted: Fri Jul 08, 2011 7:11 pm
by Kjell
Sure,

There's not a whole lot to it ( for the aliased shaderless effect ). Most of the work is being done by the distance field generator ( which basically "abuses" bilinear filtering ).

K

Posted: Sat Jul 09, 2011 10:22 am
by VilleK
For those looking at Kjells example, notice how low resolution that bitmap really is by setting Bitmap.Filter to Nearest.

Even though I've read the paper and examined your implementation I still don't understand why this is working. When the texture is rendered the alpha values through bilinear filtering extrapolates towards the higher resolution image that is the source of the alpha?

Posted: Sat Jul 09, 2011 10:48 am
by Kjell
@Ville

Bilinear filtering uses the nearest pixels to determine the interpolated value, so if you calculate / abuse those nearest values to give you the desired value ( stroke angle / gradient determined by analyzing the high resolution source ) as a result of this calculation, you get the results that you're getting* It's quite clever :)

*Classic case of knowing the desired result + knowing the calculation .. just need to feed it the correct input.

K

Cool!

Posted: Sat Jul 09, 2011 6:23 pm
by jph_wacheski
Yes, this is rather interesting,. it is a strange method to work with, but the results are looking quite good.

Some searching points to using the Distance Fields for mesh generation.., could also be interesting to try that.

I will see if I can get a grip on using this method for text rendering,. as well it could be useful as an interesting rendering method for sprite based game setups..,

Posted: Thu Dec 04, 2014 2:13 pm
by Kjell
:!:

Very neat technique that produces accurate distance fields at much lower resolutions using anti-aliased input ( instead of binary ).

http://webstaff.itn.liu.se/~stegu/aadis ... eprint.pdf

Still wouldn't recommend generating them in real-time, but it does speed up the process quite a bit ( when using a significantly smaller image ).

K

Posted: Sat Apr 18, 2015 11:12 am
by Rado1
Hi Kjell, because I want to produce some nice looking fonts and other textures for my projects, I returned to this interesting topic with a couple of questions: How did you produce the final bitmap for your Outrun.zgeproj demo? What tools and settings you used? I think SDFont supports just square png images, what's the best way to produce non-square images, are there some pitfalls? Tanks in advance for sharing your know-how.

In my trial produced a distance map from hi-res font bitmap, downscaling it to 25% of original size and replaced RGB with 255; alpha channel remained the same as in distance map. Problem was that after importing the png file to ZGE, pixels were not white, but there was applied some automatic antialiasing... so I was not able to reproduce your result without usage BitmapExpression for "post-processing".

P.S. I maybe could read the papers and try to reproduce your result by myself, but I think it is more effective to learn from somebody with know-how and experience like you.

Posted: Sat Apr 18, 2015 2:36 pm
by Kjell
Hi Rado1,
Rado1 wrote:How did you produce the final bitmap for your Outrun.zgeproj demo? What tools and settings you used?
I actually used Photoshop, which works well enough for 1D distance fields ( 2D is a little tricky though ). You can find the required steps here.

In case you have any further questions, let me know.

K

Posted: Sun Apr 19, 2015 8:55 am
by Rado1
Thanks Kjell. However, I have the final question: how did you achieve that importing a png file to ZGE did not change RGB colors of pixels according to Alpha? See the attached project and bitmap I used. BTW if you enable disabled BitmapExpression the result is correct; but I would like to avoid it.

Posted: Sun Apr 19, 2015 10:54 am
by Kjell
Hi Rado1,
Rado1 wrote:How did you achieve that importing a png file to ZGE did not change RGB colors of pixels according to Alpha?
Import as 32-bit BMP instead. By default PNG uses premultiplied color channels, which is not what you want.

K

Posted: Sun Apr 19, 2015 1:23 pm
by Rado1
Kjell wrote:Import as 32-bit BMP instead. By default PNG uses premultiplied color channels, which is not what you want.
This is the trick I wanted, thanks Kjell!

Posted: Sun Apr 19, 2015 6:42 pm
by Rado1
Kjell, do you have any idea how to make it working also on Android? The current version fails with "failed to load: opengl32". I think glEnable(GL_ALPHA_TEST) is not supported. If possible, I would like to avoid shaders and build application in Compatible GLBase.