Shortcuts ⌨️

  • SPACE to play / pause
  • ARROW RIGHT or L to go forward
  • ARROW LEFT or J to go backward
  • ARROW UP to increase volume
  • ARROW DOWN to decrease volume
  • F to toggle fullscreen
  • M to toggle mute
  • 0 to 9 to go to the corresponding part of the video
  • SHIFT + , to decrease playback speed
  • SHIFT + . or ; to increase playback speed

⚠️ Update

In the latest versions of Three.js, we need to output the colors in sRGB color space.

To do that, add the following line at the end of the fragment shader.

void main()
    // ...
    #include <colorspace_fragment>

You’ll discover what this #include is later in the course.

Colors might look slightly different from the lesson, but you’ll be able to tweak them.

Unlock content 🔓

To get access to 93 hours of video, a members-only Discord server, subtitles, lesson resources, future updates and much more join us for only $95!

Want to learn more? 🖖


That's the end of the free part 😔

To get access to 93 hours of video, a members-only Discord server and future updates, join us for only $95!

Next lesson

Introduction 00:00

Our scene is looking great with the baked texture, but we are not really using the full potential of WebGL. Let's add more details and give more life to the scene.

First, we are going to add fireflies floating around. Then, we are going to create a cool animation inside the portal. But first, we need to change that black background.

Setup 00:45

The code is exactly the same as we left it in the previous lesson.

We have our scene already imported in Three.js, we can rotate around with the OrbitControls and we have our lil-gui instance ready.

Background color 01:14

For the background, we are not going to make something too fancy. We will simply change the color to something that matches our scene a bit more. To find the perfect color, we are going to add a tweak to lil-gui.

Right before creating our lil-gui instance, add a debugObject:

// Debug
const debugObject = {}
const gui = new GUI({
    width: 400

Like we did in the previous lessons, this object's purpose is only to store the color as a property so that we can add it as a tweak to lil-gui.

After instancing the renderer, add a clearColor property to the debugObject object:

// Clear color
debugObject.clearColor = '#ff0000'

Then add it to the tweaks of lil-gui using gui.addColor(...):

gui.addColor(debugObject, 'clearColor')

You should see the color tweak but we are not using it yet.

Use the value to change the background color with renderer.setClearColor(...):

debugObject.clearColor = '#ff0000'
gui.addColor(debugObject, 'clearColor')

Unfortunately, changing the tweak won't change the color of the background because we are only changing the clearColor property.

We need to call the renderer.setClearColor(...) again when the tweak changes:

    .addColor(debugObject, 'clearColor')
    .onChange(() =>

You can now find the color that matches your scene the best:

debugObject.clearColor = '#201919'

Fireflies 05:16

To create the fireflies, we are going to use particles with a custom geometry.


Start by creating an empty BufferGeometry:

 * Fireflies
// Geometry
const firefliesGeometry = new THREE.BufferGeometry()

Create a BufferAttribute named position to set the position of each particle:

const firefliesGeometry = new THREE.BufferGeometry()
const firefliesCount = 30
const positionArray = new Float32Array(firefliesCount * 3)

for(let i = 0; i < firefliesCount; i++)
    positionArray[i * 3 + 0] = Math.random() * 4
    positionArray[i * 3 + 1] = Math.random() * 4
    positionArray[i * 3 + 2] = Math.random() * 4

firefliesGeometry.setAttribute('position', new THREE.BufferAttribute(positionArray, 3))

The positions of the fireflies are random, but we will improve their positions once we can see the fireflies.

We are going to use a PointsMaterial in order to see our fireflies, but we will change it to a custom ShaderMaterial later:

Create a PointsMaterial with a size of 0.1 and set the sizeAttenuation to true:

// Material
const firefliesMaterial = new THREE.PointsMaterial({ size: 0.1, sizeAttenuation: true })

Finally, create the Points instance using the firefliesGeometry and the firefliesMaterial and add it to the scene:

// Points
const fireflies = new THREE.Points(firefliesGeometry, firefliesMaterial)

You should see some big square particles.

Want to learn more?

That's the end of the free part 😔

To get access to 93 hours of video, a members-only Discord server and future updates, join us for only $95!

Next lesson

What are React and React Three Fiber

How to use it 🤔

  • Download the Starter pack or Final project
  • Unzip it
  • Open your terminal and go to the unzip folder
  • Run npm install to install dependencies
    (if your terminal warns you about vulnerabilities, ignore it)
  • Run npm run dev to launch the local server
    (project should open on your default browser automatically)
  • Start coding
  • The JS is located in src/script.js
  • The HTML is located in src/index.html
  • The CSS is located in src/style.css

If you get stuck and need help, join the members-only Discord server: