Recreate the interactive depth portrait effect popularized by modern portfolio websites using Three.js and WebGL.
Now that the image maps exist, build the scene that will display them.
At this stage, the goal is not to perfect the parallax effect. The goal is to create a clean rendering structure: a page component, a canvas, a scene root, a camera controller and an image plane.
The project separates the hero into a few clear layers:
Hero3D defines the active hero area.HeroCanvas creates the WebGL canvas.SceneRoot composes the scene.CameraController moves the camera.ImagePlane renders the portrait.hero-parallax-config stores shared tuning values.SceneReadiness reports loading progress for the scene.This separation keeps React UI, Three.js scene code and low-level systems from becoming one large component.
Hero3D is the component you place in the page. Its main job is to create a container ref and pass that active area to the canvas.
That container matters later because pointer input should be calculated relative to the hero, not the entire browser window.
HeroCanvas owns the React Three Fiber <Canvas>.
It configures:
SceneRoot.This is also where the input manager will be created later, because the canvas knows which DOM container defines the interactive area.
SceneRoot is the composition layer. It should contain:
CameraController.ImagePlane.SceneReadiness.The scene root is also a good place to update shared per-frame state with useFrame.
ImagePlane loads the texture maps and renders a segmented plane geometry.
The plane needs enough segments because the vertex shader will later displace the geometry using the depth map. In this project, that value lives in HERO_IMAGE_PLANE_SEGMENTS.
The image plane is also where you configure texture color spaces, wrapping and filtering so the maps behave correctly inside the shader.
Keep tunable values in hero-parallax-config.
This file should hold values such as:
Centralizing these values makes the final effect easier to tune without searching through every component.
Before moving on, the canvas should render a portrait plane in the page. It does not need to feel fully 3D yet.