Back to Other Skills

threejs-lighting

three.js3D graphicslightingwebglshadowsPBRIBLfrontend development
2.4k🕒 2026-01-19Source ↗

Install this skill

npx skills add cloudai-x/threejs-skills

Works across Claude Code, Cursor, Codex, Copilot & Antigravity

Three.js lighting provides the foundation for visual depth in 3D scenes by simulating light emission, color interaction, and shadow casting. The library distinguishes between base global illumination, such as Ambient and Hemisphere lights, and specific directional or positional sources like Point, Spot, and RectArea lights. Each type requires specific configuration for intensity, decay, and shadow resolution. Integrating these lights involves placing them within the scene graph and, for shadow-casting sources, configuring orthographic or perspective shadow cameras. Managing these properties accurately determines whether a scene feels flat or gains physical realism through light falloff and soft-edge projection. This skill focus covers the implementation of light-specific parameters to achieve varied artistic results, from sharp, high-contrast silhouettes to soft, area-based atmospheric diffusion, while maintaining performance standards by optimizing shadow map sizes and bias settings.

When to Use This Skill

  • Replicating daylight with parallel rays using DirectionalLight
  • Creating flickering torch or bulb effects with PointLight
  • Simulating soft window or screen illumination with RectAreaLight
  • Highlighting specific objects on a stage with controlled SpotLight cones

How to Invoke This Skill

Example prompts that trigger this skill in Claude Code, Cursor, or Antigravity:

  • how to add shadows to my Three.js scene
  • configure a spotlight in three.js with soft edges
  • my shadows have artifacts or look grainy in Three.js
  • how to use point lights for lamp effects
  • best way to simulate sun light in three.js
  • setup rectarealight with helper

Pro Tips

  • 💡**Prioritize Performance**: Use `AmbientLight` and `HemisphereLight` for general illumination before adding costly shadow-casting lights. Limit shadow map resolutions and only enable shadows on essential objects to maintain high frame rates.
  • 💡**Experiment with IBL**: Leverage `THREE.CubeTextureLoader` or `THREE.PMREMGenerator` with HDRIs to achieve highly realistic environment reflections and diffuse lighting for PBR materials, significantly enhancing visual quality with minimal performance impact compared to many individual lights.
  • 💡**Group Lights for Control**: Organize related lights into `THREE.Group` objects to easily manage their visibility, position, and intensity as a unit, which is especially useful for scene sections, light fixtures, or complex lighting setups.

What this skill does

  • Simulates physical light decay using intensity and distance parameters
  • Configures orthographic or perspective shadow cameras for precise light occlusion
  • Blends sky and ground colors for atmospheric environmental lighting
  • Projects restricted cone-based beams using spot light geometry
  • Applies shadow mapping with bias adjustments to prevent artifacts
  • Visualizes light positioning and range using helper classes

When not to use it

  • Real-time scenarios requiring high-performance shadows on low-end mobile devices
  • Environments where full global illumination and light bounce calculation are mandatory (use raytracing alternatives instead)

Example workflow

  1. Initialize the scene and camera setup
  2. Instantiate the desired light object with specific color and intensity
  3. Add the light and its target to the scene graph
  4. Enable castShadow on the light and target meshes
  5. Configure shadow map dimensions and bias for quality
  6. Attach a CameraHelper to debug the shadow volume range

Prerequisites

  • Basic knowledge of the Three.js Scene graph
  • Understanding of coordinate systems and object positioning

Pitfalls & limitations

  • !Ignoring shadow bias often leads to shadow acne or self-shadowing artifacts
  • !Setting shadow maps too high causes significant frame rate drops
  • !Ambient and Hemisphere lights do not support shadow casting by design

FAQ

