Files
Vibe-HD-2D/engine/include/hd2d/Weather.h
Gabrieal Jimmy 83a1f16806 Sprite sheets, atlases, game UI, time of day, weather presets, headless captures
- BillboardInstance: per-instance uv sub-rect, feet anchor, turn, dithered alpha, flash;
  BillboardBatch::sharedTexture; Texture createEmpty/update/cellUV/cellAnchor/nearest
- SpriteAtlas: fixed-cell runtime atlas with gutters
- hd2d::ui: Octopath-style panels, fonts (Cinzel, EB Garamond), dialogue box with
  typewriter + portraits + choices, menus, nameplates, toasts, ImGui theme
- DayCycle (dawn/day/dusk/night keyframes, sun + moon arcs), Weather overcast/mist/
  lightning, night-aware presets, stars and moon in the sky
- Hidden-window offscreen captures (Window visible=false, Renderer output FBO,
  OffscreenTarget); --screenshot never opens a window
- Camera::worldToScreen; CMake usable via add_subdirectory (HD2D_BUILD_DEMO,
  HD2D_ENGINE_ASSET_DIR)
2026-10-02 15:05:23 -05:00

96 lines
4.4 KiB
C++

#pragma once
#include "hd2d/Scene.h"
#include <glm/glm.hpp>
#include <random>
namespace hd2d {
struct RenderSettings;
// Everything time of day and weather change about the look, so it can be
// blended. One look fully describes the lighting of a frame.
struct WeatherLook {
// Directional light: the sun by day, the moon at night (shadows follow it).
float sunAzimuth = -0.6f, sunElevation = 0.66f; // radians, see Sun
float sunIntensity = 0.0f;
glm::vec3 sunColor{1.0f};
glm::vec3 zenith{0.5f}, horizon{0.5f}, ground{0.2f};
float ambient = 0.5f, fill = 0.35f;
float night = 0.0f; // 0..1: star field + moon disc (Sky::night)
float clouds = 0.0f; // 0..1: extra sky cloud cover (Sky::clouds)
float daylight = 1.0f; // 0 night .. 1 day: scales weather presets (a storm at night is dark)
glm::vec3 fogColor{0.5f};
float fogDensity = 0.0f, fogHeightFalloff = 0.1f, godRays = 0.0f, shaftStrength = 0.0f, cookieStrength = 0.0f;
float shadowSoftness = 1.5f;
float windStrength = 0.0f, windGustSpeed = 0.0f;
float bloomStrength = 0.0f, saturation = 1.0f, exposure = 1.0f;
glm::vec3 lift{0.0f}; // grading lift (shadow tint)
glm::vec3 gain{1.0f}; // grading gain (highlight tint)
float fireflyGlow = 1.0f; // ParticleSystem::fireflyGlow (raise at night)
};
// Linear blend of every field (t = 0: a, t = 1: b).
WeatherLook mixLooks(const WeatherLook& a, const WeatherLook& b, float t);
// Blends the scene from its clear-weather look toward overcast, fog (mist)
// and storm presets, and drives rain intensity, wetness, ground splashes,
// lightning and the fading of ambient particles.
//
// The clear look is either captured from the current scene + settings while
// the weather is fully clear (so manual tuning is kept), or supplied every
// frame with setClearLook() (e.g. from a DayCycle). Presets are authored at
// full daylight and darkened by the clear look's `daylight`.
class Weather {
public:
Weather();
// Replaces the captured clear look (call every frame, e.g. with
// DayCycle::look(hour)). Once called, the scene is no longer captured.
void setClearLook(const WeatherLook& look);
void setRain(float target) { targetRain_ = glm::clamp(target, 0.0f, 1.0f); }
void setOvercast(float target) { targetOvercast_ = glm::clamp(target, 0.0f, 1.0f); }
void setFog(float target) { targetFog_ = glm::clamp(target, 0.0f, 1.0f); }
void setLightning(bool enabled) { lightning_ = enabled; } // occasional flashes while raining
float targetRain() const { return targetRain_; }
float targetOvercast() const { return targetOvercast_; }
float targetFog() const { return targetFog_; }
bool lightning() const { return lightning_; }
float rain() const { return rain_; }
float overcast() const { return overcast_; }
float fog() const { return fog_; }
// Jumps straight to every target (no transition), e.g. for screenshots.
void snap();
void update(float dt, Scene& scene, RenderSettings& settings);
// Presets at full daylight. Time-of-day fields (sun direction, night,
// daylight, exposure, lift, gain, fill, fireflies) always come from the clear look.
WeatherLook storm; // full rain intensity
WeatherLook overcastLook; // grey sky, weak sun, soft shadows
WeatherLook mist; // thick low fog (morning mist)
float nightBrightness = 0.3f; // preset brightness at daylight = 0
float transitionSeconds = 5.0f; // fade time for every target
float splashesPerSecond = 500.0f;
float splashRadius = 12.0f; // around Scene::focusPoint
float lightningInterval = 7.0f; // mean seconds between flashes at full rain
// The look currently set on a scene + settings (e.g. a hand-tuned noon).
static WeatherLook capture(const Scene& scene, const RenderSettings& settings);
private:
static void apply(const WeatherLook& look, Scene& scene, RenderSettings& settings);
WeatherLook relative(const WeatherLook& preset, float hueKeep) const;
bool clear() const;
WeatherLook clear_;
bool haveClear_ = false, externalClear_ = false, lightning_ = false;
float rain_ = 0.0f, targetRain_ = 0.0f, wetness_ = 0.0f, splashAccum_ = 0.0f;
float overcast_ = 0.0f, targetOvercast_ = 0.0f, fog_ = 0.0f, targetFog_ = 0.0f;
float flash_ = 0.0f, flashAge_ = 1e3f, nextFlash_ = 3.0f;
std::mt19937 rng_{99};
};
} // namespace hd2d