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

Unlock content 🔓

To get access to 91 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 91 hours of video, a members-only Discord server and future updates, join us for only $95!

Next lesson

Halftone Shading

Difficulty Hard

Introduction 00:00

The halftone is a technique used in printing to create color variations looking like gradients using a grid of points of the same color but of varying size.

Seen from far away, a combination of various halftones results in pleasant shades of colors.

Today, it’s used to create old school vibes and you can appreciate it in modern movies such as Spider‑Man: Into the Spider‑Verse.

Make sure to watch the following images in a high enough resolution to appreciate the effect:

And here is a good example of halftone implementation by @YanSculpts: https://twitter.com/YanSculpts/status/1692251937087832389

In this lesson, we are going to reproduce this effect to add shadow and reflection to our 3D objects:

Setup 02:57

The starter already contains the following:

  • 3 rotating objects: a sphere, Suzanne and a torus knot
  • A basic shader already included in the src/shaders/halftone/ folder with a vertex.glsl and a fragment.glsl
  • Light functions from the previous lessons in the includes/ folder (we won’t be using them just yet)
  • An instance of lil-gui, with two tweaks, that controls the clearColor and the uColor uniform sent to the fragment shader.
  • The vite-plugin-glsl dependency to handle GLSL files
  • OrbitControls to rotate around

Lighting 04:14

Although the halftone idea is to create shading with uniform color, we are actually going to apply it like in Spider‑Man: Into the Spider‑Verse and add it on top of a subtle light shading.

  • The vNormal and the vPosition are already sent from the vertex to the fragment.
  • The viewDirection is already calculated.
  • The normal is already normalized.

We are going to use the ambient light and the directional light.

Include both light sources in fragment.glsl:

#include ../includes/ambientLight.glsl
#include ../includes/directionalLight.glsl

void main()
    // ...

Create a light variable to vec3(0.0) and multiply it by the color:

void main()
    vec3 viewDirection = normalize(vPosition - cameraPosition);
    vec3 normal = normalize(vNormal);
    vec3 color = uColor;

    // Lights
    vec3 light = vec3(0.0);
    color *= light;

    // ...

Add the following ambientLight():

void main()
    // ...

    // Lights
    vec3 light = vec3(0.0);

    light += ambientLight(
        vec3(1.0), // Light color
        1.0        // Light intensity,
    color *= light;

    // ...

We end up with the initial color because we are using a light intensity of 1.0.

Add the following directionalLight():

void main()
    // ...

    light += directionalLight(
        vec3(1.0, 1.0, 1.0), // Light color
        1.0,                 // Light intensity
        normal,              // Normal
        vec3(1.0, 1.0, 0.0), // Light position
        viewDirection,       // View direction
        1.0                  // Specular power

    // ...

The directional light adds a subtle shading to our objects.

Want to learn more?

That's the end of the free part 😔

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

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: