Build a Browser Face Mask

Build a textured 3D mask that tracks your face from your webcam in the browser.

Introduction

30 Second Summary

Camera effects can follow a face so closely that they seem attached to the person. Behind that illusion is a stream of facial points guiding every movement.

In this project, you will build a browser page that places a textured 3D mask over your live webcam feed. You will connect MediaPipe face tracking to Three.js through Threlte before deploying the result for a phone test.

What You'll Build

You will open your deployed page on a phone to see a textured 3D mask stay aligned with your face as you turn your head.

By the end of this project, you'll have:

  • A live webcam view displayed behind an empty 3D canvas in your browser.
  • A moving landmark cloud that follows your face in real time.
  • A deployed textured mask that stays locked to your face during head movements.
  • Secret Mission: An optional challenge to extend your finished face mask.

Are there any prerequisites?

You need a webcam plus basic JavaScript knowledge. You also need Node with npm installed.

Before We Start

Your mask can only react when the browser can read a webcam. A blocked camera or missing runtime would stop the project before the 3D work begins.

This step prepares the toolchain around the build. You will verify Node.js plus npm.

You will also prepare the devices needed for testing. Your publishing method will be ready for the finished page.

In this step, get ready to:
  • Prepare your local development tools.
  • Confirm your webcam plus browser requirements.
  • Prepare an HTTPS deployment method.
Check your webcam and browser

The physical camera supplies every frame that the face tracker analyses. Your browser controls whether the page can receive those frames.

  • Inspect your laptop display for a built-in webcam.
  • Connect an external webcam if your laptop does not have one.
  • Slide open any physical privacy cover over the lens.
  • Close any other application currently using the webcam.
  • Keep the modern browser where you are reading this project available for testing.

Why does the browser need permission?

Browsers expose camera input through getUserMedia() only in a secure context. localhost counts during local development.

A published page needs HTTPS. The browser asks for your permission when the page first requests the camera stream.

No webcam available?

Connect a supported external webcam before continuing. Make sure another application has released the camera.

Ask for help if your laptop cannot detect the device: help me troubleshoot a webcam that my laptop cannot detect

Verify Node.js plus npm

Node.js runs the development tools used to build the page. The Node.js installer includes npm for managing project packages.

  • Open app search by pressing Command-Space bar (macOS) or Windows key + S (Windows).
  • Type Terminal (macOS) or PowerShell (Windows).
  • Select the matching terminal result.
  • Check both tools by running these commands:
node --version
npm --version

What do these checks do?

  • The node --version command prints the installed Node.js version.
  • The npm --version command prints the installed npm version.

✔️ I see two version numbers

Your terminal can reach both tools. You are ready to use the project scripts in the next step.

ⓧ One command is not found

Installing the LTS release gives you Node.js plus npm through one installer.

  • Visit the official Node.js download page.
  • Choose the LTS installer for your operating system.
  • Run the downloaded installer.
  • Keep the default options when the installer prompts you.
  • Close your terminal after the installation finishes.
  • Reopen app search by pressing Command-Space bar (macOS) or Windows key + S (Windows).
  • Open Terminal (macOS) or PowerShell (Windows).
  • Confirm the installation by running these commands:
node --version
npm --version

What does this confirm?

Each command asks one installed tool to report its version. Two version numbers confirm that the installer added both tools to your terminal path.

You should now see two version numbers on separate lines.

Still seeing command not found?

A terminal that stayed open during installation may still use the old path. Close every terminal window before opening a fresh one.

If the command still fails, help me troubleshoot my Node.js installation.

Good work. Your JavaScript runtime plus package manager are ready for the project.

Prepare editing and deployment

A code editor keeps the project files manageable. A static hosting method gives the finished mask a public HTTPS address.

✔️ I already have a code editor

  • Open app search by pressing Command-Space bar (macOS) or Windows key + S (Windows).
  • Type the name of your code editor.
  • Select the matching result.

Your editor is ready when you can see an empty editing window.

ⓧ I need a code editor

