Web Engine Docs
Preparing documentation
Use the search bar to quickly find any topic
Preparing documentation
Use the search bar to quickly find any topic
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.
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.
| Property | Type | Default | Description |
|---|---|---|---|
| type | ui8 | 0 | Light type: 0=Point, 1=Directional, 2=Spot |
| color | [f32, 3] | [1, 1, 1] | Light color [r, g, b] in linear space (0-1) |
| intensity | f32 | 1.0 | Light intensity/brightness |
| range | f32 | 10.0 | Light range in meters (Point and Spot only) |
| angle | f32 | 0.785 | Cone angle in radians (Spot only, π/4 = 45°) |
| castShadow | ui8 | 0 | Whether light casts shadows (0=no, 1=yes) |
Directional lights simulate sunlight with parallel rays from an infinite distance. Perfect for outdoor scenes, day/night cycles, and primary scene illumination.
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 rotationTransform.position[sun] = [0, 20, 0]; // Height is visual onlyTransform.rotation[sun] = [-Math.PI / 4, // 45° downward tiltMath.PI / 4, // 45° angle from side0];// Configure as directional lightLight.type[sun] = 1; // DirectionalLight.color[sun][0] = 1.0; // White lightLight.color[sun][1] = 1.0;Light.color[sun][2] = 1.0;Light.intensity[sun] = 1.5; // Bright sunlightLight.castShadow[sun] = 1; // Enable shadows
// Noon sunlight (overhead)Transform.rotation[sun] = [-Math.PI / 2, 0, 0]; // Straight downLight.color[sun] = [1.0, 0.98, 0.95]; // Slight warm tintLight.intensity[sun] = 2.0;// Sunset lightingTransform.rotation[sun] = [-0.3, Math.PI / 3, 0]; // Low angleLight.color[sun] = [1.0, 0.6, 0.3]; // Orange-redLight.intensity[sun] = 1.2;// MoonlightTransform.rotation[sun] = [-0.5, 0, 0];Light.color[sun] = [0.6, 0.7, 1.0]; // Blue tintLight.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.
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.
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 fromTransform.position[torch] = [5, 2, 0]; // Wall-mounted torch at 2m height// Configure as point lightLight.type[torch] = 0; // PointLight.color[torch][0] = 1.0; // Orange flame colorLight.color[torch][1] = 0.6;Light.color[torch][2] = 0.2;Light.intensity[torch] = 2.0;Light.range[torch] = 10.0; // 10 meter rangeLight.castShadow[torch] = 1;
// CandleLight.type[entity] = 0;Light.color[entity] = [1.0, 0.7, 0.3];Light.intensity[entity] = 0.5;Light.range[entity] = 3.0;// Light bulbLight.type[entity] = 0;Light.color[entity] = [1.0, 0.95, 0.8];Light.intensity[entity] = 1.5;Light.range[entity] = 8.0;// Explosion flashLight.type[entity] = 0;Light.color[entity] = [1.0, 0.8, 0.3];Light.intensity[entity] = 10.0;Light.range[entity] = 20.0;// Neon signLight.type[entity] = 0;Light.color[entity] = [0.0, 1.0, 0.8]; // CyanLight.intensity[entity] = 2.0;Light.range[entity] = 5.0;
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 centerLight.range[lamp] = 5.0;Light.intensity[lamp] = 3.0;// Large radius, even spreadLight.range[lamp] = 15.0;Light.intensity[lamp] = 1.0;
Spot lights emit light in a cone shape, like a flashlight or stage spotlight. They have position, direction, range, and cone angle.
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 matterTransform.position[flashlight] = [0, 1.5, 0]; // Eye levelTransform.rotation[flashlight] = [0, 0, 0]; // Forward direction// Configure as spot lightLight.type[flashlight] = 2; // SpotLight.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 distanceLight.angle[flashlight] = Math.PI / 6; // 30° cone (π/6 radians)Light.castShadow[flashlight] = 1;
// FlashlightLight.type[entity] = 2;Light.angle[entity] = Math.PI / 6; // 30° coneLight.range[entity] = 20.0;Light.intensity[entity] = 3.0;// Stage spotlight (narrow beam)Light.type[entity] = 2;Light.angle[entity] = Math.PI / 12; // 15° coneLight.range[entity] = 30.0;Light.intensity[entity] = 5.0;// Street lampLight.type[entity] = 2;Light.angle[entity] = Math.PI / 3; // 60° coneLight.range[entity] = 15.0;Light.intensity[entity] = 2.0;// Car headlightLight.type[entity] = 2;Light.angle[entity] = Math.PI / 4; // 45° coneLight.range[entity] = 50.0;Light.intensity[entity] = 4.0;
// 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 forwardTransform.rotation[spotlight] = [0, 0, 0];// Point at 45° angle down and rightTransform.rotation[spotlight] = [Math.PI / 4, Math.PI / 4, 0];// Attach to player camera for flashlightconst camera = getCameraEntity(world);Transform.parent[flashlight] = camera;Transform.position[flashlight] = [0, -0.2, 0]; // Offset slightly down
All light types support shadow casting. Shadows are computed using shadow mapping with configurable quality and distance.
// Enable shadow casting on lightLight.castShadow[sun] = 1;// Enable shadow casting on meshMeshRenderer.castShadow[character] = 1;// Enable shadow receiving on meshMeshRenderer.receiveShadow[floor] = 1;// Both casting and receivingMeshRenderer.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 is configured globally via renderer settings// Higher resolution = sharper shadows but more expensiveconst 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 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 lightscandle: [1.0, 0.58, 0.16], // 1500Ksunset: [1.0, 0.54, 0.0], // 2000Ktungsten: [1.0, 0.78, 0.55], // 3200Khalogen: [1.0, 0.94, 0.88], // 3400K// Neutral lightsfluorescent: [0.99, 1.0, 0.98], // 4000Kdaylight: [1.0, 1.0, 1.0], // 5500Kflash: [1.0, 1.0, 1.0], // 5500K// Cool lightsovercast: [0.78, 0.84, 1.0], // 6500Kshade: [0.64, 0.73, 1.0], // 8000KclearSky: [0.25, 0.5, 1.0], // 10000K// Colored lightsfire: [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 presetLight.color[torch] = LIGHT_COLORS.tungsten;Light.color[neonSign] = LIGHT_COLORS.neonBlue;
| Light Type | Typical Intensity | Use Case |
|---|---|---|
| Directional (Sun) | 1.0 - 3.0 | Outdoor daylight, primary illumination |
| Directional (Moon) | 0.1 - 0.5 | Night scenes, subtle ambient |
| Point (Candle) | 0.3 - 0.8 | Small intimate lighting |
| Point (Bulb) | 1.0 - 2.0 | Room lighting, lamps |
| Point (Explosion) | 5.0 - 20.0 | Temporary bright flash |
| Spot (Flashlight) | 2.0 - 5.0 | Player equipment, exploration |
| Spot (Stage) | 3.0 - 10.0 | Dramatic lighting, highlights |
The Environment component controls global scene lighting including skybox, fog, ambient light, and HDRI environment maps.
| Property | Type | Default | Description |
|---|---|---|---|
| preset | ui8 | 0 | Environment preset (0=None, 1=Sunset, 2=Dawn, etc.) |
| background | ui8 | 1 | Show skybox as background (0=no, 1=yes) |
| blur | f32 | 0.0 | Background blur amount (0-1) |
| sunPosition | [f32, 3] | [10, 10, 10] | Sun position for preset environments |
| ambientIntensity | f32 | 0.5 | Ambient light intensity |
| fogColor | [f32, 3] | [0.5, 0.5, 0.5] | Fog color [r, g, b] |
| fogDensity | f32 | 0.0 | Fog density (0=no fog, 0.01=light fog, 0.1=heavy fog) |
| csmEnabled | ui8 | 0 | Cascaded shadow maps enabled (0=no, 1=yes) |
| csmIntensity | f32 | 1.0 | CSM shadow intensity |
| volumetricFog | ui8 | 0 | Volumetric fog/god rays (0=no, 1=yes) |
| envMapAssetId | ui32 | 0 | Custom HDRI environment map asset ID |
| toneMappingExposure | f32 | 1.0 | Global exposure for tone mapping |
import { addComponent, Environment } from '@web-engine/core';// Create environment entityconst env = world.addEntity();addComponent(world, Environment, env);// Sunset presetEnvironment.preset[env] = 1; // SunsetEnvironment.background[env] = 1;Environment.ambientIntensity[env] = 0.6;Environment.sunPosition[env] = [10, 2, 5]; // Low sun angle// Add fogEnvironment.fogColor[env] = [0.8, 0.6, 0.5]; // Warm fogEnvironment.fogDensity[env] = 0.02; // Light fog// Tone mappingEnvironment.toneMappingExposure[env] = 1.2;
| Preset | Value | Description |
|---|---|---|
| None | 0 | No preset environment |
| Sunset | 1 | Orange sunset sky with warm lighting |
| Dawn | 2 | Early morning sky with cool lighting |
| Night | 3 | Dark night sky with stars |
| Warehouse | 4 | Indoor warehouse HDRI |
| Forest | 5 | Forest clearing HDRI |
| Apartment | 6 | Interior apartment HDRI |
| Studio | 7 | Photo studio HDRI |
| City | 8 | Urban cityscape HDRI |
| Park | 9 | Outdoor park HDRI |
| Lobby | 10 | Interior lobby HDRI |
// Atmospheric fog (distance fog)Environment.fogColor[env] = [0.7, 0.8, 0.9]; // Sky blueEnvironment.fogDensity[env] = 0.01; // Gradual fade// Heavy fog (horror game)Environment.fogColor[env] = [0.3, 0.3, 0.35]; // GrayEnvironment.fogDensity[env] = 0.08;// UnderwaterEnvironment.fogColor[env] = [0.0, 0.3, 0.5]; // Blue-greenEnvironment.fogDensity[env] = 0.15;// No fogEnvironment.fogDensity[env] = 0.0;
// 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];// Environmentconst env = world.addEntity();addComponent(world, Environment, env);Environment.preset[env] = 1; // SunsetEnvironment.ambientIntensity[env] = 0.5;Environment.fogDensity[env] = 0.005;
// 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];
// Dim moonlightconst 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 scriptLight.range[candle] = 4.0;// Heavy fogconst 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;