Threejs Lighting

calesthio/OpenMontage/.claude/skills/threejs-lighting

by calesthio9327439db69021ab4b0e2776729bf3b58fdb5a87No license65K starsListed Oct 9, 2026Updated Oct 9, 2026Repository updated 5 days ago

Three.js lighting - light types, shadows, environment lighting. Use when adding lights, configuring shadows, setting up IBL, or optimizing lighting performance.

Instructions onlySoftware Development
AI-generated overview

Reference guide for Three.js lighting: light types, shadow configuration, IBL environments, and performance tuning.

What it does
This skill is an instructional reference for lighting 3D scenes in Three.js. It documents ambient, hemisphere, directional, point, spot, and rectangular area lights with code snippets, plus shadow setup, shadow map types, bias fixes, and contact shadows. It also covers image-based lighting with HDR and cube environments, light probes, helpers, common three-point and studio setups, light animation, and performance tips.
When to use it
Use it when adding or tuning lights in a Three.js scene, configuring shadows, setting up IBL or environment maps, or optimizing lighting performance. It suits developers who need concrete API examples rather than conceptual explanation.
Requirements
No scripts are included; it is instructions only. It assumes a Three.js project and familiarity with JavaScript and the Three.js API; some examples reference example modules such as RGBELoader, RectAreaLightUniformsLib, and ContactShadows, and HDR or cube texture assets for environment lighting.

Three.js Lighting

Quick Start

javascript
import * as THREE from "three";
// Basic lighting setupconst ambientLight = new THREE.AmbientLight(0xffffff, 0.5);scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);directionalLight.position.set(5, 5, 5);scene.add(directionalLight);

Light Types Overview

LightDescriptionShadow SupportCost
AmbientLightUniform everywhereNoVery Low
HemisphereLightSky/ground gradientNoVery Low
DirectionalLightParallel rays (sun)YesLow
PointLightOmnidirectional (bulb)YesMedium
SpotLightCone-shapedYesMedium
RectAreaLightArea light (window)No*High

*RectAreaLight shadows require custom solutions

AmbientLight

Illuminates all objects equally. No direction, no shadows.

javascript
// AmbientLight(color, intensity)const ambient = new THREE.AmbientLight(0xffffff, 0.5);scene.add(ambient);
// Modify at runtimeambient.color.set(0xffffcc);ambient.intensity = 0.3;

HemisphereLight

Gradient from sky to ground color. Good for outdoor scenes.

javascript
// HemisphereLight(skyColor, groundColor, intensity)const hemi = new THREE.HemisphereLight(0x87ceeb, 0x8b4513, 0.6);hemi.position.set(0, 50, 0);scene.add(hemi);
// Propertieshemi.color; // Sky colorhemi.groundColor; // Ground colorhemi.intensity;

DirectionalLight

Parallel light rays. Simulates distant light source (sun).

javascript
// DirectionalLight(color, intensity)const dirLight = new THREE.DirectionalLight(0xffffff, 1);dirLight.position.set(5, 10, 5);
// Light points at target (default: 0, 0, 0)dirLight.target.position.set(0, 0, 0);scene.add(dirLight.target);
scene.add(dirLight);

DirectionalLight Shadows

javascript
dirLight.castShadow = true;
// Shadow map size (higher = sharper, more expensive)dirLight.shadow.mapSize.width = 2048;dirLight.shadow.mapSize.height = 2048;
// Shadow camera (orthographic)dirLight.shadow.camera.near = 0.5;dirLight.shadow.camera.far = 50;dirLight.shadow.camera.left = -10;dirLight.shadow.camera.right = 10;dirLight.shadow.camera.top = 10;dirLight.shadow.camera.bottom = -10;
// Shadow softnessdirLight.shadow.radius = 4; // Blur radius (PCFSoftShadowMap only)
// Shadow bias (fixes shadow acne)dirLight.shadow.bias = -0.0001;dirLight.shadow.normalBias = 0.02;
// Helper to visualize shadow cameraconst helper = new THREE.CameraHelper(dirLight.shadow.camera);scene.add(helper);

PointLight

Emits light in all directions from a point. Like a light bulb.

javascript
// PointLight(color, intensity, distance, decay)const pointLight = new THREE.PointLight(0xffffff, 1, 100, 2);pointLight.position.set(0, 5, 0);scene.add(pointLight);
// PropertiespointLight.distance; // Maximum range (0 = infinite)pointLight.decay; // Light falloff (physically correct = 2)

PointLight Shadows

javascript
pointLight.castShadow = true;pointLight.shadow.mapSize.width = 1024;pointLight.shadow.mapSize.height = 1024;
// Shadow camera (perspective - 6 directions for cube map)pointLight.shadow.camera.near = 0.5;pointLight.shadow.camera.far = 50;
pointLight.shadow.bias = -0.005;