Visual Studio Code is a free code editor available for macOS plus Windows.

  • Visit the official Visual Studio Code download page.
  • Download the installer for your operating system.
  • Run the downloaded installer.
  • Keep the default options during installation.
  • Open app search by pressing Command-Space bar (macOS) or Windows key + S (Windows).
  • Type Visual Studio Code.
  • Select the matching result.

You should see an empty Visual Studio Code window.

Editor does not open?

Make sure the installation completed before searching again. Restart your laptop if the installed application does not appear in search.

If the editor still does not start, help me troubleshoot the installation.

This next check touches your login details. Your credentials stay with the hosting service, so do not paste them into this project.

✔️ I have a deployment method

  • Sign in to your existing static hosting service.
  • Confirm your account can start a new static web deployment.
  • Confirm the service publishes sites over HTTPS.

Your publishing path is ready when you can access the signed-in deployment area.

ⓧ I need a deployment method

  • Choose a free static hosting service that publishes over HTTPS.
  • Create an account without entering a payment card.
  • Complete any account verification the service requests.
  • Sign in to confirm the account is ready.

Need help choosing an option? Help me choose a static hosting service.

Before you run the checks again, do you expect both commands to succeed now?

  • Switch back to your terminal.
  • Complete the final toolchain check by running:
node --version
npm --version

What does the final check prove?

The first line confirms that Node.js is available. The second line confirms that npm is available.

You should see two version numbers. That output proves your terminal is ready for the project commands.

Your webcam, browser, toolchain, editor, plus publishing path are ready. Next up, you will create the Threlte project and render its first empty 3D canvas.

Create Your Threlte Project

Your face tracker needs a stable browser page before it can request camera access or place landmarks. This step creates that page as a clean 3D surface.

You will scaffold a minimal SvelteKit app. Then you will connect Threlte to Three.js so the browser can mount an empty 3D canvas.

In this step, get ready to:
  • Create the minimal face-mask project on your Desktop.
  • Install the 3D dependencies.
  • Run an empty 3D canvas in your browser.
Choose a minimal foundation

A minimal scaffold gives you the routing and development tools without adding demo features. This keeps the project focused on the face mask.

  • Switch back to the terminal from earlier.
  • Approve the one-time CLI download if your terminal requests permission.
  • Create the face-mask project on your Desktop by running these commands:
cd ~/Desktop
npx sv create --template minimal --no-types --no-add-ons --install npm face-mask

What does this scaffold create?

  • The first command places the project somewhere easy to find.
  • The minimal template creates a bare SvelteKit application.
  • The --no-types option keeps this project in JavaScript.
  • The --install option uses npm to install the scaffolded dependencies.
  • Confirm the new project folder exists by running:
ls

What does this check show?

The command lists the folders on your Desktop. Finding face-mask confirms the scaffold was created in the expected location.

That is the foundation in place: the face-mask folder now contains a minimal SvelteKit app with its dependencies installed.

Project folder missing?

Check that the terminal completed the scaffold before you ran the folder check. A network interruption can stop the CLI before it creates the project.

If a partial face-mask folder exists, remove that folder before running the scaffold again.

Help me fix the project scaffold.

Connect SvelteKit to Threlte

Threlte needs its core package plus the Three.js rendering engine. Together they provide the canvas that later holds the tracked face mesh.

  • Move into face-mask and install the 3D dependencies by running these commands:
cd face-mask
npm install three @threlte/core

What do these packages provide?

  • The three package provides the WebGL renderer and 3D scene objects.
  • The @threlte/core package exposes those Three.js features as Svelte components.

You should see the installation complete in your terminal. The two packages are now recorded in the project's dependencies.

Dependency installation stopped?

Confirm that your terminal is inside the face-mask folder. The install needs the package.json file created by the scaffold.

A network failure can also interrupt the package download. Run the installation again after your connection recovers.

Help me install the Threlte dependencies.

The Canvas component creates the root renderer for a Threlte scene. A full-screen container gives that renderer visible space in the browser.

  • Use the folder picker in your code editor from earlier to select Desktop/face-mask.
  • Select src/routes/+page.svelte in the editor's file explorer.
  • Replace the file contents with this code:
<script>
  // Create the root renderer for the empty 3D scene.
  import { Canvas } from '@threlte/core'
</script>

