Skip to main content

Lighting & Day/Night Cycle

Hyperscape features a dynamic day/night cycle with adaptive lighting and auto exposure that mimics realistic eye adaptation. The lighting system provides atmospheric transitions while maintaining gameplay visibility.
Lighting code lives in packages/shared/src/systems/shared/world/Environment.ts with sky system in SkySystem.ts.

Auto Exposure System

The auto exposure system mimics eye adaptation to different light levels, automatically adjusting exposure to keep the game visible during both day and night:

How It Works

Exposure Values:
Higher exposure at night compensates for lower light levels, keeping the game playable while maintaining the darker atmosphere.

Initialization

Exposure is initialized based on current time of day to prevent jarring transitions when players join at night:

Day/Night Lighting

Sun and Moon

The sun/moon light transitions based on time of day:
Light Intensity:
Moon intensity was increased from 0.4 to 0.6 to improve night visibility while maintaining atmospheric darkness.

Ambient Lighting

Hemisphere and ambient lights provide base visibility:
Ambient Intensity:

Shadow System

Cascaded Shadow Maps (WebGPU)

WebGPU uses Cascaded Shadow Maps (CSM) for high-quality shadows:
Shadow Quality Levels:

WebGL Shadow Fallback

WebGL uses simplified single directional light shadows:
WebGL Limitations:
  • No cascaded shadows (single shadow map)
  • Smaller shadow coverage area
  • Lower shadow quality
  • Still provides functional shadows for gameplay

Fog System

Fog color transitions with day/night cycle:

CSM Frustum Initialization

CSM frustums are initialized during startup to ensure shadows work from the first frame:
This prevents shadow initialization failures that could occur when camera projection isn’t ready yet.

Lighting Constants


Performance Considerations

Frustum Update Optimization

CSM frustums are only recalculated when needed (expensive operation):

Smooth Transitions

All lighting transitions use interpolation to prevent jarring changes: