Skip to main content

Overview

The Hydra atmosphere system manages day-night cycles, sky colors, directional lighting, volumetric clouds, and dynamic weather effects like rain and snow.

Basic Setup

Create an atmosphere with automatic day-night cycling:
#include "hydra/atmosphere.h"

// Create atmosphere
Atmosphere atmosphere;
atmosphere.timeOfDay = 14.5f; // 2:30 PM
atmosphere.secondsPerHour = 120.0f; // Fast time: 2 minutes per hour
atmosphere.cycle = true; // Enable automatic day-night cycle
atmosphere.enable();

// Update each frame
atmosphere.update(deltaTime);

Time of Day

Setting Time

// Set specific time (0-24 hours)
atmosphere.setTime(6.5f); // 6:30 AM
atmosphere.setTime(18.0f); // 6:00 PM
atmosphere.setTime(0.0f); // Midnight

Time Properties

timeOfDay
float
Current time of day expressed in hours [0, 24)
secondsPerHour
float
default:"3600.0f"
Number of simulated seconds per in-game hour. Lower values speed up time.
cycle
bool
default:"false"
Toggles automatic day-night cycling when true

Time Queries

// Get normalized time [0, 1)
float normalizedTime = atmosphere.getNormalizedTime();

// Check if daytime
if (atmosphere.isDaytime()) {
    // Sun is above horizon
}

Lighting

Celestial Bodies

// Get sun and moon directions
Magnitude3d sunDirection = atmosphere.getSunAngle();
Magnitude3d moonDirection = atmosphere.getMoonAngle();

// Get current light intensity and color
float intensity = atmosphere.getLightIntensity();
Color lightColor = atmosphere.getLightColor();

// Configure global lighting
atmosphere.useGlobalLight();

Light Customization

sunColor
Color
default:"Color(1.0, 0.95, 0.8, 1.0)"
Color applied to sunlight during daytime
moonColor
Color
default:"Color(0.5, 0.5, 0.8, 1.0)"
Color applied to moonlight during nighttime
sunSize
float
default:"1.0f"
Apparent size of the sun disk in the sky
moonSize
float
default:"1.0f"
Apparent size of the moon disk in the sky
sunTintStrength
float
default:"0.3f"
Strength of the warm tint applied near horizons
moonTintStrength
float
default:"0.8f"
Strength of the cold tint used for moonlit nights
starIntensity
float
default:"3.0f"
Brightness multiplier for stars rendered in the skybox

Volumetric Clouds

Basic Cloud Setup

// Add clouds to atmosphere
atmosphere.addClouds(4, 6); // Worley frequency and divisions

// Configure cloud properties
atmosphere.clouds->position = Position3d(0.0f, 100.0f, 0.0f);
atmosphere.clouds->size = Size3d(500.0f, 80.0f, 500.0f);
atmosphere.clouds->density = 0.5f;
atmosphere.clouds->absorption = 1.2f;
atmosphere.clouds->scattering = 0.9f;
atmosphere.clouds->wind = Magnitude3d(0.05f, 0.0f, 0.02f);
atmosphere.clouds->primaryStepCount = 16; // Higher = better quality

Cloud Properties

position
Position3d
default:"{0.0f, 5.0f, 0.0f}"
Center of the cloud volume in world space
size
Size3d
default:"{10.0f, 3.0f, 10.0f}"
Dimensions of the cloud volume
scale
float
default:"1.5f"
Global scale factor applied during raymarching
offset
Position3d
default:"{0.0f, 0.0f, 0.0f}"
Texture offset applied to sample positions
density
float
default:"0.45f"
Base density threshold for cloud appearance
densityMultiplier
float
default:"1.5f"
Multiplier applied to density when shaping cloud clusters
absorption
float
default:"1.1f"
Governs how much light is absorbed when traveling through clouds
scattering
float
default:"0.85f"
Controls forward/backward scattering intensity
phase
float
default:"0.55f"
Phase function parameter used in lighting calculations
clusterStrength
float
default:"0.5f"
Strength of high-frequency clusters inside the volume
primaryStepCount
int
default:"12"
Number of primary raymarching steps per pixel. Higher values increase quality but reduce performance.
lightStepCount
int
default:"6"
Number of steps taken when computing lighting contributions
lightStepMultiplier
float
default:"1.6f"
Scales the distance between light steps
minStepLength
float
default:"0.05f"
Minimum step length to avoid undersampling
wind
Magnitude3d
default:"{0.02f, 0.0f, 0.01f}"
Wind vector influencing cloud movement

Weather System

Weather Conditions

