Udemy
    •  
    •  
    •  
    •  
    •  
    •  
    •  
    •  
Turn what you know into an opportunity and reach millions around the world.
Learn More
Your cart is empty.
Keep shopping
Three.js Shading Language and Signed Distance Fields
Rating: 4.7 out of 5(23 ratings)
240 students

Three.js Shading Language and Signed Distance Fields

Learn all about the Three.js Shading Language while specialising in Signed Distance Fields.
Created bySean Bradley
Last updated 9/2025
English

What you'll learn

  • Threejs Shading Language
  • Signed Distance Fields
  • Using TSL with import maps or a build tool
  • Setting up a development environment
  • TSL imports or color, texture, convertColorSpace and positionLocal
  • Writing Fragment and Vertex Shaders
  • Generate patterns using fract, sin, cos, atan, floor, mod
  • Drawing SDF lines and shapes in 2D and 3D
  • Using Uniform and UniformArray
  • Drawing distance lines
  • Colouring 2D and 3D SDFs
  • Raymarching
  • Lighting 3D SDFs
  • SDF Shadows
  • SDF Reflections
  • SDF Union, Intersect and Subtraction
  • Ambient Occlusion
  • Fresnel Effect
  • Adaptive DPR
  • Atmospheric Scattering
  • Fractal Brownian Motion
  • Gerstner/Tricoidal water algorithm
  • Adding Clouds
  • Domain Repetition
  • Mandelbulb, Juliabulb & Kleinian Inversion Fractals
  • and much more

Course content

