Tech Art Chronicles: What Are SDFs Anwyay?
So what in the world is an SDF? SDF stands for Signed Distance Field, but I’m going to ignore the “Signed” for now and let’s talk about what a Distance Field is. A 2D Distance Field is a visual representation of distance between an object and the edge or edge of another object in the same frame.
Take this Circle:
Distance field of that Circle Icon
This distance field indicates wherever it’s pure white (1) it’s right next to the object. And wherever it is pure black (0) It’s the furthest point from the object. So it’s a way to visualize distance between the values of 0 to 1.
I find it useful to think of a Distance Field like a bunch of less opaque circles:
Because you can choose a range in your Shader how much of the Distance Field you want to render so I can choose to render the Max range 1 and the Min range .5
And that would look like this:
But you can also choose to make your Range very tight so something like .5 - .49
New Circle Size after adjusting the Distance Field Max to .5 and Min to .49
Original Circle Size
So you can set this up in the material like this when using a 2D Distance Field texture:
You can see while I can make a circle larger than my original texture image it’s not that inherently useful on something with a perfect circular shape. That’s because my texture is being sampled at various compression and likely a perfect circle won't look great. So instead this distance field technique is often used for icons that aren’t pure circles and for when you want a “glow” around something that’s not a common shape.
Here’s my photoshop file and to add a Distance Field you can add a stroke to your icon like this:
Use the stroke feature and within the stroke set your style to “Shape Burst” And set the position to “Outside” (for now) and voila change the size to whatever fits in frame and now you’ve got yourself a distance field! Easy as that. So when we sub in this new texture and set the Min/Max to 1 - .99 you can see we get our icon in engine:
And you can see if you keep the Max/Min within close lengths you will get a sharp image and if you keep the Max/Min with longer lengths between you’ll have a blurry image. This can be handy if you want to say make a “Glow” around any icon you can actually use a distance field and either bake it into the icon or you can do an R/G texture where your icon is in Red and your Distance Field is in Green. It’s a cheap way to do glow but it does require having the icon textures set up that way.
Here I’m just using that same Distance Field Texture I made from photoshop to make a glow around my icon:
So that ONE texture gets me a glow AND an icon ;) it can even do drop shadows and strokes... but it does require some logic and setup but here’s how powerful that glow can be:
You can animate it via the Sequencer in UMG or you could just bake some kind of glow into the material or even sharpen the glow to make a stroke instead... all are possible with just one texture using a Distance Field on that texture.
BUT WE HAVEN’T EVEN GOTTEN TO SIGNED DISTANCE!? WHAT IS THAT? the S in “SDF”
A “signed” distance is the same thing except you are also calculating the distance INSIDE the object as well. So if we go back to the original circle example:
Signed Distance Field
(except negative values but that’s later)
Now we have both the interior knowledge of the distance and the exterior distance:
Technically SDFs are NEGATIVE for internal mapping so that black should be -1 to 1 see the update below on that topic
ANWAY BACK TO POSITIVE VALUES
So now when I take this back to my photoshop file I can change the stroke type to “Center” instead of outside and that will get me the “Signed Distance Field”
But now your ranges are different. You’ll have to find the right the Max/Min to find your sharp icon. It will take a bit of re-adjusting to get to the right sharpness depending on your icon and stroke distance in photoshop:
My range here is between .2 and .19 to get the sharp image
What can you do with an SDF? Well it makes strokes and morphing and a lot of other things quite easy to do in materials. The easiest thing to do is to “onion” or make an outline of your icon:
This follows IQ’s rule to absolute value then subtract the stroke to get an onion found here. And also you can do some crazy Sine things and make it repeat inside itself:
All of these effects are coming from ONE texture. This is the power of SDFs is you can calculate all kinds of things with distances. It doesn’t have to be math generated SDFs too you can use textures as you can see from my photoshop files. You can even channel pack in the Red/Green channel 2 different icons and morph them together:
Channel pack your icons using the Blending Options and theck the R or G boxes on the icon you want to be in what channel, then of course apply your SDF stroke:
Import into unreal as a TGA - 24bit and here’s a cool morph material:
I hope this helps illustrate a bit of what an SDF is, and also their uses in the 2D texture space. I’m sure I’ll eventually talk about SDFs that are math generated and get more into crazy animations you can make with an SDF such as this drip which was ALL generated using SDFs -- no textures -- and just some math.
BUT that will have to be for next time :D
From the twitter sphere we have an update that SDFs are technically the internal distance is negative so - 1 - 1 Which is a bit more prevlant in the Math SDF generation and I’m not really used to using textures but here’s getting it negative:
Then you can remap the range to be -1 and 1 and you would see something like this. Which is accurate it’s got anything between 0 - 1 black
To change your texture you can run it through a constant bias scale in the material to include the negative values to re-map 0-1 to -1 - 1... granted this wont infact make the interal parts negative but it will remap the range. A two channel packed texture one with the negative values and one with the positive values are a way to do a fully “signed” distance field but that’s a little advanced why you’d need it.
Here’s a handy calculator of the constant bias scale in action:
So to change any values from 0 - 1 to a new range of -1 to 1 you add -.5 and multiply by 2. You can play with this constant bias scale graph here