Skip to content

Getting Started

Video Lecture

Section Video Links
Getting Started Getting Started

What is TSL

  • TSL (Three.js Shading 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.

Importing TSL

The TSL interpreter will convert our TSL code automatically into the equivalent WebGL2 or WebGPU shader code depending on the capabilities of our browser at runtime.

The TSL interpreter requires the three.webgpu.js import, rather then the more common three.module.js.

We can import the required Threejs modules into our project by using import maps or a build tool.

Import Maps

In the case of self hosting threejs, and using import maps, your import map could look like this below, provided that the paths to the files were correct from the perspective of your local web server.

 <script type="importmap">
    {
        "imports": {
            "three": "/build/three.webgpu.js",
            "three/webgpu": "/build/three.webgpu.js",
            "three/tsl": "/build/three.tsl.js",
            "three/addons/": "/jsm/"
        }
    }
</script>

Or if you were using a CDN to download the modules from the internet,

 <script type="importmap">
    {
        "imports": {
            "three": "https://cdn.jsdelivr.net/npm/three@<version>/build/three.webgpu.js",
            "three/webgpu": "https://cdn.jsdelivr.net/npm/three@<version>/build/three.webgpu.js",
            "three/tsl": "https://cdn.jsdelivr.net/npm/three@<version>/build/three.tsl.js",
            "three/addons/": "https://cdn.jsdelivr.net/npm/three@<version>/examples/jsm/"
        }
    }
</script>

Note. In the above import map code, you should replace <version> with a Threejs release number such as 0.173.0.

Build Tool

Or, you can use a build tool / bundler such as Vite or Webpack.

You wouldn't need to use import maps in this case, but you should install the Threejs library and optional types.

Your bundler will link up the required modules automatically and perform extra optimizations such as tree shaking any unused code.

npm install three

# optional but recommended
npm install @types/three

Script Import Statements

And then in your code you would use imports the same, whether or not you were using a bundler or import maps.

For example,

import * as THREE from 'three/webgpu'
import { positionLocal, Fn, time, vec3 } from 'three/tsl'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'

Set Up Our Development Environment

All the working examples on this website will demonstrate TSL using JavaScript with import maps.

You will be able to view the source using the <> button in the view window of any working example.

However, while we learn, we will use a locally installed copy of Threejs and a build tool.

I have a boilerplate already setup that we can use.

The boilerplate is the Threejs Vite and TypeScript boilerplate created from my course https://sbcode.net/threejs/.

Since TSL doesn't yet have any TypeScript declaration information, we can disable type checking at specific parts of the code as necessary.

So, if you don't know TypeScript, or you don't want to use it, it doesn't matter. I won't focus on it much and will show you some work arounds.

But if you do want to use TypeScript, then either way, this course is still useful.

So before you start, you should preferably have these things installed.

Next, find a place on your system where you want to work, and install the boilerplate using these commands.

git clone https://github.com/Sean-Bradley/Three.js-Boilerplate-TS-Vite.git Three-TSL-Course

CD into the Three-TSL-Course folder.

cd Three-TSL-Course

Open VSCode

code .

Open a terminal. CtrlShift'

npm install
npm run dev

Then open a browser at http://localhost:5173/ and you will see a multi coloured wireframe cube.

This is not yet a TSL project, we will update the main.ts code with this start script below. Copy, paste and save it. Then go back into your open browser.

Start Script

./src/main.ts

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import './style.css'
import * as THREE from 'three/webgpu'
import { color } from 'three/tsl'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'

const scene = new THREE.Scene()

const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  10
)
camera.position.z = 1

const renderer = new THREE.WebGPURenderer()
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)
renderer.setAnimationLoop(animate)

window.addEventListener('resize', function () {
  camera.aspect = window.innerWidth / window.innerHeight
  camera.updateProjectionMatrix()
  renderer.setSize(window.innerWidth, window.innerHeight)
})

const controls = new OrbitControls(camera, renderer.domElement)
controls.enableDamping = true

const material = new THREE.NodeMaterial()
material.fragmentNode = color('crimson')

const mesh = new THREE.Mesh(new THREE.PlaneGeometry(), material)
scene.add(mesh)

function animate() {
  controls.update()

  renderer.render(scene, camera)
}

Working Example

<>

Threejs Vite and TypeScript boilerplate

https://sbcode.net/threejs/

Git

Node.js

VSCode