Why is my shadow not appearing?
Ensure castShadow is enabled on both the light and the mesh. Also, confirm the shadow camera is wide enough to encompass your objects.
Can I have shadows with RectAreaLight?
No, RectAreaLight does not support shadows natively in standard Three.js; it requires custom shader solutions or lightmaps.
What is the purpose of the shadow bias?
Bias shifts the shadow map slightly to prevent 'shadow acne', which occurs when a surface incorrectly shadows itself due to floating-point precision issues.
How do I make a light follow an object?
Add the light as a child of the object in the scene graph or update the light's target position manually in the animation loop.

How it compares

While a generic prompt might suggest basic light addition, this skill emphasizes the technical configuration of shadow cameras, bias tuning, and helper integration required for production-ready lighting.

Source & trust

2.4k stars🕒 Updated 2026-01-19
📄 Full skill instructions — original source: cloudai-x/threejs-skills
# Three.js Lighting

## Quick Start

import * as THREE from "three";

// Basic lighting setup
const 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

| Light | Description | Shadow Support | Cost |
| ---------------- | ---------------------- | -------------- | -------- |
| AmbientLight | Uniform everywhere | No | Very Low |
| HemisphereLight | Sky/ground gradient | No | Very Low |
| DirectionalLight | Parallel rays (sun) | Yes | Low |
| PointLight | Omnidirectional (bulb) | Yes | Medium |
| SpotLight | Cone-shaped | Yes | Medium |
| RectAreaLight | Area light (window) | No\* | High |

\*RectAreaLight shadows require custom solutions

## AmbientLight

Illuminates all objects equally. No direction, no shadows.

// AmbientLight(color, intensity)
const ambient = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(ambient);

// Modify at runtime
ambient.color.set(0xffffcc);
ambient.intensity = 0.3;


## HemisphereLight

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

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

// Properties
hemi.color; // Sky color
hemi.groundColor; // Ground color
hemi.intensity;


## DirectionalLight

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

// 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

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 softness
dirLight.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 camera
const helper = new THREE.CameraHelper(dirLight.shadow.camera);
scene.add(helper);


## PointLight

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

// PointLight(color, intensity, distance, decay)
const pointLight = new THREE.PointLight(0xffffff, 1, 100, 2);
pointLight.position.set(0, 5, 0);
scene.add(pointLight);

// Properties
pointLight.distance; // Maximum range (0 = infinite)
pointLight.decay; // Light falloff (physically correct = 2)


### PointLight Shadows

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.

// 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);

// Properties
spotLight.angle; // Cone angle (radians, max Math.PI/2)
spotLight.penumbra; // Soft edge (0-1)
spotLight.distance; // Range
spotLight.decay; // Falloff


### SpotLight Shadows

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.

import { RectAreaLightHelper } from "three/examples/jsm/helpers/RectAreaLightHelper.js";
import { RectAreaLightUniformsLib } from "three/examples/jsm/lights/RectAreaLightUniformsLib.js";

// Must initialize uniforms first
RectAreaLightUniformsLib.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);

// Helper
const helper = new RectAreaLightHelper(rectLight);
rectLight.add(helper);

// Note: Only works with MeshStandardMaterial and MeshPhysicalMaterial
// Does not cast shadows natively


## Shadow Setup

### Enable Shadows

// 1. Enable on renderer
renderer.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 light
light.castShadow = true;

// 3. Enable on objects
mesh.castShadow = true;
mesh.receiveShadow = true;

// Ground plane
floor.receiveShadow = true;
floor.castShadow = false; // Usually false for floors


### Optimizing Shadows

// Tight shadow camera frustum
const 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 acne
dirLight.shadow.bias = -0.0001; // Depth bias
dirLight.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)

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

import { RectAreaLightHelper } from "three/examples/jsm/helpers/RectAreaLightHelper.js";

// DirectionalLight helper
const dirHelper = new THREE.DirectionalLightHelper(dirLight, 5);
scene.add(dirHelper);

// PointLight helper
const pointHelper = new THREE.PointLightHelper(pointLight, 1);
scene.add(pointHelper);

// SpotLight helper
const spotHelper = new THREE.SpotLightHelper(spotLight);
scene.add(spotHelper);

// Hemisphere helper
const hemiHelper = new THREE.HemisphereLightHelper(hemiLight, 5);
scene.add(hemiHelper);

// RectAreaLight helper
const rectHelper = new RectAreaLightHelper(rectLight);
rectLight.add(rectHelper);

// Update helpers when light changes
dirHelper.update();
spotHelper.update();


## Environment Lighting (IBL)

Image-Based Lighting using HDR environment maps.

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 reflections
const 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

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.

import { LightProbeGenerator } from "three/examples/jsm/lights/LightProbeGenerator.js";

// Generate from cube texture
const lightProbe = new THREE.LightProbe();
scene.add(lightProbe);

lightProbe.copy(LightProbeGenerator.fromCubeTexture(cubeTexture));

// Or from render target
const 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

// 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 fill
const ambient = new THREE.AmbientLight(0x404040, 0.3);
scene.add(ambient);


### Outdoor Daylight

// Sun
const sun = new THREE.DirectionalLight(0xffffcc, 1.5);
sun.position.set(50, 100, 50);
sun.castShadow = true;
scene.add(sun);

// Sky ambient
const hemi = new THREE.HemisphereLight(0x87ceeb, 0x8b4513, 0.6);
scene.add(hemi);


### Indoor Studio

// Multiple area lights
RectAreaLightUniformsLib.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 fill
const ambient = new THREE.AmbientLight(0x404040, 0.2);
scene.add(ambient);


## Light Animation

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

// Light layers
light.layers.set(1); // Light only affects layer 1
mesh.layers.enable(1); // Mesh is on layer 1
otherMesh.layers.disable(1); // Other mesh not affected

// Selective shadows
mesh.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

How to Use This Skill Unit

Option A: Project-Specific (Recommended)

  1. Click "Download" above
  2. In your project, create the directory: .agent/skills/threejs-lighting/
  3. Save the file as SKILL.md
  4. The agent will automatically discover the skill based on its description.

Option B: Global Installation (All Agents)

Save the file to these locations to make it available across all projects:

  • Claude Code: ~/.claude/skills/cloudai-x/threejs-skills/threejs-lighting/SKILL.md
  • Cursor: ~/.cursor/skills/cloudai-x/threejs-skills/threejs-lighting/SKILL.md
  • Antigravity: ~/.gemini/antigravity/skills/cloudai-x/threejs-skills/threejs-lighting/SKILL.md

🚀 Install with CLI:
npx skills add cloudai-x/threejs-skills

Read the Master Guide: Mastering Agent Skills

Recommended Rules

View more rules

Recommended Workflows

View more workflows

Recommended MCP Servers

View more MCP servers

Take It Further

Maximize your productivity with these powerful resources

📋

Define Your Standards

Set up coding standards to ensure this workflow produces consistent, high-quality results.

Browse Rules Library
📖

Master Workflows

Learn how to create custom workflows, use Turbo Mode, and build your automation library.

Complete Guide

How to use this Skill in Claude Code & Cursor

For Claude Code (CLI)

To use this skill in Claude Code, copy the rule content into your project's custom instructions or follow our Add-Skill CLI guide. This ensures Claude follows your standards during every code generation.

For Cursor & Windsurf

For Cursor or Windsurf, individual skills are best used in the "Rules for AI" section. This specific unit helps the agent avoid other skills issues, leading to cleaner, more efficient code.

Why the skill format matters: the standardized Agent Skills format lets your AI agent load detailed instructions only when they are relevant, keeping your prompt clean while improving results.

Source & attribution

This skill is categorized under Other Skills and is published by CloudAI-X, maintained in cloudai-x/threejs-skills.

← Browse All Agent Skills
Sponsored AI assistant. Recommendations may be paid.