<!-- Give the renderer a full browser viewport. -->
<div class="canvas-root">
  <Canvas />
</div>

<style>
  /* Keep the canvas flush with the browser edges. */
  :global(body) {
    margin: 0;
    overflow: hidden;
  }

  .canvas-root {
    width: 100vw;
    height: 100vh;
    background: #0b1020;
  }
</style>

What does this code do?

  • The Canvas component initializes the renderer and a default camera.
  • The canvas-root container gives the renderer the full browser viewport.
  • The global body rule removes the browser's default margin.
  • The dark background makes the empty rendering surface visible before any 3D objects exist.
  • Save src/routes/+page.svelte.
Prove the canvas renders

The development server compiles your Svelte components whenever you save. It stays active in the terminal so the browser can load your local page.

Before you start the server, what should a page with a mounted canvas and no 3D objects look like?

  • Start the development server by running:
npm run dev

What does this command do?

The command starts the Vite development server configured by SvelteKit. It recompiles the page as your project changes.

The process keeps control of this terminal until you stop it. Leave it running for the next steps.

  • Use the address bar in your browser from earlier to navigate to http://localhost:5173.

You should see a dark page filling the browser window. That clean surface confirms the empty Threlte canvas mounted successfully.

Canvas not loading?

Check the terminal for a compilation problem in src/routes/+page.svelte. Compare the import and component names with the code below.

If the usual local address is unavailable, use the address printed by the development server instead.

Help me debug the empty Threlte canvas.

✔️ Awesome, I've got everything!

Your face-mask project is running with its empty 3D canvas. Keep the file saved.

ⓧ I'd like to double check the full code

Compare your page with the complete file below.

<script>
  // Create the root renderer for the empty 3D scene.
  import { Canvas } from '@threlte/core'
</script>

<!-- Give the renderer a full browser viewport. -->
<div class="canvas-root">
  <Canvas />
</div>

<style>
  /* Keep the canvas flush with the browser edges. */
  :global(body) {
    margin: 0;
    overflow: hidden;
  }

  .canvas-root {
    width: 100vw;
    height: 100vh;
    background: #0b1020;
  }
</style>
  • Leave the development server running for the next step.

Your first browser-rendered layer is working. Next, you will place the webcam feed behind this canvas so you can see yourself on the page.

Add the Webcam Feed

Your empty Threlte canvas is rendering in the browser. That gives the mask a place to appear.

The mask also needs a live view of your face. In this step, the browser camera becomes the background beneath your transparent 3D canvas.

In this step, get ready to:
  • Request access to your webcam with getUserMedia.
  • Display the live video stream behind the transparent 3D canvas.
  • Confirm that the camera feed keeps updating as you move.
Request camera access

A browser protects webcam access behind a permission request. Your page starts that request through getUserMedia after it loads in the browser.

  • Open the page component that renders the existing 3D canvas in your local face-mask project.
  • Add a live video element whose browser-only setup assigns the stream returned by getUserMedia.
  • Save the page component.

Your browser should now display a camera permission request for the local project page.

  • Grant camera access through the browser permission request.

You should see your live webcam feed on the page. That confirms the browser can receive frames from your camera.

How does the camera stream work?

The browser returns a live stream from your webcam. The video element displays each incoming frame without uploading it to an external service.

Later steps use those frames to locate your face. The camera stream is the visual source for every tracking update.

Camera feed missing?

Check whether the browser blocked camera access for the local project page. Reset that permission through your browser settings before refreshing the page.

Close any other application that has exclusive control of the webcam. Return to the project page after the camera becomes available.

Help me diagnose the missing webcam feed.

Place the video behind the canvas

The webcam feed provides the background for the finished mask. The transparent canvas stays above it so future 3D objects can appear over your face.

  • Configure the video as an automatically playing muted inline background beneath the canvas.
  • Update the page layout so the webcam video fills the same viewing area as the canvas.
  • Save the page component.

The project page should refresh through the running development server. You should see the live webcam feed through the transparent canvas.

Why use two layers?

The video layer shows the camera image. The canvas layer provides the 3D space where the mask appears.

Matching their viewing areas makes future mesh positions line up with the face shown underneath.

