Recreate the interactive depth portrait effect popularized by modern portfolio websites using Three.js and WebGL.
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.
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.
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.
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.
Use hero-parallax-config to tune the feel.
Start with small changes:
pointerRange for stronger input response.motionDamping for faster motion.uvParallaxStrength for stronger pixel displacement.vertexDepthStrength for stronger geometric depth.depthPower to reshape how the depth map feels.Change one value at a time. The effect is sensitive, and small numbers usually look more convincing.
Before calling the effect finished, test:
public/.This guide covers the practical path. Deeper explanations about texture theory, shader architecture and internal design decisions can live in future documentation sections.