Listen up. If you're building modern applications, understanding The Scene in Three.js 3D WebGL is non-negotiable. This is where simple logic turns into intelligent behavior.
1The Scene as a Container
The Scene is the container for everything. It's the 3D universe where you place your objects, lights, and cameras ā nothing appears on screen unless it has been added to the scene graph first.
Internally, THREE.Scene is just a specialized THREE.Object3D that acts as the root of a tree. Every mesh, light, or group you add becomes a child node, and the renderer walks this tree each frame to figure out what to draw. This hierarchical structure is also what allows grouping: moving a parent object automatically moves every child along with it.
const scene = new THREE.Scene();3D Scene rendered. Objects: 4, Draw Calls: Optimized.
2The Scene as a Movie Set
You can think of the Scene like a movie set. A movie set without actors, lights, or a camera isn't much to look at ā the same is true of a THREE.Scene with nothing added to it.
The scene.add() method is how every actor joins that set: pass it any Object3D (a mesh, a light, a group, even another scene fragment) and it becomes part of the render tree from that point forward. Forgetting to call scene.add() on an object you've created is one of the most common reasons a Three.js object simply never appears.
scene.add(cube);
scene.add(light);3D Scene rendered. Objects: 4, Draw Calls: Optimized.
3Customizing the Scene Background
You can also change the environment of the scene itself. Let's start by changing the background color of the universe ā assigning a THREE.Color to scene.background instantly changes what fills the space outside your objects.
scene.background isn't limited to solid colors either; it also accepts a THREE.Texture or a THREE.CubeTexture, which is how skyboxes and environment reflections are typically implemented. The renderer paints this background before anything else each frame, so it always sits visually behind every object in the scene.
scene.background = new THREE.Color('midnightblue');3D Scene rendered. Objects: 4, Draw Calls: Optimized.
4Scene Setup in React Three Fiber
In React Three Fiber, the Scene is created automatically by the Canvas component. To change the background color, we can just attach a color element to the scene's background property declaratively ā no imperative scene.background = ... call needed.
This is a recurring R3F pattern: properties that Three.js sets imperatively on an object are instead expressed as JSX children with an attach prop telling R3F which property on the parent to assign the result to. It keeps scene configuration readable as part of your component tree instead of scattered across useEffect calls.
const App = () => {
return (
<Canvas>
<color attach="background" args={["#111122"]} />
<mesh>
<boxGeometry />
<meshNormalMaterial />
</mesh>
</Canvas>
);
};
render(<App />);3D Scene rendered. Objects: 4, Draw Calls: Optimized.
5The attach Prop in R3F
In R3F, the attach prop on the color tag is what assigns it to the scene's background property specifically ā attach="background" tells the reconciler 'set scene.background to the THREE.Color instance this tag creates.'
The args prop alongside it passes constructor arguments to the underlying Three.js class, exactly like it does for geometries ā args={["#111122"]} is equivalent to calling new THREE.Color("#111122"). Together, attach and args let a single JSX tag replace what would otherwise be several lines of imperative setup code.
<color ???='background' args={['red']} />3D Scene rendered. Objects: 4, Draw Calls: Optimized.
6Adding Fog for Depth
Another amazing feature of the Scene is Fog. Fog gradually fades objects into a specific color based on their distance from the camera, which is one of the cheapest ways to add a sense of scale and depth to a scene.
Beyond the aesthetic effect, fog is a practical performance tool: distant objects that fade completely into the fog color can often be culled from rendering entirely (a technique sometimes paired with far-plane clipping), since the viewer would never be able to see them clearly anyway.
scene.fog = new THREE.Fog('#111122', 1, 10); // color, near, far3D Scene rendered. Objects: 4, Draw Calls: Optimized.
7Fog in React Three Fiber
Let's see Fog in action in React Three Fiber! Watch how the cubes fade into the dark background as they move further back ā the fog tag with attach="fog" follows the exact same declarative pattern we used for the background color.
Notice that the fog's color in this example matches the scene's background color. This isn't a coincidence: fog blends objects toward its own color as distance increases, so mismatching fog and background colors produces a visible seam where fully-fogged objects meet the background instead of disappearing into it seamlessly.
const SceneWithFog = () => {
return (
<Canvas camera={{ position: [0, 2, 5] }}>
<color attach="background" args={["#111122"]} />
<fog attach="fog" args={["#111122", 2, 8]} />
<ambientLight intensity={0.5} />
<directionalLight position={[10, 10, 10]} />
{/* Front Cube - Clear */}
<mesh position={[0, 0, 0]}>
<boxGeometry />
<meshStandardMaterial color="hotpink" />
</mesh>
{/* Middle Cube - Semi-fogged */}
<mesh position={[2, 0, -3]}>
<boxGeometry />
<meshStandardMaterial color="hotpink" />
</mesh>
{/* Back Cube - Almost completely fogged */}
<mesh position={[-2, 0, -6]}>
<boxGeometry />
<meshStandardMaterial color="hotpink" />
</mesh>
</Canvas>
);
};
render(<SceneWithFog />);3D Scene rendered. Objects: 4, Draw Calls: Optimized.
8Understanding Fog's Distance Arguments
THREE.Fog takes three arguments: a color, a near distance, and a far distance. Objects closer than near render with zero fog applied, objects at or beyond far are rendered fully in the fog color, and anything in between is linearly blended based on its distance from the camera.
Tuning near and far is mostly a matter of testing against your scene's actual scale ā a near value that's too small makes even close objects look hazy, while a far value that's too large means distant objects never fully fade, undermining the depth cue fog is meant to provide.
scene.fog = new THREE.Fog('#000', 1, ???);3D Scene rendered. Objects: 4, Draw Calls: Optimized.
9Wrapping Up Scene Fundamentals
Excellent! You now know how to set the stage for your 3D world using the Scene, Backgrounds, and Fog ā the environmental building blocks that every Three.js project relies on before a single interactive object is added.
In the next lesson, we'll turn to the Camera: the object that determines exactly what portion of this scene is actually visible, and how perspective and framing affect the final image the renderer produces.
// š Universe created successfully!3D Scene rendered. Objects: 4, Draw Calls: Optimized.
10Step-by-Step Breakdown
The Scene is the container for everything. It's the 3D universe where you place your objects, lights, and cameras.
You can think of the Scene like a movie set. A movie set without actors, lights, or a camera isn't much to look at.
Which method is used to put an object into the scene?
- āpush
- āadd
- āinsert
You can also change the environment of the scene itself. Let's start by changing the background color of the universe.
In React Three Fiber, the Scene is created automatically by the <Canvas>. To change the background color, we can just attach a color to the scene's background property.
In R3F, which prop is used on the <color> tag to assign it to the scene's background?
- āassign
- āset
- āattach
Another amazing feature of the Scene is Fog. Fog gradually fades objects into a specific color based on their distance from the camera.
Let's see Fog in action in React Three Fiber! Watch how the cubes fade into the dark background as they move further back.
What does the third argument in new THREE.Fog(color, near, far) represent?
- āDensity of the fog
- āMaximum distance before full fog
- āMinimum distance
Excellent! You now know how to set the stage for your 3D world using the Scene, Backgrounds, and Fog.
Level Up š
Advanced cheat sheets, SEO tricks, and interview prep for this topic.
Browser Support
Fully supported.
Fully supported.
Fully supported.
Fully supported.
Accessibility (A11y)
1Announce Scene-Level Changes That Aren't Visually Obvious
A fog or background color change communicates mood or depth visually, but conveys nothing to a screen reader user ā if such a change is tied to an important state transition (like 'entering a new level'), announce that transition via an aria-live region rather than relying on the visual cue alone.
<div aria-live="polite">Now entering the misty forest zone.</div>SEO Implications
- 1
Scene Configuration Is Runtime State, Not Crawlable Content
scene.background and scene.fog only exist once WebGL has initialized in the browser ā none of it is present in server-rendered HTML or visible to a crawler, so this page's search value comes entirely from the surrounding written explanation of how the Scene API works, not from any specific fog color or background value.
Best Practices
Match Fog Color to Background Color for a Seamless Blend
If your fog's color doesn't match the scene's background, fully-fogged objects will visibly blend into a different color than the empty background behind them, creating an obvious seam. Keep both colors identical unless you deliberately want that contrast.
Tune Fog's near/far Values to Your Scene's Actual Scale
Default or copy-pasted fog distances rarely match a new scene's dimensions. Test near and far against your camera's typical viewing distance so nearby objects aren't hazy and distant objects actually fade out before the camera's far clipping plane.
Frequent Bugs
Setting scene.background or scene.fog on the underlying Three.js scene object directly inside a React Three Fiber component's render body, causing it to be reassigned on every re-render.
In R3F, express scene-level properties declaratively with the <color attach="background"> and <fog attach="fog"> tags instead of imperatively mutating the scene object ā this lets React's reconciliation handle updates efficiently instead of reassigning the property on every render pass.
Real-World Examples
Depth Cueing in a Racing Game's Track Environment
Racing and flight-sim style Three.js experiences commonly combine a matching scene.background color with THREE.Fog to make distant terrain fade smoothly into the horizon, both hiding the harsh edge of the camera's draw distance and reducing the number of distant objects the GPU needs to fully render each frame.
scene.background = new THREE.Color('#87CEEB');
scene.fog = new THREE.Fog('#87CEEB', 50, 500);