8. [Three.js] Lighting and Shadows
1. Digest
Lighting is fundamental to creating realistic 3D scenes. This chapter explores the various light types available in Three.js, each serving different purposes in scene illumination. Starting with basic ambient and directional lights, the examples progress through animated lighting, shadow implementation, and specialized light types including point lights, spotlights, hemisphere lights, and rectangular area lights.
The chapter demonstrates practical implementations of shadow mapping techniques with different quality settings (PCFShadowMap, PCFSoftShadowMap), shadow camera configuration for performance optimization, and proper setup of castShadow and receiveShadow properties. Each example includes dat.GUI integration for real-time light parameter adjustment, allowing experimentation with position, intensity, and color properties. Light helpers are extensively used throughout to visualize light positions and directions, making it easier to understand how different light types behave in 3D space.
The progression from basic static lights to animated and specialized lighting showcases how to create dynamic, visually appealing scenes. Understanding the distinction between lights that cast shadows (DirectionalLight, PointLight, SpotLight) and those that don't (AmbientLight, HemisphereLight, RectAreaLight) is crucial for balancing visual quality with rendering performance.
2. What is the purpose
This chapter teaches fundamental lighting concepts essential for creating realistic and visually appealing 3D scenes. You'll learn how to:
- Set up different types of lights (Ambient, Directional, Point, Spot, Hemisphere, RectArea) and understand their use cases
- Implement shadow mapping with quality optimization techniques
- Configure shadow cameras for performance tuning
- Distinguish between castShadow (objects that create shadows) and receiveShadow (surfaces that display shadows)
- Animate lights dynamically to create moving light effects
- Use light helpers to visualize and debug lighting setups
- Integrate dat.GUI for real-time lighting parameter experimentation
These skills are critical for any Three.js developer working on games, product visualizations, architectural renders, or interactive 3D experiences where lighting dramatically impacts the mood and realism of the scene.
3. Some code block and its explanation
Example 1: Basic Light Setup with DirectionalLight
// Light
const ambientLight = new THREE.AmbientLight("white", 0.5); // 색상, 강도
scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight("white", 0.5);
directionalLight.position.y = 3;
scene.add(directionalLight);
const lightHelper = new THREE.DirectionalLightHelper(directionalLight);
scene.add(lightHelper);
This demonstrates the foundational lighting setup. AmbientLight provides uniform illumination across the entire scene without direction, preventing completely dark areas. DirectionalLight simulates sunlight with parallel rays coming from a specific direction. The DirectionalLightHelper visualizes the light's position and direction, crucial for debugging. Together, these two lights create a balanced lighting environment: ambient light fills shadows softly while directional light creates definition and depth.
Example 2: Shadow Configuration
// Enable shadows in renderer
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
// Configure light for shadows
directionalLight.castShadow = true;
directionalLight.shadow.mapSize.width = 1024;
directionalLight.shadow.mapSize.height = 1024;
directionalLight.shadow.camera.near = 1;
directionalLight.shadow.camera.far = 5;
// Configure meshes
plane.receiveShadow = true;
box.castShadow = true;
box.receiveShadow = true;
sphere.castShadow = true;
sphere.receiveShadow = true;
This code implements shadow mapping with performance optimization. The renderer must explicitly enable shadows and specify the shadow algorithm (PCFSoftShadowMap provides softer, more realistic shadows than the default). The light source needs castShadow enabled and shadow map resolution specified (higher values = better quality but worse performance). Shadow camera near/far planes limit the shadow calculation range for optimization. Finally, each mesh must specify whether it casts shadows onto other objects (castShadow) or receives shadows on its surface (receiveShadow). The plane typically only receives, while objects like boxes and spheres both cast and receive for realistic inter-object shadowing.
Example 3: Animated Lighting
function draw() {
const time = clock.getElapsedTime();
directionalLight.position.x = Math.cos(time) * 5;
directionalLight.position.z = Math.sin(time) * 5;
renderer.render(scene, camera);
window.requestAnimationFrame(draw);
}
This creates a circular light animation using trigonometric functions. By using elapsed time with cos() and sin(), the light orbits around the scene center at a 5-unit radius. This technique simulates time-of-day changes or creates dramatic moving shadow effects. The same pattern works for PointLight and SpotLight animations, creating dynamic lighting scenarios common in games and interactive experiences.
Example 4: Specialized Light Types
// PointLight - Omnidirectional light from a point (like a light bulb)
const pointLight = new THREE.PointLight("white", 15, 100, 2);
pointLight.position.y = 3;
// SpotLight - Cone-shaped directional light (like a flashlight)
const spotLight = new THREE.SpotLight("white", 50, 100, Math.PI / 3);
spotLight.position.set(-3, 5, 0);
// HemisphereLight - Sky/ground gradient lighting (outdoor ambient)
const hemisphereLight = new THREE.HemisphereLight("yellow", "blue", 1);
// RectAreaLight - Rectangular area light (like a window or LED panel)
const rectAreaLight = new THREE.RectAreaLight("yellow", 1, 2, 2);
rectAreaLight.position.set(0, 2, 2);
Each specialized light type serves different purposes. PointLight emits in all directions from a point with distance falloff parameters (intensity, distance, decay), perfect for light bulbs or torches. SpotLight creates a cone-shaped beam with angle control, ideal for flashlights or stage lighting. HemisphereLight simulates outdoor lighting with sky and ground colors blending, creating natural-looking ambient illumination without harsh shadows. RectAreaLight simulates flat light-emitting surfaces like windows or LED panels (note: RectAreaLight doesn't support shadows). Choosing the right light type dramatically affects both visual quality and rendering performance.
