Three.js Depth Portrait

Recreate the interactive depth portrait effect popularized by modern portfolio websites using Three.js and WebGL.

View the Project on GitHub flavioow/threejs-depth-portrait

Finishing

The final step is to use the effect inside a real page and make it easy to adapt.

In this project, the page renders the loader and places the 3D hero behind text content.

Add The Hero To A Page

The basic structure is:

<>
  <LoaderOverlay />
  <main>
    <section className="relative isolate overflow-hidden">
      <Hero3D />
      {/* Your hero content goes here */}
    </section>
  </main>
</>

Hero3D should be positioned as the visual layer, while text or UI content can sit above it.

Place Content Over The Canvas

The canvas works well as a background layer for a hero section.

Keep the section responsible for:

The 3D system should stay focused on rendering the portrait and reacting to movement.

Replace The Portrait

To use another person or image, replace the five texture maps in public/:

diffuse.png
alpha.png
depth.png
normal.webp
roughness.webp

Keep the same filenames unless you also update texturePaths in ImagePlane.

All maps should share the same framing. If the depth map or alpha map does not line up with the diffuse image, the final result will feel broken.

Tune The Effect

Use hero-parallax-config to tune the feel.

Start with small changes:

Change one value at a time. The effect is sensitive, and small numbers usually look more convincing.

Test The Result

Before calling the effect finished, test:

Final Checklist

This guide covers the practical path. Deeper explanations about texture theory, shader architecture and internal design decisions can live in future documentation sections.