Video covering the canvas?

Check the page layering so the video remains behind the canvas. Confirm that the canvas background stays transparent.

Help me fix the webcam and canvas layering.

Verify the live camera layer

Before you check, do you expect the canvas to hide the video or let it show through?

  • Return to the local project page that is already open in your browser.
  • Refresh the page.
  • Grant camera access again if the browser requests it.
  • Move your head slowly in front of the webcam.

You should see the video update smoothly as you move. The transparent 3D canvas should remain positioned above the live feed.

You have the camera layer working. Your page can now show the face that the 3D mask needs to follow.

  • Leave the development server running.

Your webcam now fills the page beneath the 3D canvas. Next, you will turn those camera frames into a moving cloud of face landmarks.

Track Face Landmarks

Your webcam now supplies a live picture. Those pixels do not identify where your eyes, nose, or jaw are. A tracking layer must turn each frame into coordinates that the 3D scene can use.

In this step, you will load MediaPipe Face Landmarker in the browser. You will turn every result into a Threlte dot cloud that follows your face in real time.

In this step, get ready to:
  • Load MediaPipe Face Landmarker for continuous webcam analysis.
  • Process new webcam frames through the tracker.
  • Render one dot for every returned facial landmark.
Load the Face Landmarker

Face Landmarker needs a WebAssembly runtime plus a trained model before it can inspect a frame. Video mode keeps the tracker ready for a sequence of webcam images.

How does the tracker load?

  • The FaceLandmarker class plus the FilesetResolver class come from @mediapipe/tasks-vision.
  • The FilesetResolver.forVisionTasks() method loads the browser runtime from https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@latest/wasm.
  • The FaceLandmarker.createFromOptions() method loads the model from https://storage.googleapis.com/mediapipe-models/face_landmarker/face_landmarker/float16/latest/face_landmarker.task.
  • The runningMode option uses VIDEO for webcam frames.
  • The numFaces option uses 1 to track the face in front of the camera.
  • In the camera component from the previous step, add the Face Landmarker initialization described above.

The first reload can take longer while the browser fetches the runtime plus the model. A short pause during this first load is expected.

  • Save the camera component.

The development server reloads the page. Your webcam feed should remain visible while the tracker finishes loading.

  • Check the browser network inspector for the model request.

You should see a completed request ending in face_landmarker.task. This confirms that the browser loaded the model used for landmark detection.

Model request not completing?

  • Check that the model URL matches the address shown above.
  • Check that both MediaPipe classes come from @mediapipe/tasks-vision.
  • Reload the project page after correcting the tracker initialization.

Help me debug the Face Landmarker setup.

Render the landmark dot cloud

Each detection result contains normalized coordinates for facial points. The renderer must map those values into the canvas coordinate system used over the video.

How does each frame become dots?

  • The requestAnimationFrame() method schedules predictions alongside browser rendering.
  • The detectForVideo() method processes the current webcam frame with a changing timestamp.
  • A new prediction runs when the webcam advances to a new frame.
  • The first returned landmark set supplies the position of every dot.
  • A mirrored horizontal coordinate keeps each dot aligned with the mirrored webcam feed.
  • Add the frame prediction loop with landmark point rendering to the camera component.
  • Save the camera component.

The project page refreshes. You should see a dense cloud of small dots covering the visible features of your face.

Dot cloud missing or misaligned?

  • Start the prediction loop only after the webcam has a usable frame.
  • Start landmark rendering only after the Face Landmarker has loaded.
  • Mirror the horizontal landmark coordinate to match the webcam feed.

Help me fix the landmark dot cloud.

Verify live tracking

Before you test movement, what do you think the dot cloud will do when you turn your head?

  • Return to the project page from earlier.
  • Center your face inside the webcam frame.

You should see the dots settle across your eyes, nose, mouth, jaw, plus the outline of your face.

  • Turn your head slowly from side to side.

The entire dot cloud should follow your head without staying behind on the screen.

  • Open your mouth while facing the camera.

You should see the dots around your lips move with your mouth. That is the key handoff working. MediaPipe is producing live geometry data that Threlte can draw.