1 section30 lectures5h 42m total length
  • Getting Started8:48

    What is TSL

    - TSL (Three Shader Language) is a high-level shader abstraction in Three.js.

    - It helps write shaders in a structured, readable way instead of writing raw GLSL or WGSL.

    - We write it directly in our JavaScript / TypeScript files.

    - It is best suited for when you want to write customised vertex, fragment and/or compute shaders.


    In the video, we discuss,

    - using import maps,

    - using a build tool,

    - downloading a boilerplate,

    - setting up a development environment,

    - and see a working version of TSL running from our own computer.


  • What Do We Have9:42

    In this lesson, we discuss

    - renderer.debug.getShaderAsync()

    - TSL named imports of color, texture, convertColorSpace and positionLocal


    We have a basic TSL scene, we look at the generated shader code, and then change from seeing a color, to downloading a texture, to then using positionLocal to see the UV coordinates as colours.

  • PositionLocal13:13

    In this lesson, we also introduce the TSL named imports of Fn, toVar, If, abs, rotateUV, time, vec2 and vec3.


    You will find in almost all fragment shaders, the use of some kind of positional coordinates. The positional coordinates are interpolated from left and right, up and down as each pixel colour is calculated.

    In TSL, we can use `positionLocal` to get the fragment shaders current positional coordinate.

    import { positionLocal } from 'three/tsl'

    This value essentially comes from the `BufferGeometry.attributes.position`.

    So, depending where we are on the scan, the coordinate will be a different value, and we can use that to output a different color.

    On a 2D plane, the coordinates will behave like X, Y coordinates on a graph.

  • Some Patterns16:36

    In this lesson, we also introduce the TSL named imports of length, sin, cos, atan, fract.


    We will use some mathematics to draw some pretty patterns.

    You will see at the end, that variations of only a few methods can produce vastly different results.

    We will begin by using inline functions, and then move onto TSL functions.

  • Lines : Part 111:45

    Now we will use some mathematical methods to draw some lines in Three Shader Language.

    We will start with the circle, and then the radius line.

  • Lines : Part 211:56

    In part 2 of this section, we complete the sine and cosine waves, and add some dotted reference lines.

  • Uniform and UniformArray13:38

    Uniforms are variables that we can create and use outside of the fragment shader. As each fragment is processed, it will have an identical copy of the value at that time.

    In this lesson, we will create a GUI with several controls that allow us to modify the shader in real time using the TSL named imports of uniform and uniformArray.

  • Signed Distance Fields13:04

    We have been using SDFs several times throughout the course without really knowing much about them.

    In the next few lessons, we will delve much further into SDFs, starting from the basics of using SDFs in 2D scenes and then up to more advanced 3D scenes with camera movement, colouring, shadows and reflections.

    What is an SDF?

    An SDF is a function that takes a 2D or 3D point as input and returns a scalar distance value.

    This distance represents how far the point is from the nearest surface of an object:

    • If the value is positive, the point is outside the object.

    • If the value is zero, the point is on the surface.

    • If the value is negative, the point is inside the object.

  • Distance Lines13:57

    We can take colouring SDF scenes in different directions.

    In this lesson, we will experiment with,

    • creating distance lines using different functions,

    • colouring them,

    • creating some more shapes,

    • more examples of union, subtraction and intersection.

  • Colouring 2D SDFs15:29

    We will now individually colour our SDF shapes, all using some slightly different technique from the other.

  • Practice10:36

    We will practice many of the concepts we've learned so far and create this small interactive demo.

  • Add Interactivity11:22

    We add the keyboard interactivity to this 2D practice section.

    We also use the JEasings library for animating.

  • Raymarching20:26

    We can use Signed Distance Fields (SDF) to define shapes and scenes, but if we want to view our SDF shapes in 3D, then we can use raymarching.

    Raymarching will help us to calculate the distances to SDF shapes in 3D space. We will also be able to calculate the normal in which we can then use to calculate the lighting effects.

    So in this first example, imagine a position in space, this is the camera position, and it is scanning a coordinate in a some direction, and the fragment shader will raymarch along that direction until it hits a surface. We can then use that information to color the returned pixel.

  • Lighting 3D SDFs9:12

    In this lesson we will add,

    • Lambertian Reflectance,

    • Ambient Lighting,

    • Phong Specular Reflection

  • SDF Shadows8:55

    We will implement hard and soft edged shadows.

    After the diffuse has been calculated for a position, we can cast a shadow ray from that position towards the light source.

  • SDF Reflections7:50

    The basics or reflection in SDFs are,

    • When a ray hits an object, instead of stopping, we calculate a reflection ray.

    • We march the new reflected ray, just like the original one.

    • The color of each new reflection is blended into the pixels final color.

  • Adaptive DPR3:57

    On lower end GPUs, the reflections lesson would likely not perform very well.

    Raymarching is an expensive operation if done many times, as is when calculating reflections.

    A compromise, is to lower the renderers device pixel ratio (DPR) setting.

    The DPR, also sometimes may be referred to as DPI, determines how many physical pixels correspond to one logical pixel, which affects rendering quality and performance.

    If screen refresh is important for your application, than you can implement an adaptive DPR approach.

  • Colouring 3D SDFs12:20

    Colouring 3D SDFs can be done very similar to how its done in 2D SDFs, however this is not an optimal approach when you are recalculating the complete SDF scene many times in a raymarching pass. E.g., the SDF scene is recalculated multiple times in any initial, shadow or reflection raymarch. It is also called multiple times when calculating the normal.

    So the SDF scene calculation could be called from few to hundreds of times in any one fragment shader pass.

    So in the case of mixing colours in the SDF scene calculation process each time, as can be done in 2D SDFs, this would be using more resource then necessary.

    Instead, you leave the SDF scene calculation function to still focus on returning the distance float value, but also add an ID indicating which SDF was hit.

    You can use this ID later to choose a colour or pattern only in that part of your code that focuses on the individual colouring.

    The most common and optimised way to solve this problem, is to make the SDF Scene function return a vec2 containing the distance float as usual, and an ID of the SDF shape that was hit in this call.

    In this lesson, we will implement this functionality so that we can present different SDF shapes in different colours and patterns.

  • Atmospheric Scattering11:06

    We will add a background with atmospheric scattering.

    Adding a background is not so complicated unless you are using reflections.

    In this example we will be using reflections, so this creates several more considerations.

    When the background colour is black, additive blending multiplied with a decreasing reflection factor, as we've already done, works ok.

    But if you set the background to a colour other than all 0s, the additive blending will cause the scene to brighten and look washed out.

    We will refactor our code to blend with the generated background using mixing and more.


  • Ambient Occlusion6:20

    We will implement Screen Space Ambient Occlusion (AO).

    This will make areas darker based on the surrounding objects.

    We can use AO independently of shadows.

    Instead of casting a shadow ray, AO checks how much nearby geometry is blocking light.

    It will sample small distances around the object, and if any are blocked, then the position is darkened.

    Areas near the ground, near other objects, or inside corners will appear darker due to AO.

    Surfaces will feel more realistic as occluded regions will receive less light.

  • Fresnel Effect6:47

    The Fresnel effect can be used to mix colours differently depending on the surface normal.

  • Fractal Brownian Motion : Part 112:36

    Fractal Brownian Motion, which also may be sometimes referred to as Fractional Brownian Motion, is a method of modeling objects that appear more natural.

    It takes an input, such as a position, and it iterates over the value, applying a frequency and amplitude at each iteration, or layer, or octave.

    By modifying the values used in the inputs, outputs, frequencies, amplitudes at each octave you can produce all kinds of combinations of shapes that contain some gradually changing repetition that can give the impression of something you may find in nature.

  • Fractal Brownian Motion : Part 212:15

    This is part 2 of the Fractal Brownian Motion lesson where we add colours to the mountains, ambient occlusion, shadows and the ability to fly around.

  • Refactoring18:12

    The code as it is now is quite large. It is all in one file, it's quite hard to modify, navigate and conceptualise.

    In this lesson, we will take the code we have and refactor it into ES6 imports containing combinations of classes and static functions.

    The final code should be easier to work with in case we want to adapt each individual component easier.

  • Adding Water16:55

    We will add a water layer. We could use the FBM algorithm to create a water effect, but we will use a faster algorithm called a Gerstner wave, also known as a trochoidal wave.

  • Clouds11:36

    We can create some clouds in our scene.

    We will base it on the land FBM, so that the clouds appear above the mountain peaks.

  • Domain Repetition11:27

    We can get a shape and repeat it infinitely in all directions.

    In this section we will repeat a shape,

    • in all or some of the X, Y, Z directions

    • limit the boundaries of the X, Y, Z directions

    • change and animate the sizes of each repeated shape

    • change and animate the positions of each repeated shape

    • and more

  • Mandelbulb9:09

    We will practice concepts that we've already scene, but use a fractal algorithm known as the Mandelbulb.

  • Juliabulb3:42

    We will practice concepts that we've already scene, but use a fractal algorithm known as the Juliabulb.

  • Kleinian Inversion Fractal9:37

    Also known as a Kleinian/Apollonian fractal.

    These fractals are generated by repeatedly reflecting spheres inside other spheres to produce intricate nested spherical patterns.

    • Kleinian : A distance-estimated 3D fractal made from repeated inversions in spheres (and sometimes planes).

    • Apollonian : Refers to Apollonius of Perga (ancient Greek mathematician) and typically means a construction where circles (or spheres in 3D) are packed so that every gap is filled with more circles/spheres.