SpotLight

Cone-shaped light. Like a flashlight or stage light.

javascript
// SpotLight(color, intensity, distance, angle, penumbra, decay)const spotLight = new THREE.SpotLight(0xffffff, 1, 100, Math.PI / 6, 0.5, 2);spotLight.position.set(0, 10, 0);
// Target (light points at this)spotLight.target.position.set(0, 0, 0);scene.add(spotLight.target);
scene.add(spotLight);
// PropertiesspotLight.angle; // Cone angle (radians, max Math.PI/2)spotLight.penumbra; // Soft edge (0-1)spotLight.distance; // RangespotLight.decay; // Falloff

SpotLight Shadows

javascript
spotLight.castShadow = true;spotLight.shadow.mapSize.width = 1024;spotLight.shadow.mapSize.height = 1024;
// Shadow camera (perspective)spotLight.shadow.camera.near = 0.5;spotLight.shadow.camera.far = 50;spotLight.shadow.camera.fov = 30;
spotLight.shadow.bias = -0.0001;
// Focus (affects shadow projection)spotLight.shadow.focus = 1;

RectAreaLight

Rectangular area light. Great for soft, realistic lighting.

javascript
import { RectAreaLightHelper } from "three/examples/jsm/helpers/RectAreaLightHelper.js";import { RectAreaLightUniformsLib } from "three/examples/jsm/lights/RectAreaLightUniformsLib.js";
// Must initialize uniforms firstRectAreaLightUniformsLib.init();
// RectAreaLight(color, intensity, width, height)const rectLight = new THREE.RectAreaLight(0xffffff, 5, 4, 2);rectLight.position.set(0, 5, 0);rectLight.lookAt(0, 0, 0);scene.add(rectLight);
// Helperconst helper = new RectAreaLightHelper(rectLight);rectLight.add(helper);
// Note: Only works with MeshStandardMaterial and MeshPhysicalMaterial// Does not cast shadows natively

Shadow Setup

Enable Shadows

javascript
// 1. Enable on rendererrenderer.shadowMap.enabled = true;renderer.shadowMap.type = THREE.PCFSoftShadowMap;
// Shadow map types:// THREE.BasicShadowMap - fastest, low quality// THREE.PCFShadowMap - default, filtered// THREE.PCFSoftShadowMap - softer edges// THREE.VSMShadowMap - variance shadow map
// 2. Enable on lightlight.castShadow = true;
// 3. Enable on objectsmesh.castShadow = true;mesh.receiveShadow = true;
// Ground planefloor.receiveShadow = true;floor.castShadow = false; // Usually false for floors

Optimizing Shadows

javascript
// Tight shadow camera frustumconst d = 10;dirLight.shadow.camera.left = -d;dirLight.shadow.camera.right = d;dirLight.shadow.camera.top = d;dirLight.shadow.camera.bottom = -d;dirLight.shadow.camera.near = 0.5;dirLight.shadow.camera.far = 30;
// Fix shadow acnedirLight.shadow.bias = -0.0001; // Depth biasdirLight.shadow.normalBias = 0.02; // Bias along normal
// Shadow map size (balance quality vs performance)// 512 - low quality// 1024 - medium quality// 2048 - high quality// 4096 - very high quality (expensive)

Contact Shadows (Fake, Fast)

javascript
import { ContactShadows } from "three/examples/jsm/objects/ContactShadows.js";
const contactShadows = new ContactShadows({  resolution: 512,  blur: 2,  opacity: 0.5,  scale: 10,  position: [0, 0, 0],});scene.add(contactShadows);

Light Helpers

javascript
import { RectAreaLightHelper } from "three/examples/jsm/helpers/RectAreaLightHelper.js";
// DirectionalLight helperconst dirHelper = new THREE.DirectionalLightHelper(dirLight, 5);scene.add(dirHelper);
// PointLight helperconst pointHelper = new THREE.PointLightHelper(pointLight, 1);scene.add(pointHelper);
// SpotLight helperconst spotHelper = new THREE.SpotLightHelper(spotLight);scene.add(spotHelper);
// Hemisphere helperconst hemiHelper = new THREE.HemisphereLightHelper(hemiLight, 5);scene.add(hemiHelper);
// RectAreaLight helperconst rectHelper = new RectAreaLightHelper(rectLight);rectLight.add(rectHelper);
// Update helpers when light changesdirHelper.update();spotHelper.update();

Environment Lighting (IBL)

Image-Based Lighting using HDR environment maps.

