Repository navigation
Sky and Atmosphere
SparkEngine provides an analytical sky rendering system based on the Preetham 1999 paper ("A Practical Analytic Model for Daylight"). The SkyAtmosphereSystem computes physically-plausible sky colors from any view direction using Perez distribution coefficients derived from atmospheric turbidity and sun position.
Source: SparkEngine/Source/Graphics/SkyAtmosphere.h
Namespace: Spark::Graphics
Tests: Tests/TestSkyAtmosphere.cpp (5 test cases)
- Overview
- Architecture
- Sky Settings
- Preetham Sky Model
- Integration with Day/Night Cycle
- GPU Rendering
- Code Example
- Source Files
- See Also
The sky atmosphere system is a singleton (SkyAtmosphereSystem::GetInstance()) that evaluates sky luminance for any view direction given the current sun position and atmospheric turbidity. The system is primarily CPU-side -- computed colors can feed a skybox, be passed to shaders as uniform data, or be sampled for ambient lighting.
┌──────────────────────┐ sun direction ┌──────────────────────┐
│ TimeOfDaySystem │ ─────────────────────► │ SkyAtmosphereSystem │
│ (day/night cycle) │ turbidity │ Preetham/Perez │
└──────────────────────┘ │ model evaluation │
└──────────┬───────────┘
│
┌───────────────────────────────────┤
│ │
┌───────▼───────┐ ┌───────▼───────┐
│ Skybox Render │ │ Ambient Light │
│ (6 face │ │ Probe colors │
│ colors) │ │ │
└───────────────┘ └───────────────┘
Key capabilities:
-
Analytical sky color from any view direction via
ComputeSkyColor() -
Sun disc color and intensity via
ComputeSunColor() - Zenith and horizon colors for ambient lighting or fog blending
- HDR exposure control for tone mapping integration
- GPU constant buffer for shader-side sky evaluation
-
Cubemap face colors rendered via
RenderGPU()for skybox display
| Class/Struct | Responsibility |
|---|---|
SkyAtmosphereSystem |
Singleton manager. Computes Perez coefficients, evaluates sky color, manages GPU resources. |
SkySettings |
Configuration struct: turbidity, sun intensity, sun direction, exposure, ground albedo. |
SkyColor |
Linear RGB color with Lerp() and scalar multiply. |
PerezCoefficients |
Five coefficients (A-E) for one channel of the Perez distribution function. |
The SkySettings struct controls all atmospheric parameters:
| Field | Type | Default | Range | Description |
|---|---|---|---|---|
turbidity |
float |
2.0 | 1 -- 10 | Atmospheric haze. 1 = perfectly clear, 10 = heavy haze/smog. |
sunIntensity |
float |
20.0 | -- | Brightness multiplier for direct sunlight. |
sunDirection |
XMFLOAT3 |
(0, -0.5, 0.5) | Normalized | Direction toward the sun. |
exposure |
float |
1.0 | -- | HDR exposure control for tone mapping. |
groundAlbedo |
float |
0.3 | 0 -- 1 | Ground reflectance for multi-scattering approximation. |
enabled |
bool |
true | -- | Master enable/disable switch. |
Lower turbidity produces a deep blue sky with a sharp sun disc. Higher turbidity washes out the sky toward white/yellow and broadens the circumsolar glow.
The implementation follows the Preetham 1999 analytical model using the Perez luminance distribution function. For each color channel (Y luminance, x chrominance, y chrominance in CIE Yxy color space):
-
Perez coefficients (A-E) are derived from the current turbidity value via
RecalculateCoefficients(). These control:- A -- Darkening or brightening of the horizon
- B -- Luminance gradient near the horizon
- C -- Relative intensity of the circumsolar region
- D -- Width of the circumsolar region
- E -- Relative backscattered light
-
Zenith values are computed from sun elevation and turbidity via
ComputeZenithValues(). -
Sky evaluation at a view direction uses:
-
theta-- angle from zenith to the sample direction -
gamma-- angle between the sample direction and the sun direction - The ratio
F(theta, gamma) / F(0, thetaSun)normalizes the distribution relative to the zenith.
-
The static method EvaluatePerez() computes the distribution value for a given (theta, gamma) pair and coefficient set.
The sky system integrates with the Day/Night Cycle and Weather systems:
-
Sun direction is typically driven by
TimeOfDaySystem, which updates the sun angle each frame based on the in-game clock. -
Turbidity can be modulated by
WeatherSystem-- clear weather uses low turbidity, overcast or polluted conditions use high turbidity. - Exposure can be linked to auto-exposure or post-processing tone mapping.
-
Update(deltaTime)optionally animates the sun position if linked to a time-of-day source.
The FogSystem can sample GetHorizonColor() to match fog color to the sky at the horizon, creating seamless blending between distant geometry and the sky.
RenderGPU(deltaTime) creates a GPU constant buffer containing the Perez coefficients, zenith values, sun direction, and exposure. It then samples the Preetham model at six cardinal directions (+X, -X, +Y, -Y, +Z, -Z) to produce cubemap-ready colors stored internally.
// Access the computed skybox face colors
const SkyColor* faces = sky.GetSkyboxColors();
// faces[0] = +X, faces[1] = -X, faces[2] = +Y, etc.The constant buffer (m_gpuConstantBuffer) is created through the RHI abstraction, making the system backend-agnostic.
// Get the singleton
auto& sky = Spark::Graphics::SkyAtmosphereSystem::GetInstance();
sky.Initialize();
// Configure for a clear afternoon
SkySettings settings;
settings.turbidity = 3.0f;
settings.sunIntensity = 22.0f;
settings.sunDirection = {0.0f, -0.7f, 0.7f}; // Sun at ~45 degrees
settings.exposure = 1.2f;
settings.groundAlbedo = 0.3f;
sky.SetSettings(settings);
// Query sky color for a specific direction
SkyColor overhead = sky.ComputeSkyColor({0.0f, 1.0f, 0.0f}); // Looking up
SkyColor horizon = sky.GetHorizonColor();
SkyColor sunDisc = sky.ComputeSunColor();
// Use horizon color for fog blending
fogSystem.SetColor(horizon.r, horizon.g, horizon.b);
// Per-frame update
sky.Update(deltaTime);
sky.RenderGPU(deltaTime);
// Cleanup
sky.Shutdown();| File | Description |
|---|---|
SparkEngine/Source/Graphics/SkyAtmosphere.h |
SkyAtmosphereSystem, SkySettings, SkyColor, PerezCoefficients
|
Tests/TestSkyAtmosphere.cpp |
Unit tests (5 test cases) |
- Day Night Cycle and Weather -- Time-of-day and weather systems that drive sun direction and turbidity
- Volumetric Fog -- Fog system that samples horizon color for seamless sky-fog blending
- Volumetric Clouds -- Ray-marched cloud layer that composites over this sky model
- Rendering and Graphics -- Graphics engine and skybox rendering
- RHI Abstraction Layer -- Backend-agnostic GPU resource creation
- Clustered Lighting -- Lighting pipeline that uses sun intensity from the sky system
Published from 2b03dc797148. Edit the canonical source in wiki/.
- Documentation
- Docs route
- Wiki index
- Guides
- Tutorials
- Samples
- Examples
- API Reference
- API route
- Reference
- Build Guide
- Dependencies
- FAQ
- Changelog
- Roadmap
- Contributing
- Code of Conduct
- Home
- FAQ
- Getting Started
- Quick-Start Tutorial
- Making Your First Game
- Making Your First Multiplayer Game
- Artist Workflow Guide
- Editor Walkthrough
- Migration Guide
- How SparkEngine Works
- Architecture Overview
- Engine Architecture Flowchart
- Creating a Game Module
- Game Modules (catalog)
- Entity Component System
- Rendering and Graphics
- Physics
- Cloth Simulation
- Audio
- Input System
- Camera System
- Scripting with AngelScript
- Visual Scripting
- AI and Navigation
- Animation
- 2D Systems
- Networking
- Dedicated Server
- Multiplayer Quick Start
- Area Server Architecture
- Scene Management
- Large World Support
- Collaborative Editing
- Coroutine System
- Event System
- Event Response System
- Job System
- UI System
- UI Layout Extensions
- Localization
- Dialogue System
- Destruction System
- Replay System
- Achievement System
- Loading System
- Mod System
- Content Delivery
- Tween System
- Memory Integrity
- Gameplay Systems
- Terrain and Procedural Generation
- Save System
- Persistence System
- Day Night Cycle and Weather
- Cinematic Sequencer
- Runtime Prefabs
- SparkEditor
- Editor Tutorials
- SparkConsole
- SparkDaemon
- Shader Pipeline
- Asset Pipeline
- Asset Validation
- Asset Migration
- Game Packaging
- Online Services
- DataTable System
- Loot and Crafting System
- CSG System
- Font System
- Timer Manager
- Movie Render Pipeline
- HLOD and World Partition
- Remote Debug System
- Selection Manager
- Asset Dependency Graph
- Editor Automation
- File Watcher
- Project Templates
- System Requirements
- VR Support
- Mobile Platform
- Accessibility
- Platform Input
- Platform Certification
- Cross-Compilation: Wine Testing
- RHI Abstraction Layer
- D3D11 Backend
- D3D12 Backend
- Vulkan Backend
- OpenGL Backend
- Metal Backend
- DXR Raytracing
- Hybrid Ray Tracing
- Upscaling (DLSS/FSR)
- Render Graph
- Shader Graph
- GPU Particles
- GPU-Driven Rendering
- Volumetric Fog
- Volumetric Clouds
- Global Illumination
- Virtual Texturing
- Water Rendering
- Clustered Lighting
- Material System
- Post-Processing
- Shadow System
- Particle System
- Decal System
- Sky and Atmosphere
- Foliage System
- Mesh Shaders
- Neural Rendering
- Configuration Reference
- Performance Tips
- Benchmark Framework
- Threading Model
- Fuzz Policy and Parser Security
- Memory Safety
- Memory Management Patterns
- Build System and CMake Modules
- Profiler and Debugging
- Performance Profiling Guide
- Telemetry System
- Crash Reporting
- Golden Image Testing
- Utilities
- Testing
- Fuzz Policy and Parser Security
- Codebase Statistics
- Codebase Health
- Error Handling Patterns
- Hot Reload Overview
- Troubleshooting
- Contributing
- Workflow Patterns
- Build Optimizations
- CI Reproducible Builds
- GitHub API and PR Checks
- Git Rebase Conflicts
- Clang-Format
- Code Quality Violations
- AI Bloat Pattern
- MinGW + Wine Cross-Compilation
- Live Editor Testing
- Engine & Renderer Landscape
- DuetOS Portability Catalog
- Five-Engine Analysis
- Eleven-Engine Analysis
- ThorVG / Unity Graphics Analysis
- Advanced Techniques Catalog
- Third-Party Library Evaluation
- Engine Viability Evaluation
- Engine Feature Recommendations
- Project Recommendations
- Mac Compatibility Analysis
- Codebase Observations
- Codebase Bloat Audit
- Test Suite Audit
- Documentation Coverage Audit
- ThirdParty Dependencies Audit
- Load Test Baseline
- Gameplay Systems Status
- SparkGame Module Status
- Stub and Abandoned Features
- Memory Integrity System
- Memory Safety Evaluation
- Hardware Acceleration Systems
- Jolt Physics Integration
- GPU/CPU Separation Plan
- Daemon Services Architecture
- Reflection & Polymorphism Refactoring Plan
- SparkBuild In-Tree
- Wine No-JobSystem Breakthrough
- Wine Role and Fallback Tiers