# Mastering Three.js Lighting: Illuminating Your 3D World

Welcome back! 👋 In my previous posts, I covered [Three.js basics](https://blog.iamdipankarpaul.com/my-first-threejs-scene-building-a-3d-world-in-the-browser), [geometries](https://blog.iamdipankarpaul.com/exploring-threejs-geometries-the-building-blocks-of-3d) and [materials](https://claude.ai/chat/e9ad9ae7-a4d2-4a7b-928b-b12582289e7b#). Today, I'm diving into **lighting** - one of the most important aspects of creating realistic 3D scenes.

Good lighting can make or break your 3D scene. It's the difference between a flat, lifeless render and a vibrant, realistic world. Let's explore how to light our scenes like a professional photographer!

## What is Lighting in Three.js?

Lighting in Three.js simulates how light behaves in the real world. Different light types mimic different real-world light sources:

* **Sun** (DirectionalLight)
    
* **Light bulbs** (PointLight)
    
* **Flashlights** (SpotLight)
    
* **Sky lighting** (HemisphereLight)
    
* **Overall brightness** (AmbientLight)
    

Understanding when and how to use each light type is key to creating the mood and atmosphere you want.

## The Photography Analogy

Think of Three.js lighting is like setting up a photography or film studio:

* **Key Light** (main light source) - DirectionalLight or SpotLight
    
* **Fill Light** (softens shadows) - AmbientLight or HemisphereLight
    
* **Rim/Back Light** (separates subject from background) - PointLight or SpotLight
    
* **Practical Lights** (visible light sources) - PointLight with visible geometry
    

Just like in photography, you rarely use just one light. The magic happens when you combine multiple lights!

## Project Setup

Here's our HTML structure with controls:

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Three.js Lighting Guide</title>
    <style>
        body { 
            margin: 0; 
            overflow: hidden;
            font-family: Arial, sans-serif;
        }
        canvas { 
            display: block; 
        }
        #controls {
            position: absolute;
            top: 20px;
            right: 20px;
            color: white;
            background: rgba(0, 0, 0, 0.85);
            padding: 20px;
            border-radius: 8px;
            font-size: 13px;
            max-width: 280px;
            max-height: 90vh;
            overflow-y: auto;
        }
        #controls h3 {
            margin-top: 0;
            color: #4ecdc4;
            font-size: 16px;
        }
        .light-section {
            margin: 15px 0;
            padding: 10px;
            background: rgba(255, 255, 255, 0.05);
            border-radius: 4px;
        }
        .light-section h4 {
            margin: 0 0 10px 0;
            color: #ffe66d;
            font-size: 14px;
        }
        .control-group {
            margin: 8px 0;
        }
        .control-group label {
            display: block;
            margin-bottom: 3px;
            color: #aaa;
            font-size: 11px;
        }
        input[type="range"] {
            width: 100%;
        }
        input[type="checkbox"] {
            margin-right: 5px;
        }
        .toggle-label {
            display: flex;
            align-items: center;
            cursor: pointer;
        }
        #info {
            position: absolute;
            top: 20px;
            left: 20px;
            color: white;
            background: rgba(0, 0, 0, 0.85);
            padding: 15px;
            border-radius: 8px;
            font-size: 13px;
            max-width: 250px;
        }
        #info h3 {
            margin-top: 0;
            color: #4ecdc4;
        }
    </style>
</head>
<body>
    <canvas id="canvas"></canvas>
    
    <div id="info">
        <h3>Lighting Demo</h3>
        <p>Toggle different lights to see how they affect the scene. Light helpers show light positions.</p>
    </div>
    
    <div id="controls">
        <h3>Light Controls</h3>
        
        <div class="light-section">
            <h4>Ambient Light</h4>
            <div class="control-group">
                <label class="toggle-label">
                    <input type="checkbox" id="ambientToggle" checked>
                    Enable
                </label>
            </div>
            <div class="control-group">
                <label>Intensity: <span id="ambientIntensity">0.3</span></label>
                <input type="range" id="ambientSlider" min="0" max="1" step="0.1" value="0.3">
            </div>
        </div>
        
        <div class="light-section">
            <h4>Directional Light</h4>
            <div class="control-group">
                <label class="toggle-label">
                    <input type="checkbox" id="directionalToggle" checked>
                    Enable
                </label>
            </div>
            <div class="control-group">
                <label>Intensity: <span id="directionalIntensity">1.0</span></label>
                <input type="range" id="directionalSlider" min="0" max="2" step="0.1" value="1">
            </div>
        </div>
        
        <div class="light-section">
            <h4>Point Light</h4>
            <div class="control-group">
                <label class="toggle-label">
                    <input type="checkbox" id="pointToggle" checked>
                    Enable
                </label>
            </div>
            <div class="control-group">
                <label>Intensity: <span id="pointIntensity">1.0</span></label>
                <input type="range" id="pointSlider" min="0" max="2" step="0.1" value="1">
            </div>
        </div>
        
        <div class="light-section">
            <h4>Spot Light</h4>
            <div class="control-group">
                <label class="toggle-label">
                    <input type="checkbox" id="spotToggle" checked>
                    Enable
                </label>
            </div>
            <div class="control-group">
                <label>Intensity: <span id="spotIntensity">1.0</span></label>
                <input type="range" id="spotSlider" min="0" max="2" step="0.1" value="1">
            </div>
            <div class="control-group">
                <label>Angle: <span id="spotAngle">0.5</span></label>
                <input type="range" id="spotAngleSlider" min="0" max="1.57" step="0.1" value="0.5">
            </div>
        </div>
        
        <div class="light-section">
            <h4>Hemisphere Light</h4>
            <div class="control-group">
                <label class="toggle-label">
                    <input type="checkbox" id="hemisphereToggle">
                    Enable
                </label>
            </div>
            <div class="control-group">
                <label>Intensity: <span id="hemisphereIntensity">0.5</span></label>
                <input type="range" id="hemisphereSlider" min="0" max="1" step="0.1" value="0.5">
            </div>
        </div>
        
        <div class="light-section">
            <h4>Helpers</h4>
            <div class="control-group">
                <label class="toggle-label">
                    <input type="checkbox" id="helpersToggle" checked>
                    Show Light Helpers
                </label>
            </div>
        </div>
    </div>
    
    <script type="module" src="/src/lighting.js"></script>
</body>
</html>
```

## Building Our Lighting Scene

Let's create a scene that demonstrates most used light types!

### Step 1: Scene and Camera Setup

```javascript
import * as THREE from "three";

const canvas = document.getElementById("canvas");

// Scene setup
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x0a0a0a); // Very dark background

// Camera setup
const camera = new THREE.PerspectiveCamera(
    75,
    window.innerWidth / window.innerHeight,
    0.1,
    1000
);
camera.position.set(0, 8, 20);
camera.lookAt(0, 0, 0);
```

### Step 2: Creating Scene Objects

Let's create a simple scene with objects that will show off the lighting:

```javascript
// Create a ground plane
const groundGeometry = new THREE.PlaneGeometry(50, 50);
const groundMaterial = new THREE.MeshStandardMaterial({
  color: 0x333333,
  roughness: 0.8,
  metalness: 0.2,
});
const ground = new THREE.Mesh(groundGeometry, groundMaterial);
ground.rotation.x = -Math.PI / 2; // Rotate to be horizontal
ground.position.y = -2;
scene.add(ground);

// Create center sphere
const sphereGeometry = new THREE.SphereGeometry(2, 64, 64);
const sphereMaterial = new THREE.MeshStandardMaterial({
  color: 0xffffff,
  roughness: 0.3,
  metalness: 0.7,
});
const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
sphere.position.set(0, 0, 0);
scene.add(sphere);

// Create surrounding cubes to show light distribution
const cubeGeometry = new THREE.BoxGeometry(1.5, 1.5, 1.5);
const cubeMaterial = new THREE.MeshStandardMaterial({
  color: 0x4ecdc4,
  roughness: 0.5,
  metalness: 0.3,
});

const cubes = [];
const cubePositions = [
  [-6, -0.5, 0], // Left
  [6, -0.5, 0], // Right
  [0, -0.5, 6], // Front
];

cubePositions.forEach((pos) => {
  const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
  cube.position.set(pos[0], pos[1], pos[2]);
  cubes.push(cube);
  scene.add(cube);
});

// Add a torus for variety
const torusGeometry = new THREE.TorusGeometry(1.5, 0.5, 16, 100);
const torusMaterial = new THREE.MeshStandardMaterial({
  color: 0xff6b6b,
  roughness: 0.4,
  metalness: 0.6,
});
const torus = new THREE.Mesh(torusGeometry, torusMaterial);
torus.position.set(0, 5, 0);
scene.add(torus);
```

### Step 3: Creating All Light Types

Now let's create each of the six light types with their helpers!

```javascript
// ============================================
// 1. AMBIENT LIGHT
// Provides overall base illumination, no direction
// Does not cast shadows
// Use case: Base lighting so nothing is completely black.
// Never use alone, combine with directional lights.
// Performance: Very cheap, no calculations needed.

// No helper for ambient light (it's everywhere equally)
// ============================================
const ambientLight = new THREE.AmbientLight(
  0xffffff, // White light
  0.3 // Low intensity
);
scene.add(ambientLight);

// ============================================
// 2. DIRECTIONAL LIGHT
// Parallel rays like sunlight, illuminates from a direction
// Use case: Outdoor scenes (sun/moon), main key light.
// All rays are parallel regardless of distance.
// Performance: Cheap, good for primary light source.
// ============================================
const directionalLight = new THREE.DirectionalLight(
  0xffffff, // White light
  1.0 // Full intensity
);
directionalLight.position.set(5, 10, 5);
scene.add(directionalLight);

// Helper to visualize light direction
const directionalHelper = new THREE.DirectionalLightHelper(
  directionalLight,
  2 // Helper size
);
scene.add(directionalHelper);

// ============================================
// 3. POINT LIGHT
// Radiates light in all directions from a point (like a light bulb)
// Use case: Light bulbs, lamps, candles, explosions.
// Light diminishes with distance (uses distance and decay).
// Performance: Medium cost, use sparingly for many lights.
// ============================================
const pointLight = new THREE.PointLight(
  0xff00ff, // Magenta color
  1.0, // Intensity
  50, // Distance (light fades to 0 at this distance)
  2 // Decay (how fast light fades, 2 = realistic)
);
pointLight.position.set(-8, 3, 0);
scene.add(pointLight);

// Helper to visualize light position and range
const pointHelper = new THREE.PointLightHelper(
  pointLight,
  0.5 // Helper sphere size
);
scene.add(pointHelper);

// ============================================
// 4. SPOT LIGHT
// Cone of light from a point (like a flashlight or stage light)
// Use case: Flashlights, stage spotlights, car headlights.
// Creates dramatic focused lighting with soft edges.
// Performance: Most expensive, use carefully.
// ============================================
const spotLight = new THREE.SpotLight(
  0x00ffff, // Cyan color
  1.0, // Intensity
  30, // Distance
  Math.PI / 10, // Angle (cone width in radians)
  0.5, // Penumbra (softness of edge, 0-1)
  2 // Decay
);
spotLight.position.set(-6, 10, 0);
spotLight.target.position.set(0, 0, 0); // Point at center
scene.add(spotLight);
scene.add(spotLight.target); // Target must be in scene

// Helper to visualize cone
const spotHelper = new THREE.SpotLightHelper(spotLight);
scene.add(spotHelper);

// ============================================
// 5. HEMISPHERE LIGHT
// Sky/ground ambient lighting (different colors from top/bottom)
// Use case: Outdoor scenes with sky lighting, subtle ambient variation.
// Creates natural-looking ambient from above (sky) and below (ground bounce).
// Performance: Cheap, great alternative to plain ambient light.
// ============================================
const hemisphereLight = new THREE.HemisphereLight(
  0x0066ff, // Sky color (blue)
  0xff6600, // Ground color (orange)
  0.5 // Intensity
);
hemisphereLight.position.set(0, 10, 0);
scene.add(hemisphereLight);

// Helper shows sky and ground colors
const hemisphereHelper = new THREE.HemisphereLightHelper(
  hemisphereLight,
  2 // Helper size
);
scene.add(hemisphereHelper);

// Store references for toggling
const helpers = {
  directional: directionalHelper,
  point: pointHelper,
  spot: spotHelper,
  hemisphere: hemisphereHelper,
};

// Initially hide some lights to avoid overwhelming the scene
hemisphereLight.visible = false;
hemisphereHelper.visible = false;
```

### Step 4: Interactive Controls

Let's wire up all the controls to adjust lights in real-time:

```javascript
// Ambient Light Controls
const ambientToggle = document.getElementById("ambientToggle");
const ambientSlider = document.getElementById("ambientSlider");
const ambientIntensityDisplay = document.getElementById("ambientIntensity");

ambientToggle.addEventListener("change", (e) => {
  ambientLight.visible = e.target.checked;
});

ambientSlider.addEventListener("input", (e) => {
  const value = parseFloat(e.target.value);
  ambientLight.intensity = value;
  ambientIntensityDisplay.textContent = value.toFixed(1);
});

// Directional Light Controls
const directionalToggle = document.getElementById("directionalToggle");
const directionalSlider = document.getElementById("directionalSlider");
const directionalIntensityDisplay = document.getElementById(
  "directionalIntensity"
);

directionalToggle.addEventListener("change", (e) => {
  directionalLight.visible = e.target.checked;
  directionalHelper.visible = e.target.checked;
});

directionalSlider.addEventListener("input", (e) => {
  const value = parseFloat(e.target.value);
  directionalLight.intensity = value;
  directionalIntensityDisplay.textContent = value.toFixed(1);
});

// Point Light Controls
const pointToggle = document.getElementById("pointToggle");
const pointSlider = document.getElementById("pointSlider");
const pointIntensityDisplay = document.getElementById("pointIntensity");

pointToggle.addEventListener("change", (e) => {
  pointLight.visible = e.target.checked;
  pointHelper.visible = e.target.checked;
});

pointSlider.addEventListener("input", (e) => {
  const value = parseFloat(e.target.value);
  pointLight.intensity = value;
  pointIntensityDisplay.textContent = value.toFixed(1);
});

// Spot Light Controls
const spotToggle = document.getElementById("spotToggle");
const spotSlider = document.getElementById("spotSlider");
const spotAngleSlider = document.getElementById("spotAngleSlider");
const spotIntensityDisplay = document.getElementById("spotIntensity");
const spotAngleDisplay = document.getElementById("spotAngle");

spotToggle.addEventListener("change", (e) => {
  spotLight.visible = e.target.checked;
  spotHelper.visible = e.target.checked;
});

spotSlider.addEventListener("input", (e) => {
  const value = parseFloat(e.target.value);
  spotLight.intensity = value;
  spotIntensityDisplay.textContent = value.toFixed(1);
});

spotAngleSlider.addEventListener("input", (e) => {
  const value = parseFloat(e.target.value);
  spotLight.angle = value;
  spotAngleDisplay.textContent = value.toFixed(2);
});

// Hemisphere Light Controls
const hemisphereToggle = document.getElementById("hemisphereToggle");
const hemisphereSlider = document.getElementById("hemisphereSlider");
const hemisphereIntensityDisplay = document.getElementById(
  "hemisphereIntensity"
);

hemisphereToggle.addEventListener("change", (e) => {
  hemisphereLight.visible = e.target.checked;
  hemisphereHelper.visible = e.target.checked;
});

hemisphereSlider.addEventListener("input", (e) => {
  const value = parseFloat(e.target.value);
  hemisphereLight.intensity = value;
  hemisphereIntensityDisplay.textContent = value.toFixed(1);
});

// Helpers Toggle
const helpersToggle = document.getElementById("helpersToggle");
helpersToggle.addEventListener("change", (e) => {
  const visible = e.target.checked;
  Object.values(helpers).forEach((helper) => {
    // Only show helper if its light is also visible
    const lightVisible = helper.light ? helper.light.visible : true;
    helper.visible = visible && lightVisible;
  });
});
```

### Step 5: Renderer and Animation

```javascript
// Renderer setup
const renderer = new THREE.WebGLRenderer({
  canvas: canvas,
  antialias: true,
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);

// Animation loop
function animate() {
  requestAnimationFrame(animate);

  const time = Date.now() * 0.001;

  // Rotate center sphere
  sphere.rotation.y = time * 0.3;

  // Rotate torus
  torus.rotation.x = time * 0.5;
  torus.rotation.y = time * 0.05;

  // Gently bob cubes up and down
  cubes.forEach((cube, index) => {
    cube.position.y = -0.5 + Math.sin(time + index) * 0.3;
    cube.rotation.y = time * 0.5;
  });

  // Animate point light in a circle
  pointLight.position.x = Math.cos(time * 0.5) * 8;
  pointLight.position.z = Math.sin(time * 0.5) * 8;

  // Update helpers
  if (spotHelper.visible) spotHelper.update();
  if (directionalHelper.visible) directionalHelper.update();

  renderer.render(scene, camera);
}

animate();

// Handle window resize
window.addEventListener("resize", () => {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
});
```

## Understanding Light Properties

### Common Properties (Most Lights)

**Colour** - The colour of the light

```javascript
light.color = new THREE.Color(0xff0000); // Red light
```

**intensity** - How bright the light is

```javascript
light.intensity = 1.5; // 150% brightness
```

### Distance-Based Properties (Point & Spot Lights)

**distance** - Maximum range of the light (0 = infinite)

```javascript
pointLight.distance = 50; // Light fades to 0 at 50 units
```

**decay** - How quickly light diminishes with distance

```javascript
pointLight.decay = 2; // Physically accurate (inverse square law)
// 1 = linear falloff
// 2 = realistic falloff (default)
```

### Spot Light Specific

**angle** - Width of the light cone (in radians)

```javascript
spotLight.angle = Math.PI / 6; // 30 degrees
```

**penumbra** - Softness of the cone edge (0-1)

```javascript
spotLight.penumbra = 0.5; // 50% soft edge
// 0 = hard edge
// 1 = very soft edge
```

**target** - What the spotlight points at

```javascript
spotLight.target.position.set(0, 0, 0);
scene.add(spotLight.target); // Must add target to scene!
```

### Hemisphere Light Specific

**groundColor** - Colour of light from below

```javascript
hemisphereLight.groundColor = new THREE.Color(0x080820);
```

## When to Use Each Light Type

### AmbientLight

**Performance:** ⚡⚡⚡⚡⚡ (Cheapest)  
**When to use:**

* Base lighting, so objects aren't completely black
    
* Fill light to soften harsh shadows
    
* Quick prototyping before adding complex lighting
    

**Best practices:**

* Keep intensity low (0.2-0.4)
    
* Never use as the only light source
    
* Combine with directional lights
    

**Real-world equivalent:** Overcast day, diffused light everywhere

### DirectionalLight

**Performance:** ⚡⚡⚡⚡ (Very Cheap)  
**When to use:**

* Outdoor scenes (sun or moon)
    
* Main key light in any scene
    
* When you need parallel light rays
    

**Best practices:**

* Position far from scene center
    
* Use as primary light source
    
* Great for casting consistent shadows
    

**Real-world equivalent:** Sunlight, moonlight

### PointLight

**Performance:** ⚡⚡⚡ (Medium)  
**When to use:**

* Light bulbs, lamps, candles
    
* Explosions or fire effects
    
* Small localized light sources
    

**Best practices:**

* Set appropriate distance and decay
    
* Don't use too many (expensive with many)
    
* Great for accent lighting
    

**Real-world equivalent:** Light bulb, candle, torch

### SpotLight

**Performance:** ⚡⚡ (Expensive)  
**When to use:**

* Flashlights, car headlights
    
* Stage lighting, theatrical effects
    
* Drawing attention to specific objects
    

**Best practices:**

* Use sparingly (most expensive)
    
* Adjust angle and penumbra for desired effect
    
* Remember to add target to scene
    

**Real-world equivalent:** Flashlight, stage spotlight, car headlight

### HemisphereLight

**Performance:** ⚡⚡⚡⚡ (Cheap)  
**When to use:**

* Outdoor scenes with sky
    
* Natural-looking ambient lighting
    
* When you want colour variation (sky vs ground)
    

**Best practices:**

* Better than plain Ambient Light for realism
    
* Use sky and ground colours that make sense
    
* Great for outdoor environments
    

**Real-world equivalent:** Natural sky lighting with ground bounce

### RectAreaLight

**Performance:** ⚡ (Most Expensive)  
**When to use:**

* Windows or doors letting in light
    
* TV screens, monitors, LED panels
    
* Soft box photography lighting
    
* When you need realistic area lighting
    

**Best practices:**

* Only works with Standard/Physical materials!
    
* Use very sparingly (heavy performance cost)
    
* Great for hero objects or key scenes
    

**Real-world equivalent:** Window, LED panel, soft box light

## Performance Tips and Light Combinations

### Performance Hierarchy (Cheapest to Most Expensive)

1. **AmbientLight / HemisphereLight** - No calculations
    
2. **DirectionalLight** - Simple directional calculations
    
3. **PointLight** - Distance-based calculations
    
4. **SpotLight** - Cone + distance calculations
    
5. **RectAreaLight** - Complex area calculations
    

### Recommended Light Combinations

**Basic Scene (Best Performance)**

```javascript
const ambient = new THREE.AmbientLight(0xffffff, 0.4);
const directional = new THREE.DirectionalLight(0xffffff, 1.0);
```

**Outdoor Scene**

```javascript
const hemisphere = new THREE.HemisphereLight(0x87CEEB, 0x8B4513, 0.6);
const directional = new THREE.DirectionalLight(0xffffff, 0.8);
```

**Indoor Scene**

```javascript
const ambient = new THREE.AmbientLight(0xffffff, 0.3);
const pointLight1 = new THREE.PointLight(0xffffee, 1.0, 20);
const pointLight2 = new THREE.PointLight(0xffffee, 0.8, 15);
```

**Dramatic/Cinematic**

```javascript
const ambient = new THREE.AmbientLight(0xffffff, 0.2);
const spot1 = new THREE.SpotLight(0xffffff, 1.5); // Key light
const spot2 = new THREE.SpotLight(0x4444ff, 0.5); // Rim light
```

**High-Quality Product Visualization**

```javascript
const ambient = new THREE.AmbientLight(0xffffff, 0.3);
const rectArea = new THREE.RectAreaLight(0xffffff, 2.0, 10, 10);
const directional = new THREE.DirectionalLight(0xffffff, 0.8);
```

## What I Learned

### 1\. **Lighting Makes or Breaks a Scene**

The same geometry and materials look entirely different under different lighting. Good lighting is often more important than complex geometry!

### 2\. **Combine Multiple Lights**

Professional scenes rarely use just one light. The "three-point lighting" technique from photography (key, fill, rim) applies to 3D too!

### 3\. **Light Helpers Are Essential**

Always use light helpers when setting up your scene. They show exactly where lights are positioned and what they're illuminating. Turn them off for final render.

### 4\. **Performance Matters**

More lights = worse performance. Start with cheap lights (Ambient, Directional) and add expensive ones (Spot, RectArea) only where needed.

### 5\. **Distance and Decay Are Critical**

For Point and Spot lights, setting appropriate distance and decay values is crucial. A decay of 2 is physically accurate and usually looks best.

### 6\. **RectAreaLight Limitations**

RectAreaLight only works with MeshStandardMaterial and MeshPhysicalMaterial. If your objects look unlit, check your material type!

### 7\. **Colour Temperature Matters**

Real lights have colour! Sunlight is slightly yellow (0xffffee), fluorescent lights are cooler (0xeeeeff), candlelight is warm orange (0xff8844). Adding subtle colour makes scenes more realistic.

### 8\. **Light Position Is Key**

The same light at different positions creates entirely different moods. Experiment with positioning lights high, low, front, back, and sides.

### 9\. **Hemisphere Light Is Underrated**

Instead of plain AmbientLight, HemisphereLight adds subtle colour variation from sky and ground that makes outdoor scenes look much more natural.

### 10\. **Start Simple, Then Add**

Begin with just ambient + directional light. Once that looks good, add accent lights (point, spot) for drama and interest.

## Common Lighting Recipes

Here are some lighting setups I found useful:

### Sunny Day

```javascript
const hemisphere = new THREE.HemisphereLight(0x87CEEB, 0x8B7355, 0.6);
const sun = new THREE.DirectionalLight(0xffffee, 1.0);
sun.position.set(10, 20, 10);
```

### Overcast Day

```javascript
const ambient = new THREE.AmbientLight(0xcccccc, 0.8);
const directional = new THREE.DirectionalLight(0xffffff, 0.3);
```

### Night Scene with Moon

```javascript
const ambient = new THREE.AmbientLight(0x111144, 0.2);
const moon = new THREE.DirectionalLight(0xaaaaff, 0.5);
moon.position.set(-10, 20, 5);
```

### Indoor Warm Lighting

```javascript
const ambient = new THREE.AmbientLight(0x332211, 0.3);
const lamp1 = new THREE.PointLight(0xffaa66, 1.0, 15, 2);
const lamp2 = new THREE.PointLight(0xffaa66, 0.8, 12, 2);
```

### Studio/Gallery Lighting

```javascript
const ambient = new THREE.AmbientLight(0xffffff, 0.4);
const key = new THREE.SpotLight(0xffffff, 1.5, 30, Math.PI/6, 0.3);
const fill = new THREE.SpotLight(0xffffff, 0.5, 25, Math.PI/4, 0.5);
const rim = new THREE.DirectionalLight(0x8888ff, 0.6);
```

## Debugging Lighting Issues

If your scene looks wrong, check these:

**Objects Are Completely Black**

* Are lights added to the scene?
    
* Do materials need lights? (Basic doesn't, others do)
    
* Is ambient light intensity too low?
    

**Lights Don't Seem to Work**

* Check light visibility (light.visible = true)
    
* Verify light helpers are showing correct positions
    
* For SpotLight, did you add the target to scene?
    
* For RectAreaLight, are you using Standard/Physical material?
    

**Scene Is Too Dark/Bright**

* Adjust ambient light intensity (start around 0.3)
    
* Change directional light intensity (start around 1.0)
    
* Check camera exposure (some renderers support this)
    

**Point/Spot Lights Fade Too Fast**

* Increase distance property
    
* Check decay value (2 is realistic but you can adjust)
    
* Increase intensity
    

## Next Steps

Now that I understand lighting, here's what I'm planning to explore:

* Adding shadows to lights for more realism
    
* Using textures on materials
    
* Environment maps for realistic reflections
    
* Post-processing effects (bloom, ambient occlusion)
    
* Combining great lighting with textured materials
    

## Try experimenting with:

* Different light colour combinations
    
* Three-point lighting setups key (directional), fill (ambient) and rim (spot light)
    
* Animating light positions for dynamic effects
    
* Adjusting intensity to create different moods
    
* Combining lights to simulate real environments
    

Understanding lighting is a game-changer. Happy illuminating! 💡
