Three.js Lighting
Use this skill for light selection, shadow behavior, and image-based illumination. Route
PBR surface settings to threejs-materials, HDR/environment asset setup to
threejs-textures, and screen-space effects to threejs-postprocessing.
When to use this skill
- Light a scene with physically meaningful direct and ambient/environment contribution
- Configure directional, point, or spot shadows without uncontrolled quality cost
- Set up an HDR environment for PBR reflections and diffuse illumination
- Diagnose black, flat, overexposed, acne-prone, or performance-heavy lighting
Instructions
Step 1: Start from material and exposure reality
- Confirm the mesh uses a light-reactive material such as
MeshStandardMaterial; an
unlit MeshBasicMaterial cannot demonstrate lighting changes.
- Establish renderer color/tone settings before compensating with arbitrary light values.
- Decide whether the scene needs direct lights, image-based lighting, or both. A single
ambient light hides shape; use it sparingly as fill, not as an all-purpose fix.
Step 2: Choose the narrowest light model
| Visual requirement |
Default |
| Sun/moon-like directional source |
DirectionalLight |
| Local bulb or small emitter |
PointLight |
| Cone/projector with falloff |
SpotLight |
| Soft sky/ground fill |
HemisphereLight |
| Large studio panel |
RectAreaLight |
| PBR reflection and ambient response |
Environment map / IBL |
const key = new THREE.DirectionalLight(0xffffff, 3);
key.position.set(4, 6, 3);
key.castShadow = true;
scene.add(key);
scene.add(new THREE.HemisphereLight(0xcfe8ff, 0x223344, 1));
Use helpers during setup, then remove or gate them in production views.
Step 3: Make shadows intentional
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
mesh.castShadow = true;
mesh.receiveShadow = true;
key.shadow.mapSize.set(1024, 1024);
key.shadow.camera.near = 0.5;
key.shadow.camera.far = 30;
Tighten the shadow camera/frustum around real casters and receivers. Increase map size,
number of shadow-casting lights, or update frequency only after profiling target hardware.
Address acne/peter-panning by checking geometry scale, bias, and normal bias—not by
blindly pushing values until artifacts invert.
Step 4: Add image-based lighting when PBR requires it
Load and preprocess an HDR/equirectangular asset through the appropriate loader/PMREM
path for the installed Three.js version. Set scene.environment for material response;
set scene.background separately when the environment should also be visible.
Step 5: Verify look and budget
- Compare the material response with shadows off/on, direct light only, and IBL only.
- Test shadow edges, moving casters, and objects near the light's shadow bounds.
- Profile on target devices with real scene density before raising quality tiers.
- Verify teardown disposes feature-owned environment/render resources through the
texture-loading owner.
Examples
Small product presentation
Use a key directional/area source, low-intensity fill, and an environment map. Do not
simulate every studio bounce with many shadowed point lights; PBR environment lighting is
usually more stable and cheaper.
Outdoor scene
Use one directional sun, a sky/ground hemisphere contribution, and a bounded shadow
camera that follows the visible play/view area only when required.
Best practices
- Light for material response, not only for a bright screenshot.
- Keep shadow casters/receivers and the shadow frustum as small as the visual need allows.
- Use environment maps for PBR instead of stacking ambient lights.
- Tune tone mapping/exposure at the renderer level before distorting every light.
- Treat every shadow quality increase as a measured performance tradeoff.
References
1---2name: threejs-lighting3description: Design and debug Three.js lighting with directional, point, spot, hemisphere, and area lights, shadow maps, image-based lighting, environment maps, light helpers, and performance budgets. Use when lighting a 3D scene, configuring shadows, setting up HDR illumination, matching a visual reference, or fixing dark, flat, or expensive renders. Triggers on: Three.js lighting, directional light, point light, spot light, shadows, shadow map, ambient light, HDR environment, IBL, environment map, light helper.4license: MIT5---67# Three.js Lighting89Use this skill for light selection, shadow behavior, and image-based illumination. Route10PBR surface settings to `threejs-materials`, HDR/environment asset setup to11`threejs-textures`, and screen-space effects to `threejs-postprocessing`.1213## When to use this skill1415- Light a scene with physically meaningful direct and ambient/environment contribution16- Configure directional, point, or spot shadows without uncontrolled quality cost17- Set up an HDR environment for PBR reflections and diffuse illumination18- Diagnose black, flat, overexposed, acne-prone, or performance-heavy lighting1920## Instructions2122### Step 1: Start from material and exposure reality23241. Confirm the mesh uses a light-reactive material such as `MeshStandardMaterial`; an25 unlit `MeshBasicMaterial` cannot demonstrate lighting changes.262. Establish renderer color/tone settings before compensating with arbitrary light values.273. Decide whether the scene needs direct lights, image-based lighting, or both. A single28 ambient light hides shape; use it sparingly as fill, not as an all-purpose fix.2930### Step 2: Choose the narrowest light model3132| Visual requirement | Default |33|---|---|34| Sun/moon-like directional source | `DirectionalLight` |35| Local bulb or small emitter | `PointLight` |36| Cone/projector with falloff | `SpotLight` |37| Soft sky/ground fill | `HemisphereLight` |38| Large studio panel | `RectAreaLight` |39| PBR reflection and ambient response | Environment map / IBL |4041```js42const key = new THREE.DirectionalLight(0xffffff, 3);43key.position.set(4, 6, 3);44key.castShadow = true;45scene.add(key);46scene.add(new THREE.HemisphereLight(0xcfe8ff, 0x223344, 1));47```4849Use helpers during setup, then remove or gate them in production views.5051### Step 3: Make shadows intentional5253```js54renderer.shadowMap.enabled = true;55renderer.shadowMap.type = THREE.PCFSoftShadowMap;5657mesh.castShadow = true;58mesh.receiveShadow = true;59key.shadow.mapSize.set(1024, 1024);60key.shadow.camera.near = 0.5;61key.shadow.camera.far = 30;62```6364Tighten the shadow camera/frustum around real casters and receivers. Increase map size,65number of shadow-casting lights, or update frequency only after profiling target hardware.66Address acne/peter-panning by checking geometry scale, bias, and normal bias—not by67blindly pushing values until artifacts invert.6869### Step 4: Add image-based lighting when PBR requires it7071Load and preprocess an HDR/equirectangular asset through the appropriate loader/PMREM72path for the installed Three.js version. Set `scene.environment` for material response;73set `scene.background` separately when the environment should also be visible.7475### Step 5: Verify look and budget7677- Compare the material response with shadows off/on, direct light only, and IBL only.78- Test shadow edges, moving casters, and objects near the light's shadow bounds.79- Profile on target devices with real scene density before raising quality tiers.80- Verify teardown disposes feature-owned environment/render resources through the81 texture-loading owner.8283## Examples8485### Small product presentation8687Use a key directional/area source, low-intensity fill, and an environment map. Do not88simulate every studio bounce with many shadowed point lights; PBR environment lighting is89usually more stable and cheaper.9091### Outdoor scene9293Use one directional sun, a sky/ground hemisphere contribution, and a bounded shadow94camera that follows the visible play/view area only when required.9596## Best practices97981. Light for material response, not only for a bright screenshot.992. Keep shadow casters/receivers and the shadow frustum as small as the visual need allows.1003. Use environment maps for PBR instead of stacking ambient lights.1014. Tune tone mapping/exposure at the renderer level before distorting every light.1025. Treat every shadow quality increase as a measured performance tradeoff.103104## References105106- [Three.js Lighting source coverage](https://github.com/CloudAI-X/threejs-skills/tree/main/skills/threejs-lighting)107- [Lights documentation](https://threejs.org/docs/#api/en/lights/Light)108- [Three.js manual: shadows](https://threejs.org/manual/#en/shadows)