Implement WoW-accurate DBC-driven sky system with lore-faithful celestial bodies

Add SkySystem coordinator that follows WoW's actual architecture where skyboxes
are authoritative and procedural elements serve as fallbacks. Integrate lighting
system across all renderers (terrain, WMO, M2, character) with unified parameters.

Sky System:
- SkySystem coordinator manages skybox, celestial bodies, stars, clouds, lens flare
- Skybox is authoritative (baked stars from M2 models, procedural fallback only)
- skyboxHasStars flag gates procedural star rendering (prevents double-star bug)

Celestial Bodies (Lore-Accurate):
- Two moons: White Lady (30-day cycle, pale white) + Blue Child (27-day cycle, pale blue)
- Deterministic moon phases from server gameTime (not deltaTime toys)
- Sun positioning driven by LightingManager directionalDir (DBC-sourced)
- Camera-locked sky dome (translation ignored, rotation applied)

Lighting Integration:
- Apply LightingManager params to WMO, M2, character renderers
- Unified lighting: directional light, diffuse color, ambient color, fog
- Star occlusion by cloud density (70% weight) and fog density (30% weight)

Documentation:
- Add comprehensive SKY_SYSTEM.md technical guide
- Update MEMORY.md with sky system architecture and anti-patterns
- Update README.md with WoW-accurate descriptions

Critical design decisions:
- NO latitude-based star rotation (Azeroth not modeled as spherical planet)
- NO always-on procedural stars (skybox authority prevents zone identity loss)
- NO universal dual-moon setup (map-specific celestial configurations)
This commit is contained in:
Kelsi 2026-02-10 14:36:17 -08:00
parent 159a434c60
commit 8e60d0e781
16 changed files with 1036 additions and 47 deletions

View file

@ -98,7 +98,8 @@ void StarField::shutdown() {
stars.clear();
}
void StarField::render(const Camera& camera, float timeOfDay) {
void StarField::render(const Camera& camera, float timeOfDay,
float cloudDensity, float fogDensity) {
if (!renderingEnabled || vao == 0 || !starShader || stars.empty()) {
return;
}
@ -106,6 +107,10 @@ void StarField::render(const Camera& camera, float timeOfDay) {
// Get star intensity based on time of day
float intensity = getStarIntensity(timeOfDay);
// Reduce intensity based on cloud density and fog (more clouds/fog = fewer visible stars)
intensity *= (1.0f - glm::clamp(cloudDensity * 0.7f, 0.0f, 1.0f));
intensity *= (1.0f - glm::clamp(fogDensity * 0.3f, 0.0f, 1.0f));
// Don't render if stars would be invisible
if (intensity <= 0.01f) {
return;