javascript
import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader.js";
const rgbeLoader = new RGBELoader();rgbeLoader.load("environment.hdr", (texture) => {  texture.mapping = THREE.EquirectangularReflectionMapping;
  // Set as scene environment (affects all PBR materials)  scene.environment = texture;
  // Optional: also use as background  scene.background = texture;  scene.backgroundBlurriness = 0; // 0-1, blur the background  scene.backgroundIntensity = 1;});
// PMREMGenerator for better reflectionsconst pmremGenerator = new THREE.PMREMGenerator(renderer);pmremGenerator.compileEquirectangularShader();
rgbeLoader.load("environment.hdr", (texture) => {  const envMap = pmremGenerator.fromEquirectangular(texture).texture;  scene.environment = envMap;  texture.dispose();  pmremGenerator.dispose();});

Cube Texture Environment

javascript
const cubeLoader = new THREE.CubeTextureLoader();const envMap = cubeLoader.load([  "px.jpg",  "nx.jpg",  "py.jpg",  "ny.jpg",  "pz.jpg",  "nz.jpg",]);
scene.environment = envMap;scene.background = envMap;

Light Probes (Advanced)

Capture lighting from a point in space for ambient lighting.

javascript
import { LightProbeGenerator } from "three/examples/jsm/lights/LightProbeGenerator.js";
// Generate from cube textureconst lightProbe = new THREE.LightProbe();scene.add(lightProbe);
lightProbe.copy(LightProbeGenerator.fromCubeTexture(cubeTexture));
// Or from render targetconst cubeCamera = new THREE.CubeCamera(  0.1,  100,  new THREE.WebGLCubeRenderTarget(256),);cubeCamera.update(renderer, scene);lightProbe.copy(  LightProbeGenerator.fromCubeRenderTarget(renderer, cubeCamera.renderTarget),);

Common Lighting Setups

Three-Point Lighting

javascript
// Key light (main light)const keyLight = new THREE.DirectionalLight(0xffffff, 1);keyLight.position.set(5, 5, 5);scene.add(keyLight);
// Fill light (softer, opposite side)const fillLight = new THREE.DirectionalLight(0xffffff, 0.5);fillLight.position.set(-5, 3, 5);scene.add(fillLight);
// Back light (rim lighting)const backLight = new THREE.DirectionalLight(0xffffff, 0.3);backLight.position.set(0, 5, -5);scene.add(backLight);
// Ambient fillconst ambient = new THREE.AmbientLight(0x404040, 0.3);scene.add(ambient);

Outdoor Daylight

javascript
// Sunconst sun = new THREE.DirectionalLight(0xffffcc, 1.5);sun.position.set(50, 100, 50);sun.castShadow = true;scene.add(sun);
// Sky ambientconst hemi = new THREE.HemisphereLight(0x87ceeb, 0x8b4513, 0.6);scene.add(hemi);

Indoor Studio

javascript
// Multiple area lightsRectAreaLightUniformsLib.init();
const light1 = new THREE.RectAreaLight(0xffffff, 5, 2, 2);light1.position.set(3, 3, 3);light1.lookAt(0, 0, 0);scene.add(light1);
const light2 = new THREE.RectAreaLight(0xffffff, 3, 2, 2);light2.position.set(-3, 3, 3);light2.lookAt(0, 0, 0);scene.add(light2);
// Ambient fillconst ambient = new THREE.AmbientLight(0x404040, 0.2);scene.add(ambient);

Light Animation

javascript
const clock = new THREE.Clock();
function animate() {  const time = clock.getElapsedTime();
  // Orbit light around scene  light.position.x = Math.cos(time) * 5;  light.position.z = Math.sin(time) * 5;
  // Pulsing intensity  light.intensity = 1 + Math.sin(time * 2) * 0.5;
  // Color cycling  light.color.setHSL((time * 0.1) % 1, 1, 0.5);
  // Update helpers if using  lightHelper.update();}

Performance Tips

  1. Limit light count: Each light adds shader complexity
  2. Use baked lighting: For static scenes, bake to textures
  3. Smaller shadow maps: 512-1024 often sufficient
  4. Tight shadow frustums: Only cover needed area
  5. Disable unused shadows: Not all lights need shadows
  6. Use light layers: Exclude objects from certain lights
javascript
// Light layerslight.layers.set(1); // Light only affects layer 1mesh.layers.enable(1); // Mesh is on layer 1otherMesh.layers.disable(1); // Other mesh not affected
// Selective shadowsmesh.castShadow = true;mesh.receiveShadow = true;decorMesh.castShadow = false; // Small objects often don't need to cast

See Also

  • threejs-materials - Material light response
  • threejs-textures - Lightmaps and environment maps
  • threejs-postprocessing - Bloom and other light effects

Source and attribution

Source:calesthio/OpenMontagein.claude/skills/threejs-lightingat commit9327439

License: No license

Content belongs to its original authors. SourceWeft indexes it from a public repository.

Report or request removal