Kelsidavis-WoWee/src/rendering/sky_system.cpp
Kelsi 6563eebb60 Enhanced sky atmosphere with DBC-driven colors, sun lighting, and zone weather
- Skybox now uses DBC sky colors (skyTop/skyMiddle/skyBand1/skyBand2) instead
  of hardcoded C++ color curves, with 3-band gradient and Rayleigh/Mie scattering
- Clouds receive sun direction for lit edges, self-shadowing, and silver lining
- Fixed sun quad box artifact with proper edge fade in celestial shader
- Lens flare attenuated by fog, cloud density, and weather intensity
- Replaced garish green/purple lens flare ghosts with warm natural palette
- Added zone-based weather system for single-player mode with per-zone rain/snow
  configuration, probability-based activation, and smooth intensity transitions
- Server SMSG_WEATHER remains authoritative when connected to a server
2026-02-22 23:20:13 -08:00

183 lines
5.1 KiB
C++

#include "rendering/sky_system.hpp"
#include "rendering/skybox.hpp"
#include "rendering/celestial.hpp"
#include "rendering/starfield.hpp"
#include "rendering/clouds.hpp"
#include "rendering/lens_flare.hpp"
#include "rendering/camera.hpp"
#include "rendering/vk_context.hpp"
#include "core/logger.hpp"
namespace wowee {
namespace rendering {
SkySystem::SkySystem() = default;
SkySystem::~SkySystem() {
shutdown();
}
bool SkySystem::initialize(VkContext* ctx, VkDescriptorSetLayout perFrameLayout) {
if (initialized_) {
LOG_WARNING("SkySystem already initialized");
return true;
}
LOG_INFO("Initializing sky system");
// Skybox (Vulkan)
skybox_ = std::make_unique<Skybox>();
if (!skybox_->initialize(ctx, perFrameLayout)) {
LOG_ERROR("Failed to initialize skybox");
return false;
}
// Celestial bodies — sun + 2 moons (Vulkan)
celestial_ = std::make_unique<Celestial>();
if (!celestial_->initialize(ctx, perFrameLayout)) {
LOG_ERROR("Failed to initialize celestial bodies");
return false;
}
// Procedural stars — fallback / debug (Vulkan)
starField_ = std::make_unique<StarField>();
if (!starField_->initialize(ctx, perFrameLayout)) {
LOG_ERROR("Failed to initialize star field");
return false;
}
starField_->setEnabled(false); // Off by default; skybox is authoritative
// Clouds (Vulkan)
clouds_ = std::make_unique<Clouds>();
if (!clouds_->initialize(ctx, perFrameLayout)) {
LOG_ERROR("Failed to initialize clouds");
return false;
}
// Lens flare (Vulkan)
lensFlare_ = std::make_unique<LensFlare>();
if (!lensFlare_->initialize(ctx, perFrameLayout)) {
LOG_ERROR("Failed to initialize lens flare");
return false;
}
initialized_ = true;
LOG_INFO("Sky system initialized successfully");
return true;
}
void SkySystem::shutdown() {
if (!initialized_) {
return;
}
LOG_INFO("Shutting down sky system");
if (lensFlare_) lensFlare_->shutdown();
if (clouds_) clouds_->shutdown();
if (starField_) starField_->shutdown();
if (celestial_) celestial_->shutdown();
if (skybox_) skybox_->shutdown();
lensFlare_.reset();
clouds_.reset();
starField_.reset();
celestial_.reset();
skybox_.reset();
initialized_ = false;
}
void SkySystem::update(float deltaTime) {
if (!initialized_) {
return;
}
if (skybox_) skybox_->update(deltaTime);
if (celestial_) celestial_->update(deltaTime);
if (starField_) starField_->update(deltaTime);
if (clouds_) clouds_->update(deltaTime);
}
void SkySystem::render(VkCommandBuffer cmd, VkDescriptorSet perFrameSet,
const Camera& camera, const SkyParams& params) {
if (!initialized_) {
return;
}
// --- Skybox (authoritative sky gradient, DBC-driven colors) ---
if (skybox_) {
skybox_->render(cmd, perFrameSet, params);
}
// --- Procedural stars (debug / fallback) ---
bool renderProceduralStars = false;
if (debugSkyMode_) {
renderProceduralStars = true;
} else if (proceduralStarsEnabled_) {
renderProceduralStars = !params.skyboxHasStars;
}
if (starField_) {
starField_->setEnabled(renderProceduralStars);
if (renderProceduralStars) {
const float cloudDensity = params.cloudDensity;
const float fogDensity = params.fogDensity;
starField_->render(cmd, perFrameSet, params.timeOfDay, cloudDensity, fogDensity);
}
}
// --- Celestial bodies (sun + White Lady + Blue Child) ---
if (celestial_) {
celestial_->render(cmd, perFrameSet, params.timeOfDay,
&params.directionalDir, &params.sunColor, params.gameTime);
}
// --- Clouds (DBC-driven colors + sun lighting) ---
if (clouds_) {
clouds_->render(cmd, perFrameSet, params);
}
// --- Lens flare (attenuated by atmosphere) ---
if (lensFlare_) {
glm::vec3 sunPos = getSunPosition(params);
lensFlare_->render(cmd, camera, sunPos, params.timeOfDay,
params.fogDensity, params.cloudDensity,
params.weatherIntensity);
}
}
glm::vec3 SkySystem::getSunPosition(const SkyParams& params) const {
glm::vec3 dir = glm::normalize(params.directionalDir);
if (glm::length(dir) < 0.0001f) {
dir = glm::vec3(0.0f, 0.0f, -1.0f);
}
glm::vec3 sunDir = -dir;
if (sunDir.z < 0.0f) {
sunDir = dir;
}
return sunDir * 800.0f;
}
void SkySystem::setMoonPhaseCycling(bool enabled) {
if (celestial_) celestial_->setMoonPhaseCycling(enabled);
}
void SkySystem::setWhiteLadyPhase(float phase) {
if (celestial_) celestial_->setMoonPhase(phase);
}
void SkySystem::setBlueChildPhase(float phase) {
if (celestial_) celestial_->setBlueChildPhase(phase);
}
float SkySystem::getWhiteLadyPhase() const {
return celestial_ ? celestial_->getMoonPhase() : 0.5f;
}
float SkySystem::getBlueChildPhase() const {
return celestial_ ? celestial_->getBlueChildPhase() : 0.25f;
}
} // namespace rendering
} // namespace wowee