Skip to main content
GameDev.net gamedev.net
🔒 Locked

2D Distance Field computation

Started by Deliverance May 6, 2010 at 7:26 AM 3 replies 2.7k views
Original Post
Deliverance
Deliverance
I was reading Valve's paper and was wondering how one has to compute a distance field such that you would alpha test with a value of 0.5? In my implementation i have to use values like 0.97 to have decent results. [Edited by - Deliverance on May 6, 2010 7:48:12 AM]
Ashaman73
Ashaman73
The assumption is, that you have an alpha map with just 0 and 1 values.
When you process a pixel, you have to get the closest texel with the inverse value up to a max distance M.
The normalized distance to this pixel is d = d/M ( a value between 0..1).
Now you have to take the pixel value of 0 and 1 into account. 0 is not visible, 1 is visible. Here's some pseudo code
for each pixel p do  alpha = pixel.a    // get closest distance to pixel with other value  d = closest distance to pixel with value (1-alpha)    // normalize and clamp to 0..1  d = min( 1.0f , (d / MAX_DISTANCE));  // final calculation  if(alpha==0)  {    final_d = (1.0-d)*0.5;  } else {    final_d = d * 0.5 + 0.5;  }end


Hodgman
Hodgman
Quote:
Original post by Deliverance
I was reading Valve's paper and was wondering how one has to compute a distance field such that you would alpha test with a value of 0.5? In my implementation i have to use values like 0.97 to have decent results.
How are you currently generating your field?

I used an algorithm simmilar to Ashaman73's, where you start with a binary (0/1) alpha map.
maxDist = 0for each pixel p do  alpha = pixel.a    // get closest distance to pixel with other value  d = BIG_NUMBER  for each pixel o do    if o.alpha != alpha      d = min( d, distance(p,o) )  //the above can be *greatly* optimised    maxDist = max( maxDist, d );  if(alpha==0)    d = -d;  p.final_d = dendfor each pixel p do  p.final_d = p.final_d / maxDist;// normalise to -1 to +1 range  p.final_d = (p.final_d*0.5+0.5)*255//encode into 8 bit
After this, you've got a high-res distance field, which you can resize down to a low-res texture using a box-filter etc.

There's also an article here on an easy way to make them in Photoshop instead of writing a tool.
Deliverance
Deliverance
Thanks guys! I was doing it similar to Hodgman but didn't account for negative distances.... Now it's working as expected!

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.