Lighting Components

Light component for DirectionalLight, PointLight, and SpotLight with shadow support and Environment settings.

Lighting components enable realistic illumination and shadows in your scenes. Web Engine uses Three.js lighting with support for directional, point, and spot lights, plus advanced features like shadow mapping and environmental lighting.

Light Component#

The Light component is a unified component for all light types. The type field determines whether the entity is a directional, point, or spot light.

Properties#

PropertyTypeDefaultDescription
typeui80Light type: 0=Point, 1=Directional, 2=Spot
color[f32, 3][1, 1, 1]Light color [r, g, b] in linear space (0-1)
intensityf321.0Light intensity/brightness
rangef3210.0Light range in meters (Point and Spot only)
anglef320.785Cone angle in radians (Spot only, π/4 = 45°)
castShadowui80Whether light casts shadows (0=no, 1=yes)

Light Types#

  • Point (0): Emits light in all directions from a point (like a light bulb)
  • Directional (1): Parallel rays from infinite distance (like the sun)
  • Spot (2): Emits light in a cone shape (like a flashlight)

DirectionalLight#

Directional lights simulate sunlight with parallel rays from an infinite distance. Perfect for outdoor scenes, day/night cycles, and primary scene illumination.

Usage#

import { addComponent, Light, Transform } from '@web-engine/core';
// Create sun (directional light)
const sun = world.addEntity();
addComponent(world, Transform, sun);
addComponent(world, Light, sun);
// Position doesn't matter (infinite distance), only rotation
Transform.position[sun] = [0, 20, 0]; // Height is visual only
Transform.rotation[sun] = [
-Math.PI / 4, // 45° downward tilt
Math.PI / 4, // 45° angle from side
0
];
// Configure as directional light
Light.type[sun] = 1; // Directional
Light.color[sun][0] = 1.0; // White light
Light.color[sun][1] = 1.0;
Light.color[sun][2] = 1.0;
Light.intensity[sun] = 1.5; // Bright sunlight
Light.castShadow[sun] = 1; // Enable shadows

Common Configurations#

// Noon sunlight (overhead)
Transform.rotation[sun] = [-Math.PI / 2, 0, 0]; // Straight down
Light.color[sun] = [1.0, 0.98, 0.95]; // Slight warm tint
Light.intensity[sun] = 2.0;
// Sunset lighting
Transform.rotation[sun] = [-0.3, Math.PI / 3, 0]; // Low angle
Light.color[sun] = [1.0, 0.6, 0.3]; // Orange-red
Light.intensity[sun] = 1.2;
// Moonlight
Transform.rotation[sun] = [-0.5, 0, 0];
Light.color[sun] = [0.6, 0.7, 1.0]; // Blue tint
Light.intensity[sun] = 0.3; // Dim

Directional Light Position

Directional lights simulate infinitely distant light sources, so the position doesn't affect lighting. Only the rotation (direction) matters. Position is only used for visual representation in the editor.

PointLight#

Point lights emit light in all directions from a single point, like a light bulb or torch. They have a limited range and use distance-based attenuation.

Usage#

import { addComponent, Light, Transform } from '@web-engine/core';
// Create torch (point light)
const torch = world.addEntity();
addComponent(world, Transform, torch);
addComponent(world, Light, torch);
// Position matters - place where light should emit from
Transform.position[torch] = [5, 2, 0]; // Wall-mounted torch at 2m height
// Configure as point light
Light.type[torch] = 0; // Point
Light.color[torch][0] = 1.0; // Orange flame color
Light.color[torch][1] = 0.6;
Light.color[torch][2] = 0.2;
Light.intensity[torch] = 2.0;
Light.range[torch] = 10.0; // 10 meter range
Light.castShadow[torch] = 1;

Common Configurations#

// Candle
Light.type[entity] = 0;
Light.color[entity] = [1.0, 0.7, 0.3];
Light.intensity[entity] = 0.5;
Light.range[entity] = 3.0;
// Light bulb
Light.type[entity] = 0;
Light.color[entity] = [1.0, 0.95, 0.8];
Light.intensity[entity] = 1.5;
Light.range[entity] = 8.0;
// Explosion flash
Light.type[entity] = 0;
Light.color[entity] = [1.0, 0.8, 0.3];
Light.intensity[entity] = 10.0;
Light.range[entity] = 20.0;
// Neon sign
Light.type[entity] = 0;
Light.color[entity] = [0.0, 1.0, 0.8]; // Cyan
Light.intensity[entity] = 2.0;
Light.range[entity] = 5.0;

Light Attenuation#

Point lights use physically-based inverse square falloff with configurable range:

// Light intensity decreases with distance:
// intensity_at_distance = intensity / (distance^2 + 1)
// At range distance, light contribution approaches zero
// Small radius, bright center
Light.range[lamp] = 5.0;
Light.intensity[lamp] = 3.0;
// Large radius, even spread
Light.range[lamp] = 15.0;
Light.intensity[lamp] = 1.0;

SpotLight#

Spot lights emit light in a cone shape, like a flashlight or stage spotlight. They have position, direction, range, and cone angle.

Usage#

import { addComponent, Light, Transform } from '@web-engine/core';
// Create flashlight (spot light)
const flashlight = world.addEntity();
addComponent(world, Transform, flashlight);
addComponent(world, Light, flashlight);
// Position and rotation both matter
Transform.position[flashlight] = [0, 1.5, 0]; // Eye level
Transform.rotation[flashlight] = [0, 0, 0]; // Forward direction
// Configure as spot light
Light.type[flashlight] = 2; // Spot
Light.color[flashlight][0] = 1.0;
Light.color[flashlight][1] = 1.0;
Light.color[flashlight][2] = 0.9;
Light.intensity[flashlight] = 3.0;
Light.range[flashlight] = 20.0; // 20m beam distance
Light.angle[flashlight] = Math.PI / 6; // 30° cone (π/6 radians)
Light.castShadow[flashlight] = 1;

Common Configurations#

// Flashlight
Light.type[entity] = 2;
Light.angle[entity] = Math.PI / 6; // 30° cone
Light.range[entity] = 20.0;
Light.intensity[entity] = 3.0;
// Stage spotlight (narrow beam)
Light.type[entity] = 2;
Light.angle[entity] = Math.PI / 12; // 15° cone
Light.range[entity] = 30.0;
Light.intensity[entity] = 5.0;
// Street lamp
Light.type[entity] = 2;
Light.angle[entity] = Math.PI / 3; // 60° cone
Light.range[entity] = 15.0;
Light.intensity[entity] = 2.0;
// Car headlight
Light.type[entity] = 2;
Light.angle[entity] = Math.PI / 4; // 45° cone
Light.range[entity] = 50.0;
Light.intensity[entity] = 4.0;

Spotlight Direction#

// Spotlight points in entity's local -Z direction
// Rotate to aim spotlight
// Point down (ceiling lamp)
Transform.rotation[spotlight] = [Math.PI / 2, 0, 0];
// Point forward
Transform.rotation[spotlight] = [0, 0, 0];
// Point at 45° angle down and right
Transform.rotation[spotlight] = [Math.PI / 4, Math.PI / 4, 0];
// Attach to player camera for flashlight
const camera = getCameraEntity(world);
Transform.parent[flashlight] = camera;
Transform.position[flashlight] = [0, -0.2, 0]; // Offset slightly down

Shadow Configuration#

All light types support shadow casting. Shadows are computed using shadow mapping with configurable quality and distance.

Enabling Shadows#

// Enable shadow casting on light
Light.castShadow[sun] = 1;
// Enable shadow casting on mesh
MeshRenderer.castShadow[character] = 1;
// Enable shadow receiving on mesh
MeshRenderer.receiveShadow[floor] = 1;
// Both casting and receiving
MeshRenderer.castShadow[rock] = 1;
MeshRenderer.receiveShadow[rock] = 1;

Shadow Performance

Shadow rendering is expensive. Limit shadow-casting lights to 1-3 per scene. Use castShadow=1 only on important lights (sun, player flashlight). Disable shadows on small or distant objects for better performance.

Shadow Quality#

// Shadow quality is configured globally via renderer settings
// Higher resolution = sharper shadows but more expensive
const renderer = getRenderer(world);
// Low quality (mobile)
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.BasicShadowMap; // 1024x1024
// Medium quality (default)
renderer.shadowMap.type = THREE.PCFShadowMap; // 2048x2048, soft edges
// High quality (desktop)
renderer.shadowMap.type = THREE.PCFSoftShadowMap; // 4096x4096, very soft
// Ultra quality (cinematic)
renderer.shadowMap.type = THREE.VSMShadowMap; // Variance shadow maps

Light Properties Deep Dive#

Color and Temperature#

Light colors are specified in linear RGB space (0-1). Use color temperature presets for realistic lighting:

// Color temperature presets (Kelvin to RGB)
const LIGHT_COLORS = {
// Warm lights
candle: [1.0, 0.58, 0.16], // 1500K
sunset: [1.0, 0.54, 0.0], // 2000K
tungsten: [1.0, 0.78, 0.55], // 3200K
halogen: [1.0, 0.94, 0.88], // 3400K
// Neutral lights
fluorescent: [0.99, 1.0, 0.98], // 4000K
daylight: [1.0, 1.0, 1.0], // 5500K
flash: [1.0, 1.0, 1.0], // 5500K
// Cool lights
overcast: [0.78, 0.84, 1.0], // 6500K
shade: [0.64, 0.73, 1.0], // 8000K
clearSky: [0.25, 0.5, 1.0], // 10000K
// Colored lights
fire: [1.0, 0.5, 0.0],
lava: [1.0, 0.3, 0.0],
neonBlue: [0.0, 0.5, 1.0],
neonPink: [1.0, 0.0, 0.5],
poison: [0.5, 1.0, 0.0],
};
// Apply color preset
Light.color[torch] = LIGHT_COLORS.tungsten;
Light.color[neonSign] = LIGHT_COLORS.neonBlue;

Intensity Guidelines#

Light TypeTypical IntensityUse Case
Directional (Sun)1.0 - 3.0Outdoor daylight, primary illumination
Directional (Moon)0.1 - 0.5Night scenes, subtle ambient
Point (Candle)0.3 - 0.8Small intimate lighting
Point (Bulb)1.0 - 2.0Room lighting, lamps
Point (Explosion)5.0 - 20.0Temporary bright flash
Spot (Flashlight)2.0 - 5.0Player equipment, exploration
Spot (Stage)3.0 - 10.0Dramatic lighting, highlights

Environment Component#

The Environment component controls global scene lighting including skybox, fog, ambient light, and HDRI environment maps.

Properties#

PropertyTypeDefaultDescription
presetui80Environment preset (0=None, 1=Sunset, 2=Dawn, etc.)
backgroundui81Show skybox as background (0=no, 1=yes)
blurf320.0Background blur amount (0-1)
sunPosition[f32, 3][10, 10, 10]Sun position for preset environments
ambientIntensityf320.5Ambient light intensity
fogColor[f32, 3][0.5, 0.5, 0.5]Fog color [r, g, b]
fogDensityf320.0Fog density (0=no fog, 0.01=light fog, 0.1=heavy fog)
csmEnabledui80Cascaded shadow maps enabled (0=no, 1=yes)
csmIntensityf321.0CSM shadow intensity
volumetricFogui80Volumetric fog/god rays (0=no, 1=yes)
envMapAssetIdui320Custom HDRI environment map asset ID
toneMappingExposuref321.0Global exposure for tone mapping

Usage#

import { addComponent, Environment } from '@web-engine/core';
// Create environment entity
const env = world.addEntity();
addComponent(world, Environment, env);
// Sunset preset
Environment.preset[env] = 1; // Sunset
Environment.background[env] = 1;
Environment.ambientIntensity[env] = 0.6;
Environment.sunPosition[env] = [10, 2, 5]; // Low sun angle
// Add fog
Environment.fogColor[env] = [0.8, 0.6, 0.5]; // Warm fog
Environment.fogDensity[env] = 0.02; // Light fog
// Tone mapping
Environment.toneMappingExposure[env] = 1.2;

Environment Presets#

PresetValueDescription
None0No preset environment
Sunset1Orange sunset sky with warm lighting
Dawn2Early morning sky with cool lighting
Night3Dark night sky with stars
Warehouse4Indoor warehouse HDRI
Forest5Forest clearing HDRI
Apartment6Interior apartment HDRI
Studio7Photo studio HDRI
City8Urban cityscape HDRI
Park9Outdoor park HDRI
Lobby10Interior lobby HDRI

Fog Configuration#

// Atmospheric fog (distance fog)
Environment.fogColor[env] = [0.7, 0.8, 0.9]; // Sky blue
Environment.fogDensity[env] = 0.01; // Gradual fade
// Heavy fog (horror game)
Environment.fogColor[env] = [0.3, 0.3, 0.35]; // Gray
Environment.fogDensity[env] = 0.08;
// Underwater
Environment.fogColor[env] = [0.0, 0.3, 0.5]; // Blue-green
Environment.fogDensity[env] = 0.15;
// No fog
Environment.fogDensity[env] = 0.0;

Best Practices#

  • Use one directional light as the primary light source (sun/moon)
  • Limit shadow-casting lights to 1-3 per scene for performance
  • Use point lights for local illumination (torches, lamps, fires)
  • Use spot lights for focused beams (flashlights, headlights, stage lights)
  • Set appropriate light ranges to minimize overlap and improve performance
  • Use ambient light (Environment.ambientIntensity) to fill shadows
  • Match fog color to background color for seamless blending
  • Enable castShadow only on important objects (characters, props)
  • Use color temperature to create mood (warm = cozy, cool = clinical)
  • Add slight color tint to lights for visual interest (not pure white)
  • Use HDRI environment maps for realistic reflections and ambient lighting
  • Combine multiple lights for depth: key light (bright), fill light (soft), rim light (edge)

Common Lighting Scenarios#

Outdoor Day Scene#

// Sun (directional)
const sun = world.addEntity();
addComponent(world, Light, sun);
Light.type[sun] = 1;
Light.color[sun] = [1.0, 0.98, 0.95];
Light.intensity[sun] = 2.0;
Light.castShadow[sun] = 1;
Transform.rotation[sun] = [-Math.PI / 3, Math.PI / 4, 0];
// Environment
const env = world.addEntity();
addComponent(world, Environment, env);
Environment.preset[env] = 1; // Sunset
Environment.ambientIntensity[env] = 0.5;
Environment.fogDensity[env] = 0.005;

Indoor Room#

// Ceiling lamp (point)
const lamp = world.addEntity();
addComponent(world, Light, lamp);
Light.type[lamp] = 0;
Light.color[lamp] = [1.0, 0.95, 0.85];
Light.intensity[lamp] = 1.5;
Light.range[lamp] = 8.0;
Transform.position[lamp] = [0, 3, 0];
// Window light (spot, simulating sunbeam)
const window = world.addEntity();
addComponent(world, Light, window);
Light.type[window] = 2;
Light.color[window] = [1.0, 1.0, 0.98];
Light.intensity[window] = 2.0;
Light.range[window] = 10.0;
Light.angle[window] = Math.PI / 6;
Light.castShadow[window] = 1;
Transform.position[window] = [5, 3, 0];
Transform.rotation[window] = [0, -Math.PI / 2, 0];

Horror Atmosphere#

// Dim moonlight
const moon = world.addEntity();
addComponent(world, Light, moon);
Light.type[moon] = 1;
Light.color[moon] = [0.5, 0.6, 0.8];
Light.intensity[moon] = 0.3;
Transform.rotation[moon] = [-0.5, 0, 0];
// Flickering candle (point)
const candle = world.addEntity();
addComponent(world, Light, candle);
Light.type[candle] = 0;
Light.color[candle] = [1.0, 0.7, 0.3];
Light.intensity[candle] = 0.8; // Flicker in script
Light.range[candle] = 4.0;
// Heavy fog
const env = world.addEntity();
addComponent(world, Environment, env);
Environment.fogColor[env] = [0.1, 0.1, 0.15];
Environment.fogDensity[env] = 0.05;
Environment.ambientIntensity[env] = 0.1;
Components | Web Engine Docs | Web Engine Docs