DEV Community

Cover image for Understanding Three.js Lighting — A Concise Reference
Peter Riding
Peter Riding

Posted on

Understanding Three.js Lighting — A Concise Reference

Understanding Three.js Lighting — A Concise Reference

TL;DR: Start with an Ambient/Hemisphere fill, add a Directional for sun, use Point/Spot sparingly for local effects, and RectArea for studio soft light.
Read time: ~3–4 minutes

Lighting transforms a flat scene into something believable. This short reference explains the six core Three.js lights (plus a note on LightProbe), when to use them, and practical performance tips.


The lights at a glance

Light Real-world What it does Use / performance Notes
AmbientLight Overcast / studio fill Uniform light, no shadows ✅ Very cheap — always add a little Use low intensity (0.1–0.5) to avoid flatness
DirectionalLight Sun / flood Parallel rays, good shadows 🟡 Moderate — efficient for large scenes No distance falloff; tune shadow.camera for quality
HemisphereLight Sky above / ground below Sky color on up-facing, ground color on down-facing ✅ Cheap — natural outdoor tint Params: skyColor, groundColor, intensity
PointLight Bulb / candle Radiates in all directions, attenuates 🔴 Expensive if many + shadows Use distance and decay (constructor: color, intensity, distance, decay)
RectAreaLight Softbox Soft directional illumination 🔴 Expensive — studio-quality Works only with MeshStandardMaterial / MeshPhysicalMaterial; requires examples lib init
SpotLight Flashlight / headlight Cone-shaped beam; adjustable angle & penumbra 🔴 Most expensive if casting shadows Needs a target added to the scene; tune angle, penumbra, decay

Note — LightProbe: Useful for image-based PBR lighting (cheap ambient for materials). Pairs with environment maps and PMREMGenerator.


Quick, practical setups

Assumes scene and THREE are available.

1) Outdoor / daylight (realistic, moderate cost)

scene.add(new THREE.AmbientLight(0xffffff, 0.3));

const sun = new THREE.DirectionalLight(0xffffff, 0.9);
sun.position.set(10, 15, 5);
sun.castShadow = true;
sun.shadow.mapSize.set(1024, 1024);
sun.shadow.camera.left = -20;
sun.shadow.camera.right = 20;
sun.shadow.bias = -0.0005;
scene.add(sun);
Enter fullscreen mode Exit fullscreen mode

Good for landscapes and day/night cycles. Ambient prevents pitch-black shadows.


2) Interior / dynamic (medium cost)

scene.add(new THREE.AmbientLight(0xffffff, 0.5));

const lamp = new THREE.PointLight(0xffeecc, 1, 15, 2); // color, intensity, distance, decay
lamp.position.set(0, 3, 0);
lamp.castShadow = true;
scene.add(lamp);

const accent = new THREE.SpotLight(0xff9000, 0.8, 30, Math.PI / 6, 0.2, 2);
accent.position.set(5, 4, 3);
scene.add(accent);
scene.add(accent.target); // remember to add the target to the scene
Enter fullscreen mode Exit fullscreen mode

Limit shadow-casting lights to a few; prefer baked lighting for fixed interiors.


3) Studio / product (higher cost — high quality)

import { RectAreaLightUniformsLib } from 'three/examples/jsm/lights/RectAreaLightUniformsLib.js';
RectAreaLightUniformsLib.init();

scene.add(new THREE.AmbientLight(0xffffff, 0.4));

const key = new THREE.RectAreaLight(0xffffff, 2, 4, 4);
key.position.set(-5, 4, 3);
key.lookAt(0, 0, 0);
scene.add(key);

const back = new THREE.DirectionalLight(0xff9900, 0.6);
back.position.set(0, 3, -8);
scene.add(back);
Enter fullscreen mode Exit fullscreen mode

Note: RectAreaLight only lights MeshStandardMaterial / MeshPhysicalMaterial and requires RectAreaLightUniformsLib.init() (examples helper).


Performance rules of thumb

  • Start with Ambient (0.2–0.3). Cheap and prevents black areas.
  • Use 1 Directional for sun/moon effects; tune shadow.camera bounds for shadow quality.
  • Cap Point/Spot lights to ~3–5 in real-time; each shadowed light is costly.
  • Disable shadows on lights that don’t need them: light.castShadow = false.
  • Decay = 2 is standard for realistic attenuation with PointLight/SpotLight; modern Three.js uses physical units by default.
  • Shadow tuning: reduce shadow.mapSize, constrain shadow.camera, and use shadow.bias to fight acne.

Key takeaways

  • 2–4 lights is usually enough — more lights ≠ better visuals, just more cost.
  • AmbientLight is your safety net. Use a low intensity to soften contrast.
  • Reserve Point/Spot/RectArea for visual impact where they matter.
  • Profile your scene (Three.js DevTools / Chrome DevTools) to find bottlenecks.

Top comments (0)