Supported weather types:
  • WeatherCondition::Clear - No precipitation
  • WeatherCondition::Rain - Rain particles
  • WeatherCondition::Snow - Snow particles
  • WeatherCondition::Storm - Intense rain with strong wind

Setting Weather

// Enable weather system
atmosphere.enableWeather();

// Set weather delegate
atmosphere.weatherDelegate = [](ViewInformation viewInfo) {
    WeatherState weather;
    weather.condition = WeatherCondition::Rain;
    weather.intensity = 0.7f; // 0.0 to 1.0
    weather.wind = Magnitude3d(0.1f, -0.5f, 0.05f);
    return weather;
};

Dynamic Weather

// Time-based weather
atmosphere.weatherDelegate = [&atmosphere](ViewInformation viewInfo) {
    WeatherState weather;
    
    float time = atmosphere.timeOfDay;
    if (time >= 14.0f && time <= 18.0f) {
        // Afternoon storms
        weather.condition = WeatherCondition::Storm;
        weather.intensity = 0.8f;
        weather.wind = Magnitude3d(0.3f, -0.7f, 0.2f);
    } else if (time >= 20.0f || time <= 6.0f) {
        // Night/morning snow
        weather.condition = WeatherCondition::Snow;
        weather.intensity = 0.4f;
        weather.wind = Magnitude3d(0.05f, -0.2f, 0.05f);
    } else {
        weather.condition = WeatherCondition::Clear;
    }
    
    return weather;
};

Global Wind

// Set global wind affecting clouds and particles
atmosphere.wind = Magnitude3d(0.1f, 0.0f, 0.05f);

// Wind automatically propagates to clouds
atmosphere.addClouds();
// atmosphere.clouds->wind is automatically set

Sky Rendering

Procedural Skybox

// Create sky cubemap
Cubemap sky = atmosphere.createSkyCubemap(512); // Resolution

// Update existing cubemap
atmosphere.updateSkyCubemap(existingSky);

// Get current sky colors
std::array<Color, 6> skyColors = atmosphere.getSkyboxColors();

Shadow Casting

// Generate shadows from sun
atmosphere.castShadowsFromSunlight(2048); // Shadow map resolution

Complete Example

#include "hydra/atmosphere.h"

// Create atmosphere with day-night cycle
Atmosphere atmosphere;
atmosphere.timeOfDay = 14.5f; // 2:30 PM
atmosphere.secondsPerHour = 120.0f; // Fast time: 2 minutes per hour
atmosphere.cycle = true;
atmosphere.enable();

// Configure sun and moon
atmosphere.sunColor = Color(1.0, 0.95, 0.8);
atmosphere.moonColor = Color(0.5, 0.5, 0.9);
atmosphere.sunSize = 1.2f;
atmosphere.starIntensity = 2.5f;

// Add volumetric clouds
atmosphere.addClouds(4, 6);
atmosphere.clouds->position = Position3d(0.0f, 100.0f, 0.0f);
atmosphere.clouds->size = Size3d(500.0f, 80.0f, 500.0f);
atmosphere.clouds->density = 0.5f;
atmosphere.clouds->absorption = 1.2f;
atmosphere.clouds->scattering = 0.9f;
atmosphere.clouds->wind = Magnitude3d(0.05f, 0.0f, 0.02f);
atmosphere.clouds->primaryStepCount = 16;

// Set up dynamic weather
atmosphere.enableWeather();
atmosphere.weatherDelegate = [](ViewInformation viewInfo) {
    WeatherState weather;
    weather.condition = WeatherCondition::Rain;
    weather.intensity = 0.7f;
    weather.wind = Magnitude3d(0.1f, -0.5f, 0.05f);
    return weather;
};

// Configure scene lighting
atmosphere.useGlobalLight();

// Update each frame
while (running) {
    atmosphere.update(deltaTime);
    // ... render scene
}

Methods Reference

update()

Advances celestial bodies and weather simulation:
void update(float dt);

enable() / disable()

Activates or deactivates atmospheric rendering:
void enable();
void disable();
bool isEnabled() const;

enableWeather() / disableWeather()

Enables or disables weather particle systems:
void enableWeather();
void disableWeather();
For realistic day-night cycles, set secondsPerHour to 3600.0 (real-time) or lower values for faster time progression.
Higher primaryStepCount values in cloud configuration significantly impact performance. Start with 12-16 and adjust based on target hardware.

See Also

  • Fluids - Water surfaces that reflect atmospheric lighting
  • Terrain - Terrain systems that integrate with weather

Build docs developers (and LLMs) love