Jump to content

  • Log In with Google      Sign In   
  • Create Account


Distance field font artifacts


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
9 replies to this topic

#1 n3Xus   Members   -  Reputation: 700

Like
0Likes
Like

Posted 01 July 2013 - 09:21 AM

Hello,

 

I'm wondering how Valve got their distance field font looking so good. I tried generating my font with other tools, my tool and photoshop but the results are almost never as perfect as they are in Valves paper.

 

So my question is: must you fine tune the alpha threshold and is fattening the font characters "correct" in order to get them to draw nicely?

 

The distance field font texture is 256x128 and every letter is around 20x20 pixels.

 

Here are two images:

- the top one has thinner font with more artiafacts

- the bottom one has fatter font with less artifacts

 

http://i.imgur.com/ACVpfnX.png

http://i.imgur.com/OWmk1Zg.png

 



Sponsor:

#2 C0lumbo   Crossbones+   -  Reputation: 2163

Like
1Likes
Like

Posted 01 July 2013 - 09:31 AM

I think that in Valve's paper http://www.valvesoftware.com/publications/2007/SIGGRAPH2007_AlphaTestedMagnification.pdf they're just using a higher resolution than you. In figure 4 (the image with significant magnification), they're using a 256x256 "No Trespassing" source image, which judging by the layout of the source image in figure 2 would amount to 40-50 pixel height per character.



#3 samoth   Crossbones+   -  Reputation: 4656

Like
3Likes
Like

Posted 01 July 2013 - 09:47 AM

FFS Windows 8... third time I start typing this reply...

 

I think that in Valve's paper http://www.valvesoftware.com/publications/2007/SIGGRAPH2007_AlphaTestedMagnification.pdf they're just using a higher resolution than you. In figure 4 (the image with significant magnification), they're using a 256x256 "No Trespassing" source image, which judging by the layout of the source image in figure 2 would amount to 40-50 pixel height per character.

 

This, exactly. Distance field fonts do not look better by "magic" (though to some extent that is also the case because the distance information interpolates more favorably) but because they contain more information.

 

Instead of a boolean value, every pixel holds 8 bits (or 16 bits) of useful information. This is equivalent to using a texture that is 16 times (256 times) bigger in every dimension!

 

However, if Shannon taught us one thing, that is that information that isn't recorded does not magically appear because you upscale it later. The information must be present in the original dataset, i.e. you must use a larger source image to generate the distance field font.



#4 n3Xus   Members   -  Reputation: 700

Like
0Likes
Like

Posted 01 July 2013 - 11:06 AM

Thanks for the replies, makes sense.



#5 hupsilardee   Members   -  Reputation: 486

Like
1Likes
Like

Posted 02 July 2013 - 07:46 AM

Off topic tip: Instead of an alpha threshold, you could try a steep gradient outside the threshold, which will give nice antialiasing :)



#6 n3Xus   Members   -  Reputation: 700

Like
0Likes
Like

Posted 03 July 2013 - 01:30 AM

Yup done that, looks very nice :D



#7 belfegor   Crossbones+   -  Reputation: 2517

Like
0Likes
Like

Posted 07 July 2013 - 03:31 AM

Off topic tip: Instead of an alpha threshold, you could try a steep gradient outside the threshold, which will give nice antialiasing smile.png

 

Could you possibly give some more detail how this work? How to make "steep gradient" to blend between DF and base font texture?



#8 unbird   Crossbones+   -  Reputation: 4973

Like
1Likes
Like

Posted 07 July 2013 - 06:13 AM

It's in that valve paper as well, the paragraph about antialiasing. The corresponding code is the one in the SOFT_EDGES if-clause, basically a smoothstep using the distance value and some range. Alternatively - also mentioned in the paragraph - on SM 3.0 one can use hardware gradients (ddx, ddy) so one wouldn't need to adjust the range for different sizes (viewing distances).



#9 belfegor   Crossbones+   -  Reputation: 2517

Like
0Likes
Like

Posted 07 July 2013 - 07:00 AM

Thanks, but i need more help to understand this?

1. This Valve article is only valid for alpha tested "objects"?

2.

alpha = smoothstep( edge_min, edge_max, alphaDF );

In what ranges these first two parameters should be in context of rendering 2d fonts?

3. I don't understand ddx/y function, what parameters is it expecting and how should i replace smoothstep with them?

 

Thank you for your time and understanding.



#10 unbird   Crossbones+   -  Reputation: 4973

Like
4Likes
Like

Posted 07 July 2013 - 08:37 AM

*Digging up my distance field shader*

You're welcome.

1. This Valve article is only valid for alpha tested "objects"?

I don't think so. If you enable alpha blending that shader should work without any change. You can of course combine it with alpha testing (e.g. for performance).

In what ranges these first two parameters should be in context of rendering 2d fonts?

Depends on how big the decal (or whatever) appears on your render target and how you created the distance field in the first place.

In short: Let's play with it: Here's a distance you can use

61817e264354770.gif

(Click on the images, there's scaled up/down. I deliberately don't use the forum's gallery functionality: the images get sometimes screwed - or disappear. Imagebam keeps them for ages).

Here's a minimalpixel shader I just came up with for illustration:

float4 PS(in float2 texCoord: TEXCOORD0, in float4 diffuse: COLOR0) : COLOR0
{
    float dist = tex2D(DiffuseSampler, texCoord).r;
    float center = 0.46; 
    float transition = 0.01; // in distance field space !    
    diffuse.a *= smoothstep(center - transition, center + transition, dist);    
    return diffuse;
}
Note: I had to play around with the center value. Can't quite remember how I generated the distance field.

This yields:
6980a1264354773.gif

Playing with the transition value (now 0.02)
af9fa0264354776.gif

transition now 0.05
08ca32264354779.gif

3. I don't understand ddx/y function, what parameters is it expecting and how should i replace smoothstep with them?


ddx() gives you the rate of change of any value (not only scalars) from one pixel to the next to the right. ddy is the same for down.

With this information one can achieve a couple of useful stuff but here one can estimate the distance field change in screen space.
Here's a good explanation for this estimation (without the hardware gradients).
This GPU Gems article is also enlighting. (Paragraph 25.5 about Antialiasing).

Don't bother too much, there's a shortcut for the problem at hand : fwidth
    float transition = fwidth(dist) * 1.0;
This yields approx 1 pixel AA independant of how big we render.

3d5c55264354781.gif

Cheers.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS