threejs-lighting

import * as THREE from "three";

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "threejs-lighting" with this command: npx skills add toilahuongg/shopify-agents-kit/toilahuongg-shopify-agents-kit-threejs-lighting

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

  • Limit light count: Each light adds shader complexity

  • Use baked lighting: For static scenes, bake to textures

  • Smaller shadow maps: 512-1024 often sufficient

  • Tight shadow frustums: Only cover needed area

  • Disable unused shadows: Not all lights need shadows

  • 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

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Automation

shopify-api

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

shopify-extensions

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

shopify-functions

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

agent-creator

No summary provided by upstream source.

Repository SourceNeeds Review