Tracking stops when you move?

  • Keep your face inside the webcam frame during the test.
  • Use steady front lighting so the tracker can distinguish your facial features.
  • Check that each new webcam frame receives a later timestamp.

Help me troubleshoot interrupted face tracking.

Your browser can now turn a live face into moving coordinates. Next up, you will connect those points into a 3D wireframe that sits across your face.

Fit the 3D Face Mesh

Your moving dot cloud proves that MediaPipe Face Landmarker can follow your face frame by frame. Those separate points now need to become one connected surface.

A 3D mesh gives the mask its shape. In this step, Threlte renders a canonical face model while each tracked landmark controls the matching mesh vertex.

In this step, get ready to:
  • Load the canonical 3D face model into the existing Threlte scene.
  • Update the matching mesh vertices from the face landmarks every frame.
  • Confirm that the wireframe mesh follows your head.
Load the canonical face model

The canonical model has a fixed face-shaped layout. Its vertex order provides a stable match for the corresponding landmarks returned by the tracker.

  • Add the canonical 3D face model to the existing Threlte scene in the component that renders the landmark dot cloud.
  • Save the component.

You should see the canonical face surface rendered over the webcam feed. Its position can still look static because the landmarks do not control it yet.

Cannot see the face model?

Confirm that the canonical model belongs to the same canvas scene as the landmark dots. Check that the webcam layer remains behind the transparent canvas.

Ask for help with the missing model if it still does not render: help me find why my canonical face model is missing from the Threlte scene.

Drive the mesh from face landmarks

Wireframe mode exposes the model's edges. This makes alignment problems easy to spot before a texture hides the geometry.

  • Set the canonical face model's material to wireframe mode.
  • Save the component.

You should see the face surface change into a connected grid of edges. The grid reveals how the model's vertices form the mask.

Why Start With Wireframe?

Wireframe mode lets you inspect the entire face topology. Gaps or twisted edges become visible as soon as a vertex receives the wrong landmark position.

This mapping is the fiddly part. The tracker returns normalised positions while the mesh uses coordinates inside the 3D scene.

How Does the Fitting Loop Work?

Each frame uses the newest detected landmarks. Every landmark updates the mesh vertex at the same matching position after its coordinates are converted into scene space.

Reusing the position buffer avoids rebuilding the geometry every frame. Marking that data as changed tells Three.js to render the new shape.

  • Extend the existing frame callback with an in-place mesh-fitting loop that maps every landmark to its corresponding vertex.
  • Save the component.
  • Return to the browser page from earlier.
  • Move your head slowly across the webcam frame.

You should see the wireframe deform around your features while following the dot cloud. The geometry now updates from the latest landmark positions every frame.

Does the Wireframe Move the Wrong Way?

Keep the horizontal coordinate conversion consistent with the mirrored webcam feed. A mismatched horizontal direction makes the mesh move opposite to your face.

If the shape twists or breaks apart, check that every landmark writes to the corresponding mesh vertex. help me debug the landmark-to-vertex mapping in my face mesh.

Check the wireframe tracking

Before the final check, consider whether the wireframe stays attached through a slow head turn.

  • Centre your face inside the webcam frame.
  • Turn your head slowly to the left.
  • Turn your head slowly to the right.
  • Move slightly closer to the camera.

You should see the wireframe remain locked to your face throughout each movement. Its vertices should keep following the corresponding landmark dots without leaving the webcam image.

That is the central tracking bridge working. Your face landmarks now drive a renderable 3D surface in real time.

✔️ Awesome, I've got everything!

Your canonical face mesh is visible in wireframe mode. It follows your head through the live webcam feed.

ⓧ I'd like to double check the full code

Your cumulative project should now match the following state.

  • A canonical 3D face model has vertices mapped to corresponding MediaPipe face landmark positions every frame. The mesh is visible in wireframe mode over the webcam feed.
  • A rendered dot exists for each landmark returned by MediaPipe Face Landmarker. Every dot updates each frame to follow the detected face.
  • MediaPipe Face Landmarker is loaded in the browser. It detects face landmarks continuously from webcam video frames.
  • The local Threlte project named face-mask has a transparent 3D canvas. Its development server remains running.
  • The browser camera stream appears as live video behind the 3D canvas. Camera permission remains granted for the local project page.

