Sharp Lines with Distance Fields

 

CREDITS

2D Characters in 3D Worlds - JayTheDevGuy

Glyphs, shapes, fonts, signed distance fields - Martin Donald

This guide is built off information gained from these two videos, packaged into a guide specific to Unreal Engine.

 

Terminology

SDF - Shorthand for Signed Distance Field

 

Software
  • Unreal Engine (I'm using 5.3 for this guide, but as long as the SmoothStep node exists in the material editor, any version should work)
  • Image Editor (I'm using Photoshop CS5, though any image editor should work)
  • Material Maker (A pay what you want material generation tool)

  • SDFGenerator.PTEX (A save file for Material Maker with the setup to make a SDF already created)

 

Useful Tips
  • When creating a signed distance field the input texture should be large (i use 4096x4096) then scaled down bicubicly after the SDF is generated

  • IMPORTANT - Setting your imported SDF's compression settings in Unreal's texture window to Grayscale and the texture sampler node to Linear Grayscale will yield the best results.

 

Guide

First off you need some art that you want the smooth outlines on. The tricky part is you need seperate outlines to your colours. This art should be high resolution so it can be scaled down. (even better if it's in vector format)

 

When you export the art, export the colours at the desired ingame resolution (128-512 recommended, the smaller the better) and the lines, we will do some extra processing to to generate the SDF.

 

The image below shows the coloured part of my circle exported with transparency at 256x256 resolution.

A png of a red circle used as my colour portion of the image, Exported at 256x256 pixels

Now onto the lines, these require a little extra work in order to create a SDF. First off, the image should be grayscale, with the lines being white and the background being gray. This should be exported in the highest resolution possible. The image below shows my circle's outline converted to white, against a black background.

Now we have our two images, we can use the grayscale mask we just made to create a SDF. Using a template from Martin Donald's video I have saved a template for Material Maker which you can use to create your SDF texture.

 

First, open the SDFGenerator file in Material Maker. You should see a node layout like this. 

If you click on the purple and blue drip icon on the node labled Image, you will get a file browser thatw ill allow you to chose the grayscale image you created for your SDF. It should look something like this when done. 

Once you have done this, you need to change the resolution of both Dilate nodes to match your input resolution. If your image is 4096x4096 then you can skip this step. 

 

Now, if you click on the Math node you should see the preview in the bottom left look more like a SDF. It should look like a feathered representation of the image you put in. 

Now you can export the generated SDF by right clicking the preview, selecting export, then the size you want the SDF to be at. I'd recommend 128x128, but you can certainly go lower.

We are now ready to start importing our textures into Unreal Engine. Drag the colour and SDF png file into the Unreal Engine content browser at a location of your choice. 

Before we get into materials, we need to adjust some texture settings on our SDF texture. Double click on the SDF texture to bring up the Texture settings panel. 

 

The two settings we need to change are:

  1. Compression Settings - Grayscale
  2. sRGB - Unchecked

 

This sets up the texture to be used as a grayscale mask. If you wanted to, you could even bake this texture inside of another map such as the alpha channel on a normal map. 

Now our textures are setup correctly, we can move onto the material. This material is recreated from a snipped of JayTheDevGuy's Video and I will explain what each part of the material does so you can recreate it yourself. 

This material will now give you the sharp outlines you need. Below will be a node by node explanation of the material.

 

  1. TexCoord[0] - Gets the UV layout (texture coordinates) of channel 0 on the mesh. Unless you have custom UVs in different channels, this can be left alone.
  2. DiffuseTexture - A Texture Sampler that references the colour texture you imported in the previous steps. The sampler type for this image should be "Colour"
  3. OutlineColour - a Vector 3 That allows you to set the colour used in your outline texture. As the texture uses white, we can use this colour to set any colour we want for the outlines.
  4. OutlinesTexture - A Texture Sampler that references the SDF texture we created. IMPORTANT! The sampler type for this image should be "Linear Grayscale"
  5. SmoothStep - This node is the "Magic" of the SDF technique. Without going into too much detail, it is the function that creates the outlines we are looking for. The difference between the min and max values will determine how thich the lines are, but for most cased Min = 0.499 and Max 0.5 will suffice, though you can adjust these to your liking.
  6. Multiply - This is taking the white lines created by the smoothstep SDF and colouring them based on the OutlineColour parameter.
  7. Lerp - This is blending the colours and SDF based on the output of the SDF calculation.
  8. Add - This is creating an alpha mask combining the SDF and the alpha of the colour image. This is why we used a texture with an alpha channel. (PNG or TGA)
  9. PBR properties. These are set to give the material a flat look. Most 2d sprites don't need PBR information so in order to give a consistant look, we set Metalic, Specular and Anisotropy to 0 and Roughness to 1. These can be changed to match your art style. 
  10. Blend Mode - IMPORTANT! This should be set to masked to ensure that the outer edges of the image are smooth. If you know what you're doing, you can get away with transparent, but generally this should stay as masked. 

 

With all that, you have a material and texture set to achieve the desired smoothed edges look no matter how close to the camera your image gets. This material can now be applied to your geometry, such as planes sprites. 

 

If you have any issues or suggestions feel free to reach out to me on Twitter @Classyham.

 

Below is a comparison of a 128x128 material with and without the SDF material.