Requirements

  • This is an intermediate course about Three.js and you should already have some experience using it.
  • You will need a modern graphics card capable of running GLSL and WGSL shader code.

Description

Three.js Shading Language (TSL) is a framework built to simplify shader development within the Three.js ecosystem.

Signed Distance Fields are a way to draw scenes and animations predominantly using mathematical functions.

You can draw anything with Signed Distance Fields, and TSL makes that more accessible for developers, especially those without deep knowledge of low-level GLSL, WGSL or graphics programming.

So, in the course, we will cover,

  • Basic environment development setup,

  • Importing the required libraries,

  • Using import Maps or a bundler / build tool,

  • Discuss the prerequisites of a TSL scene,

  • Fragment Shader coordinates,

  • Create several animated patterns from easy to more advanced,

  • Draw various styles of lines,

  • Implement uniforms and uniform array,

  • Interact with our scenes using a GUI,

  • Learn the basics of sign distance Fields,

  • Draw distance lines using SDF information,

  • Colouring and animating 2D SDFs,

  • Practice by building something and adding keyboard interactivity,

  • Learn the basics of Ray marching,

  • Lighting 3D SDFs,

  • Using Lambertian, Ambient and Phong specular,

  • Using hard and soft shadowing,

  • Implement SDF reflections,

  • Implement adaptive device pixel ratio,

  • Colouring and animating 3D SDFs,

  • Add atmospheric Scattering,

  • Implement, Ambient Occlusion,

  • And apply Fresnel Effect,

  • Learn all about Fractal Brownian Motion,

  • Add Gerstner/Trochoidal algorithm water effect,

  • Add Clouds,

  • Domain Repetition,

  • Mandelbulb, Juliabulb & Kleinian Inversion fractals,

  • and much more

By using TSL's node-based shader graph system, developers can create and manage shaders without needing to write complex GLSL or WGSL code manually.

TSL is renderer-agnostic, meaning shaders created with it work seamlessly across different rendering backends like WebGL and WebGPU.

Since TSL is written at the Javascript or TypeScript layer, along side your existing Three.js code, you will be able to benefit from the features provided by your IDE, such as IntelliSense code completion, code formatting and linting. Your final production code can also benefit from tree shaking provided by your bundler.

Thanks for taking part in my Three.js Shading Language (TSL) and Signed Distance Fields course.

Sean

Who this course is for:

  • People who have experience with Threejs and want to write shader code using the techniques of signed distance fields.