Your wireframe now follows the structure of your face. Next, you will replace those visible edges with a texture that stays attached during movement.

Texture and Deploy the Mask

Your wireframe face mesh is locked to the landmark positions. The visible edges keep the result in diagnostic mode.

This step turns the tracked surface into a textured mask. A texture map gives the existing Three.js geometry its finished appearance inside Threlte.

You will publish the result at an HTTPS URL. That public page brings the MediaPipe Face Landmarker experience to your phone camera.

In this step, get ready to:
  • Store a texture image with the face-mask project.
  • Apply the texture to the canonical mesh with wireframe mode disabled.
  • Publish the application at an HTTPS URL for a phone tracking test.
Apply a texture to the face mesh

A texture map uses the mesh's existing UV coordinates to place each part of an image on a stable part of the face. The moving vertices carry that image with them.

  • Switch back to the code editor you used for the wireframe mesh.
  • Choose a texture image that you have permission to use.
  • Copy the image into the face-mask folder through your code editor's file explorer.
  • Confirm the image appears in the face-mask file list.

The texture image is now stored with the project. Its project path can travel with the deployed build.

  • Return to the component that renders the canonical face mesh.
  • Update the existing mesh material to load the texture image from its project path.
  • Save the component file.

The browser page from earlier should refresh. You should see the image colors spread across the moving face mesh.

Texture missing from the mesh?

Check that the material uses the texture image's exact project path. Confirm that the filename capitalization matches the file list.

If the mesh turns blank, try a smaller image in a common browser image format.

Help me diagnose why my face mesh is not showing its texture.

The texture changes the mesh material only. The landmark dot cloud keeps updating from the detected face.

  • Disable wireframe mode on the existing face mesh material.
  • Save the component file.

You should now see a solid textured mask over your webcam feed. The texture should remain attached as you move your head.

Still seeing wireframe edges?

Confirm that wireframe mode is disabled on the material assigned to the canonical face mesh. Make sure you edited the material used by the moving mesh.

If the texture stops moving, restore the existing vertex update logic. The material change should leave that tracking loop untouched.

Help me check why the textured face mesh still shows wireframe edges or no longer tracks.

That is the visual leap. Your tracker now drives a finished mask.

Publish the browser experience

A phone browser needs a secure page before it can request camera access. Publishing through an HTTPS host gives it that secure context.

Your provider login stays with that provider. This project does not ask you to paste credentials into the application.

  • In your browser, sign in to the HTTPS hosting provider you use for web projects.
  • Create a new site from the face-mask project through the provider's project-import screen.
  • Start the deployment with the settings detected from the project.

You should see the deployment finish with a public HTTPS address. That address points to the deployed version of your mask.

Deployment did not finish?

Confirm that you selected the face-mask folder instead of its parent folder. The host needs the project files that contain the existing build setup.

If the build fails, compare the provider's detected settings with the settings used by your local project.

Help me troubleshoot why my face-mask project is not deploying.

  • Record the public address here: https://your-face-mask.example.

Before you load the public page, do you expect it to reuse the camera permission from your local page?

  • Open https://your-face-mask.example in a new browser tab on your laptop.
  • Grant camera access when your browser requests it.
  • Center your face in the webcam frame.

You should see the live webcam feed on the deployed page. The textured mask should follow your face as you move.

Your mask now has a public home. The next check proves that the deployment works beyond your laptop.

Test the mask on your phone

This check proves the deployed build works on another device. It also confirms the phone can load every asset before tracking begins.

Before you load the page, do you expect the phone to share your laptop's camera permission?

  • Enter https://your-face-mask.example in your phone's browser.

You should see a fresh camera permission request. Camera access is granted separately for each browser and device.

  • Grant camera access on your phone.
  • Center your face in the phone camera frame.
  • Turn your head slowly to the left.
  • Turn your head slowly to the right.

You should see the phone's webcam feed with the textured mask locked to your face. The texture should stay attached through both head turns.

Mask not tracking on your phone?

Confirm that the deployed address uses HTTPS. Reload the page after granting camera access.

