1. All Unity Pro perpetual license customers: your special offer to subscribe is ready! Click here.
  2. We're running a survey about the usage of our graphics pipeline, help give us your feedback.
  3. Unity 5.6 beta is now available for download.
  4. Unity 5.5 is now released.
  5. Check out all the fixes for 5.5 in patch releases 1 & 2.
  6. Enter the Google Play Indie Games Contest in Europe. Read more about it here.
  7. Get prepared for the Tizen Mobile App Incentive Program! Read more about the upcoming program here.
  8. Enter the Microsoft Developer Challenge for a chance to win prizes. Read more about it here.

SDF Toolkit - Now Released

Discussion in 'Works In Progress' started by Jasper-Flick, Mar 26, 2015.

  1. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Messages:
    744
    The SDF Toolkit public beta phase has ended. It is available in the asset store!

    I'm working on a set of shaders for SDF materials. They function like Unity 5's standard shaders, except they generate shapes from a singed distance field. Here's an example.

    sdf-warning.jpg

    The shaders can cast both solid and semitransparent shadows. Semitransparent shadows use Unity's dithering approach. You can turn this off manually, in which case you're left with solid shadows that work with an alpha threshold.

    sdf-semitransparent.jpg

    There is also a cutout mode, which allows the materials to receive dynamic shadows and work with the deferred shading pipeline. The downside is that you'll get a hard cut at the alpha threshold, which means aliasing. The below image used FXAA to get some smoothing.

    sdf-shadowed-fxaa.jpg

    You don't need to use cutout mode to be lightmapped, so you can get both smooth edges and soft baked shadows.

    sdf-lightmapped.jpg

    The shaders also work with dynamic global illumination. You can choose whether the effect is off, dynamic, or baked.

    sdf-gi.jpg

    Check out the webplayer demo!
     
    Last edited: Nov 20, 2015
  2. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Messages:
    744
    Join the public beta!

    A problem with textures is that they have a fixed resolution and will appear blocky when you get too close. And too far away it degrades into an aliased mess, unless we use mipmaps.

    bad.jpg

    Here's the same image, but now using an SDF texture (the same size) and shader.

    good.jpg

    This is the original texture.

    sdf-512.png

    And this is its signed distance field (SDF), which is a measure of distance from the contour. It's originally an alpha-only texture, converted to grayscale to make it visible. The original contour sits at half opacity. The transitions both inside and outside of the shape are configurable.

    sdf-512 SDF.png

    The SDF shader evaluates this texture to determine whether a pixel lies inside or outside the shape. This approach degrades much better when zooming in. Unfortunately procedural shaders are prone to aliasing when zooming out, because they don't have mipmaps. The SDF texture can use mipmaps, which makes it not that bad but still not very good. Fortunately, adaptive smoothing and texture supersampling can greatly increase the quality.
     
    Last edited: Apr 28, 2015
    rakkarage likes this.
  3. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Messages:
    744
    How to create an SDF texture? The brute-force method is to create a very-high resolution contour texture, compute local distances per pixel for that and downsample. Stefan Gustavson and Robin Strand developed a better method, which directly converts a low-resolution anti-aliased contour texture into an SDF texture of the same resolution. This is so fast it might be feasible to do it realtime for small textures, if the algorithm is properly optimized. I have had a Unity editor tool available for years already that uses their approach. It's been available under the GNU GPL, but for this project I've improved it and it'll become available for a better license.

    What can you use it for? It's typically used for text rendering using bitmap fonts. I myself use it with my Text Box product. You can also use it for any kind of iconography or labels. You could also use it to cut holes into geometry.

    Besides simply reproducing the contour, you can add additional effects like outlines and bevels. As these effects are controlled with shader properties they can be animated as well.

    Are you interested? Let me know!

    I plan to put my improved SDF generator tool on the asset store for free. I'll also bundle it with my SDF shaders and put that on the store for a modest fee, as well as include them with Text Box. I want to make the shaders free for a while too, as a public alpha/beta so you can try and test them.
     
    Last edited: Mar 26, 2015
  4. imaginaryhuman

    imaginaryhuman

    Joined:
    Mar 21, 2010
    Messages:
    5,144
    Its cool. I thought when I looked into signed distance fields, there was a piece of graphics software which let you draw vector shapes etc in realtime which was using this/had developed this technology, and had patented it, meaning it wasn't possible to use this method. .... maybe I was wrong... when I google these I get numerous hits so it seems others are using this method already. You might want to check that. ..... but I like the result.

    Something like http://ieeexplore.ieee.org/xpl/logi...re.ieee.org/xpls/abs_all.jsp?arnumber=4547967 .... adaptive signed distance fields... but maybe this is just a variation?
     
  5. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Messages:
    744
    @imaginaryhuman The concept of signed distance fields isn't patented. Maybe a specific realtime vector drawing system is patented, but that's of no concern here.

    Your link is about a completely different application of distance fields.
     
    Last edited: Mar 26, 2015
  6. rocki

    rocki

    Joined:
    Aug 10, 2012
    Messages:
    1,256
    I'm definitely interested.
     
  7. auntiejrg

    auntiejrg

    Joined:
    Mar 26, 2015
    Messages:
    6
    looks cool!
     
  8. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Messages:
    744
    The standard shaders have four different rendering modes. Opaque, Cutout, Fade, and Transparent. My SDF shaders don't have the Opaque mode, but do support the other three modes. The difference between Fade and Transparent is that the latter is for realistic semitransparent materials like glass, while the former is for unrealistic fading.

    Fade mode is best for opaque contours. The fading is responsible for the smooth edges. Light reflections will fade out as well, but this is exactly what you want. However, it becomes troublesome when you want correctly lit semitransparent shapes. The shape in the image below has a completely transparent interior and a semitransparent outline. It might look fine, except that the specular on the outline is far too weak and the "glass" interior has no reflections at all.

    fade.jpg

    In contrast, the next image uses the Transparent rendering mode. Light now correctly bounces off the transparent surfaces.

    transparent.jpg

    It actually requires some trickery to make this work, because you'd only want the light to reflect from the surface inside the contour, not from the outside. At least, that is my assumption. So I'm eliminating the lighting beyond the outer contour, otherwise it would end up like in the following image.

    transparent-wrong.jpg
     
    Last edited: Mar 27, 2015
  9. Evil-Tak

    Evil-Tak

    Joined:
    Feb 4, 2014
    Messages:
    48
    I'm particularly interested in knowing how you achieved those awesome looking semi-transparent shadows ;)
     
  10. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Messages:
    744
    @Evil Tak I use the same approach that Unity is using, which is clipping the shadow caster using a dither pattern. This looks very bad with hard shadows, but when blurred with soft shadows it starts to look a lot better, at least from a distance.

    hard.jpg soft.jpg

    Unfortunately this technique suffers especially from temporal aliasing, to the point that it becomes unusable. That's why I made semitransparent shadows optional. When not using them, you get alpha-clipped shadows on a custom threshold. So that's all-or-nothing shadows, but they still work with mixtures of opaque and (semi)transparent materials.
     
  11. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Messages:
    744
    A problem is that the lightmapping and GI system cannot deal with backfaces. If you just use a single quad you'll find that objects close behind it will get solid black lightmaps as their lighting data is considered unusable. The solution is to add a mirrored duplicate of the quad that's facing the other direction. This is also one reason why I only support the default backface-culling mode. If you need two-sided rendering, use duplicate geometry. I avoids a lot of headaches.

    After solving that, global illumination and lightmapping still took some experimenting to get right. Lightmapping doesn't work with semitransparent objects. This means that the mostly transparent quad that I've shown in all the images so far blocks way too much light. You either have to make a better fitting mesh, or create a lightmap parameters asset and set it to transparent so it doesn't block any light at all, but still receives it.

    Marking objects as transparent for lightmapping is definitely handy, but then there's the problem that they will emit light from their entire surface via global illumination, which makes their contribution far too strong. I solved this by multiplying the final albedo and emission values with opacity, basically using premultiplied alpha colors. Here's an example of completely white text of which the outline emits red light.

    shaded.jpg

    And here are the GI albedo and emissive maps, with way too high resolution to show the details.

    albedo.jpg emissive.jpg
     
  12. imaginaryhuman

    imaginaryhuman

    Joined:
    Mar 21, 2010
    Messages:
    5,144
    In terms of antialiasing, when an image is in perspective, like the text you showed earlier, since it's based on textures, with telex enlargement showing when nearer the camera, does that mean that parts closer to the camera will have a `thicker` band of blur/antialiasing on the edges, compared to parts which are further away? I can't tell from your image because it seems both ends of the text are about the same fuzziness. i.e. is there always a 1 pixel antialiasing border or does that get thicker as the camera gets closer?
     
  13. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Messages:
    744
    @imaginaryhuman You actually can tell, because what you observed is exactly what's happening. :)

    There are three smoothing modes. Auto, manual, and mixed. The auto mode is what you see in the screenshots. It gives you that one-pixel smoothing. This is done with derivative instructions, so it's target 3.0.

    The other option is manual smoothing, which has you set a smoothing range that's constant no matter the view angle or distance, which is what you initially described. This doesn't give you constant antialiasing, but you can make blurry edges with it and it works with shader model 2.0.

    The mixed mode combines both approaches. It's useful when you want both antialiasing and fuzzy borders.

    Then there's supersampling, which also targets 3.0. It's more expensive, but greatly increases visual quality at small scales and extreme angles, and reduces temporal aliasing. You'd typically combine it with auto smoothing.
     
    Last edited: Apr 8, 2015
  14. imaginaryhuman

    imaginaryhuman

    Joined:
    Mar 21, 2010
    Messages:
    5,144
    The derivative instructions, like 'ddx ddy'.. aren't supported in cg are they? Do you write in glsl or something?
     
  15. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Messages:
    744
    You don't need to write glsl yourself, but you need to add #pragma glsl to have Unity compile to GLSL instead of to ARB_vertex/fragment_program format for OpenGL. At least, that's the case for Unity 4. Unity 5 no longer uses ARB_vertex/fragment_programs, so you can forget about the pragma.
     
  16. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Messages:
    744
    It's time to show something realtime! I made a demo scene that you can check out here.

    sdf-demo.jpg

    It's a webplayer build. I tried webgl too, but it's a huge download and PBS and GI don't work right. That's for Unity in general, the SDF shaders function properly.

    I used linear color space, and found that this doesn't work for me in Safari, when windowed. But it does look fine when going fullscreen, or when using Chrome or Firefox. I added a gamma color space build as well in case linear won't work for you at all.
     
  17. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Messages:
    744
    I've been working on the documentation for what I now call the SDF Toolkit. What I have so far is already online.

    02-normals.jpg

    I want to make a couple of tweaks to the toolkit and the docs, and then it's getting time for public beta.
     
  18. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Messages:
    744
    I put a video online showcasing how to use the toolkit. Have a look!



    Seems like YouTube chokes on it sometimes, at least for me. After a few reloads it does play, for some reason.
     
    Last edited: Apr 16, 2015
    Arkade likes this.
  19. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Messages:
    744
    You can now get the public beta from the asset store!

    SDF Toolkit public beta

    Please report anything weird, especially for Windows platforms as I'm developing it on a Mac.
     
  20. Zapgun

    Zapgun

    Joined:
    Jun 3, 2011
    Messages:
    37
    An interesting project - I could see myself using this in a few different ways. Can I ask about performance.. and is this strictly a desktop thing, or could this be used on mobile?

    Cheers and thanks,

    Zap
     
  21. imaginaryhuman

    imaginaryhuman

    Joined:
    Mar 21, 2010
    Messages:
    5,144
    Looks cool. web player in fullscreen HD looks very nice quality.
     
  22. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Messages:
    744
    @Zapgun Shader performance depends on the chosen complexity. Unlit is fast, while standard shaders aren't really for mobile. Depending on demand, I can add more shader flavors, like cheap lighting for mobiles.
     
  23. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Messages:
    744
    There was a weird issue with materials disappearing when using DX11. With the help of some people - especially @Aras - this has been fixed in version 1.0.1.
     
  24. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Messages:
    744
    Public beta 1.1 is now available! I have added shader variants that work with Unity's UI. There's a new example scene that demonstrates them.

    sdf-ui.jpg

    There is a rather big issue with the UI though. If a graphic is masked, it will use a duplicate of the actual material. The duplicate is cached and doesn't inherit the shader keywords of the original. This means that shaders that depend on shader keywords - like Unity's standard shaders and my SDF shaders - simply don't work. Also, UI graphics won't update themselves to reflect changes you make to the material while editing, which is very annoying.

    I have solved these problems by introducing a UIMaterialLink component. Add it to clipped graphic objects, assign the material, and suddenly everything works as it should.
     
    Last edited: May 15, 2015
  25. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Messages:
    744
    Unity 5.1 added HDR support for the editor color widget. SDF Toolkit version 1.2 takes advantage of that. Besides a cosmetic change, it also eliminates four shader properties per lit shader.

    As Unity 5.0.x doesn't have this feature, emissive colors will be displayed with a vector field in that version. Another reason to upgrade to 5.1!
     
    silentneedle likes this.
  26. recursive

    recursive

    Joined:
    Jul 12, 2012
    Messages:
    72
    I've been looking into SDF for some effects/specialized decal objects, thanks for making this!
     
  27. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Messages:
    744
    The public beta phase has ended. Version 1.0 is now official!

    Unity changed some lighting functions in 5.2 and I updated the shaders to use the new versions so they remain compatible. As a result, the minimum supported version is now 5.2.

    While the SDF Toolkit is no longer free, I will also add a free version to the store. That version will only contain the SDF Texture Generator, not the shaders. This way the generator remains freely accessible to everyone.
     
  28. popMark

    popMark

    Joined:
    Apr 14, 2013
    Messages:
    73
    Hi @Jasper Flick
    The asset looks great, do you know how/if it performs on mobile? and can it do parallax effects?
    For the bevel effect, could you calculate a dilated looking normal map in your generator instead of doing 4 texture lookups, and store that in the RGB of your distance field texture?
     
    Last edited: Dec 8, 2015
  29. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Messages:
    744
    @popMark Performance on mobile depends on shader complexity. The unlit shaders are fine, but the PBS shaders - just like Unity's - are heavy-weights, even when dumbed-down for mobiles. And in general, the more shader features you enable, the worse they'll run.

    I haven't included parallax in the PBS shaders because it doesn't combine well with the contour rendering. It's quite expensive for a subtle effect, which works better for rough surfaces like stone, with lots of variety.

    Technically you could bake a normal map in the RGB channels, but that quadruples the texture size. It also doesn't have any of the flexibility of a distance map, so it doesn't really belong there. If you want a fixed normal map, you can use a separate (compressed) normal map, as usual.
     
  30. popMark

    popMark

    Joined:
    Apr 14, 2013
    Messages:
    73
    Cheers good to know, I'm trying to create this sort of high res extrude effect (with parallax occlusion) given any 2D shape as a texture and I figured distance fields might be a good direction to look in and these shaders look like a good starting point.

    [​IMG]

    Flexibility wise I meant basically calculating the normal derivative by cross sampling as you do in the shader just ahead of time, I reckon it'd be equally flexible as you always cross sample by 2 pixels then scale the result? It's a performance/memory trade off.
     
    Last edited: Dec 9, 2015
  31. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Messages:
    744
    @popMark You cannot cross-sample the normals ahead of time while remaining flexible. This is because you don't know the height values, only the distance values. The distance delta can tell you which direction is outward, but not where you are relative to the original contour. The heights are only available after evaluating the bevel curve in the shader, based on location.

    The Unity parallax effect cannot produce such nice volumetric results as in your image. To get such results from a distance map, you need a more advanced ray-tracing shader. This is doable, but not part of the SDF Toolkit at this time.
     
  32. Hodgson_SDAS

    Hodgson_SDAS

    Joined:
    Apr 30, 2015
    Messages:
    114
    Not sure why, but I can't seem to get smooth edges with a parabola.

    upload_2016-10-25_10-4-33.png
     
  33. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Messages:
    744
    My guess is that's either not an SDF texture, or its resolution is too low.
     
  34. Hodgson_SDAS

    Hodgson_SDAS

    Joined:
    Apr 30, 2015
    Messages:
    114
    Hmm, Yeah I used a 1k image, and used the SDF Generator with your package. Is there a specific way to prepare the images before going through the generator?
     
  35. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Messages:
    744
    The generator requires anti-aliased black & white images. A 1024x1024 texture should be sufficient, unless you get real close. The best settings for inside and outside distance depends on the effect range that you're aiming for. Having said that, the shapes shouldn't be made too thin, otherwise there's no room for the gradient. The best quality is achieved when the shader contours are close to 0.5.

    If you can't get a good result, you can post the source images and I'll take a look.
     
    Hodgson_SDAS likes this.
  36. Hodgson_SDAS

    Hodgson_SDAS

    Joined:
    Apr 30, 2015
    Messages:
    114
    It was just too thin. I was able to get it to work properly after thickening up the shapes.
     
  37. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Messages:
    744
    That's good to hear!
     
  38. jeffweber

    jeffweber

    Joined:
    Dec 17, 2009
    Messages:
    433
    I'm attempting to use your SDF generator with the Unity 5.5 beta. When I click generate, Unity locks up and never comes back.

    Any chance you could test your SDF generator with Unity 5.5 beta?

    -Jeff
     
  39. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Messages:
    744
    Which beta version have you tried it with? I can generate SDF textures fine in 5.5.0b10. The code that checks for the correct texture format has become obsolete due to the new importer functionality, but that shouldn't stop the generator from working. Just use an uncompressed source, as it doesn't adjust on the fly anymore. Have you tried it with the included example contour textures, Star and Warning? Those should work, although they're now compressed when imported.

    Having said that, I just encountered a texture-destroying bug with the new texture importer, so it's not stable yet on Unity's end.
     
  40. jeffweber

    jeffweber

    Joined:
    Dec 17, 2009
    Messages:
    433
    I was on b9 so possibly something fixed it in b10. Will try again once I get latest...
     
  41. jeffweber

    jeffweber

    Joined:
    Dec 17, 2009
    Messages:
    433
    I have a couple question about the free (non-shader) version of SDF Generator.

    I have a simple all white texture. Your tool is very easy to use and I can generate the sdf texture pretty easy.

    What I'm less clear on is the image settings required to optimize the sdf texture's anti aliasing.

    Do the settings matter? If so, what settings matter most?
    Can I use this for Sprites without using any custom shaders?

    Thanks,

    -Jeff
     
  42. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Messages:
    744
    SDF textures should be single-channel, alpha only, and uncompressed. Compression ruins the quality, but the textures don't need to be as large as regular textures.

    You need a specialized shader to take advantage of SDF textures. The standard shaders are not going to cut it.

    Fundamentally, SDF rendering is simple. Pick a threshold. Everything on one side is opaque. Everything on the other side is transparent. But a crude cutoff will get you aliased edges. There are three ways to make those edges smooth, which can be mixed. First, use a fixed smoothing range. Second, use a variable smoothing range, based on screen-space derivatives. Third, use supersampling. And you can pile on additional effects, like outlines and bevels.

    The paid version gives you a collection of shaders that do all these things, and more. You can check the docs too see their features.