Integrate lighting system with renderer and shaders

Wire DBC-driven lighting to terrain shaders:
- Add LightingManager to Renderer
- Initialize lighting manager with AssetManager
- Update lighting each frame with player position
- Feed lighting params to terrain shader uniforms:
  * Ambient color
  * Diffuse (sun) color and direction
  * Fog color, start, end distances
- Fallback to skybox-based fog if lighting unavailable

TODOs for full integration:
- Wire actual map ID from game state
- Wire server game time from login packets
- Add weather/underwater state detection
- Apply lighting to WMO/M2/skybox shaders

Current state: Uses local time + Eastern Kingdoms map (0)
Next: Hook up SMSG_LOGIN_SETTIMESPEED for real game time
This commit is contained in:
Kelsi 2026-02-10 13:48:50 -08:00
parent 69fa4c6e03
commit 159a434c60
2 changed files with 40 additions and 1 deletions

View file

@ -26,6 +26,7 @@ class StarField;
class Clouds;
class LensFlare;
class Weather;
class LightingManager;
class SwimEffects;
class MountDust;
class CharacterRenderer;
@ -157,6 +158,7 @@ public:
audio::CombatSoundManager* getCombatSoundManager() { return combatSoundManager.get(); }
audio::SpellSoundManager* getSpellSoundManager() { return spellSoundManager.get(); }
audio::MovementSoundManager* getMovementSoundManager() { return movementSoundManager.get(); }
LightingManager* getLightingManager() { return lightingManager.get(); }
private:
core::Window* window = nullptr;
@ -173,6 +175,7 @@ private:
std::unique_ptr<Clouds> clouds;
std::unique_ptr<LensFlare> lensFlare;
std::unique_ptr<Weather> weather;
std::unique_ptr<LightingManager> lightingManager;
std::unique_ptr<SwimEffects> swimEffects;
std::unique_ptr<MountDust> mountDust;
std::unique_ptr<CharacterRenderer> characterRenderer;

View file

@ -12,6 +12,7 @@
#include "rendering/clouds.hpp"
#include "rendering/lens_flare.hpp"
#include "rendering/weather.hpp"
#include "rendering/lighting_manager.hpp"
#include "rendering/swim_effects.hpp"
#include "rendering/mount_dust.hpp"
#include "rendering/character_renderer.hpp"
@ -296,6 +297,14 @@ bool Renderer::initialize(core::Window* win) {
weather.reset();
}
// Create lighting system
lightingManager = std::make_unique<LightingManager>();
auto* assetManager = core::Application::getInstance().getAssetManager();
if (assetManager && !lightingManager->initialize(assetManager)) {
LOG_WARNING("Failed to initialize lighting manager");
lightingManager.reset();
}
// Create swim effects
swimEffects = std::make_unique<SwimEffects>();
if (!swimEffects->initialize()) {
@ -1193,6 +1202,19 @@ void Renderer::update(float deltaTime) {
lastCameraUpdateMs = 0.0;
}
// Update lighting system
if (lightingManager) {
// TODO: Get actual map ID from game state (0 = Eastern Kingdoms for now)
// TODO: Get actual game time from server (use -1 for local time fallback)
// TODO: Get weather/underwater state from game state
uint32_t mapId = 0; // Eastern Kingdoms
float gameTime = -1.0f; // Use local time for now
bool isRaining = false; // TODO: Get from weather system
bool isUnderwater = false; // TODO: Get from player state
lightingManager->update(characterPosition, mapId, gameTime, isRaining, isUnderwater);
}
// Sync character model position/rotation and animation with follow target
if (characterInstanceId > 0 && characterRenderer && cameraController && cameraController->isThirdPerson()) {
if (meleeSwingCooldown > 0.0f) {
@ -1800,7 +1822,21 @@ void Renderer::renderWorld(game::World* world) {
canalUnderwater = liquidType && (*liquidType == 5 || *liquidType == 13 || *liquidType == 17);
}
if (skybox) {
// Apply lighting from lighting manager
if (lightingManager) {
const auto& lighting = lightingManager->getLightingParams();
// Set lighting (direction, color, ambient)
float lightDir[3] = {lighting.directionalDir.x, lighting.directionalDir.y, lighting.directionalDir.z};
float lightColor[3] = {lighting.diffuseColor.r, lighting.diffuseColor.g, lighting.diffuseColor.b};
float ambientColor[3] = {lighting.ambientColor.r, lighting.ambientColor.g, lighting.ambientColor.b};
terrainRenderer->setLighting(lightDir, lightColor, ambientColor);
// Set fog
float fogColor[3] = {lighting.fogColor.r, lighting.fogColor.g, lighting.fogColor.b};
terrainRenderer->setFog(fogColor, lighting.fogStart, lighting.fogEnd);
} else if (skybox) {
// Fallback to skybox-based fog if no lighting manager
glm::vec3 horizonColor = skybox->getHorizonColor(timeOfDay);
float fogColorArray[3] = {horizonColor.r, horizonColor.g, horizonColor.b};
terrainRenderer->setFog(fogColorArray, 400.0f, 1200.0f);