If the mask moves in the wrong direction, confirm that the webcam video and face mesh use the same mirroring direction.

Help me troubleshoot face-mask tracking on my phone.

You have completed the full loop. Your phone camera now drives the textured face mesh from a public URL.

Secret mission

Design and Publish a Second Mask

Turn your current mask into a second design with a stripe on one side. Add a circle to the other side. Use both markers to test alignment before publishing the new look to your existing URL.

Clean Up Your Resources

Clean Up Your Resources

Face tracking runs on your devices with no paid API calls, so this project has no ongoing usage costs. Decide whether to keep everything, pause the live camera session, or delete the resources you no longer need.

Resources you used:

  • The running local development server for your Threlte project.
  • The local face-mask project folder. It contains the canonical face mesh, MediaPipe Face Landmarker setup, project code, dependencies, and texture image.
  • Camera permission for the local project page in your laptop browser.
  • Camera permission for the deployed page in your phone browser.
  • The deployed face-mask application at your learner-owned HTTPS URL.

Keep everything running

Leave the current setup in place if you are still experimenting with textures or face tracking.

  • Keep the local development server running while you are actively testing the mask.
  • Keep the face-mask folder so your project code plus texture image remain available.
  • Leave camera permission enabled on each device you are still using for tests.
  • Keep the deployed application online so your learner-owned URL continues to show the mask.

Pause - I'll come back to this later

End the active camera sessions to free local resources while preserving your project files plus deployed page.

  • Return to the terminal running the local development server.
  • Press Ctrl+C to stop the server.
  • Confirm the terminal returns to its command prompt.

Your local server is now stopped. The face-mask folder remains untouched.

  • Return to the local project page in your laptop browser.
  • Use browser settings for that page to revoke camera access.
  • Check that camera access for the local project page is no longer allowed.
  • Return to the deployed page in your phone browser.
  • Use browser settings for that page to revoke camera access.
  • Check that camera access for the deployed page is no longer allowed.

That closes both live camera sessions while keeping your mask ready for another day. Your local folder plus deployed URL remain available.

Delete - I don't want to use this again

Your texture image disappears when you delete the local folder. The deployed page also goes offline when you remove the hosted application.

  • Return to the terminal running the local development server.
  • Press Ctrl+C to stop the server.
  • Confirm the terminal returns to its command prompt.

The development server no longer holds the project folder open.

  • Return to the local project page in your laptop browser.
  • Use browser settings for that page to revoke camera access.
  • Return to the deployed page in your phone browser.
  • Use browser settings for that page to revoke camera access.

Check both browser settings. Neither page should still have camera access.

Your hosting provider determines where its deployment deletion control appears.

  • Return to the hosting service you used earlier.
  • Select the deployed face-mask application.
  • Use the provider's documented project deletion control.
  • Return to your learner-owned URL after the deletion finishes.

You should no longer see the face mask page at that URL. This confirms the hosted application has been removed.

Delete the local face-mask folder using the instructions for your computer.

macOS

  • Return to the Finder window containing the face-mask folder.
  • Select the face-mask folder.
  • Press Cmd+Delete to move the folder to Trash.
  • Empty Trash to remove the folder permanently.
  • Confirm the face-mask folder no longer appears in Finder.

Windows

  • Return to the File Explorer window containing the face-mask folder.
  • Select the face-mask folder.
  • Press the Delete key to move the folder to the Recycle Bin.
  • Empty the Recycle Bin to remove the folder permanently.
  • Confirm the face-mask folder no longer appears in File Explorer.

Cleanup complete. The project no longer runs locally or at your deployed URL.

Nice Work!

Nice Work!

You did it! Your textured 3D mask now tracks your face in real time through a deployed browser page. You also confirmed that camera tracking works on your phone.

What you learned:

  • Turned a live webcam feed into a moving landmark dot cloud with MediaPipe Face Land Landmarker.
  • Mapped tracked points onto a canonical 3D face model in Threlte. The mesh now follows each head movement.
  • Applied a texture image to create the finished mask. Deployed the application to an HTTPS URL. Verified live camera tracking on a phone.
  • Completed the optional Secret Mission to extend the browser face-mask experience.

Ready to quiz yourself?