From 0545f93f24c686609d1eba9f6bc9450220f51460 Mon Sep 17 00:00:00 2001 From: Hirek193 Date: Mon, 19 Oct 2026 17:51:13 +0200 Subject: [PATCH] Keep the hotspotpower of light points apart from their colour --- betterRenderer/renderer/source/nvrenderer.cpp | 4 +- model/Model3d.cpp | 42 ++++++++++++------- model/Model3d.h | 2 +- rendering/opengl46/opengl46locallights.cpp | 4 +- 4 files changed, 31 insertions(+), 21 deletions(-) diff --git a/betterRenderer/renderer/source/nvrenderer.cpp b/betterRenderer/renderer/source/nvrenderer.cpp index 926666d5..398ffedb 100644 --- a/betterRenderer/renderer/source/nvrenderer.cpp +++ b/betterRenderer/renderer/source/nvrenderer.cpp @@ -2050,8 +2050,8 @@ void NvRenderer::Animate(Renderable &renderable, TSubModel *Submodel, Renderable::SpotLight &spotlight = renderable.m_spotlights.emplace_back(); spotlight.m_origin = model_transform[3]; spotlight.m_direction = glm::normalize(-model_transform[2]); - spotlight.m_color = - Submodel->f4Diffuse * Config()->m_lighting.m_freespot_multiplier; + spotlight.m_color = Submodel->f4Diffuse * Submodel->fHotspotPower * + Config()->m_lighting.m_freespot_multiplier; spotlight.m_cos_outer_cone = Submodel->fCosFalloffAngle; spotlight.m_cos_inner_cone = Submodel->fCosHotspotAngle; spotlight.m_radius = glm::sqrt( diff --git a/model/Model3d.cpp b/model/Model3d.cpp index 66fc08c9..80d7e577 100644 --- a/model/Model3d.cpp +++ b/model/Model3d.cpp @@ -360,19 +360,21 @@ std::pair TSubModel::Load(cParser &parser, bool dynamic) parser >> fNearAttenStart >> discard >> fNearAttenEnd >> discard >> bUseNearAtten >> discard >> iFarAttenDecay >> discard >> fFarDecayRadius >> discard >> fCosFalloffAngle // kąt liczony dla średnicy, a nie promienia >> discard >> fCosHotspotAngle; // kąt liczony dla średnicy, a nie promienia - // trzeba pobrac do kolejki 2 tokeny + // opcjonalne natężenie światła w procentach. trzeba pobrać do kolejki 2 tokeny; jeśli to nie hotspotpower, + // zostają w kolejce dla odczytu zasięgu widoczności, który przywraca autoclear parser.getTokens(2); if (parser.peek() == "hotspotpower:") { - float multiplier; - parser >> discard >> multiplier; - WriteLog("Found hotspot power!"); - // recaluclate multiplier - diffuseMultiplier = multiplier / 100.f; - - // apply color only on nvrenderer - if (Global.NvRenderer) - f4Diffuse *= diffuseMultiplier; + float power; + parser >> discard >> power; + if (power > 0.f) + { + fHotspotPower = power * 0.01f; + } + else + { + ErrorLog("Bad model: non-positive hotspotpower " + std::to_string(power) + " of light \"" + pName + "\" in model \"" + parser.Name() + "\", ignored", logtype::model); + } } else parser.autoclear(false); @@ -1814,7 +1816,10 @@ void TSubModel::serialize(std::ostream &s, std::vector &models, std sn_utils::ls_int32(s, m_geometry.index_offset); // external data - sn_utils::ls_float32(s, diffuseMultiplier); + // the slot of the former diffuse multiplier, by which the diffuse colour of light points was multiplied (or not, depending on + // the renderer the model was converted with). the colour is written as it is now, 1 makes older programs leave it so + sn_utils::ls_float32(s, 1.f); + sn_utils::ls_float32(s, fHotspotPower); // fill empty space size_t fill = end - s.tellp(); @@ -1986,10 +1991,17 @@ void TSubModel::deserialize(std::istream &s) m_geometry.index_offset = sn_utils::ld_int32(s); // extra data block - diffuseMultiplier = sn_utils::ld_float32(s); - // only multiply diffuse on experimental renderer - if (!Global.NvRenderer) - f4Diffuse /= diffuseMultiplier <= 0.0 ? 1.0 : diffuseMultiplier; + auto const diffusemultiplier{sn_utils::ld_float32(s)}; + fHotspotPower = sn_utils::ld_float32(s); + if (fHotspotPower <= 0.f) + { + // file without the power of its own, where the diffuse colour holds it, or files older than both: 0 in either slot + fHotspotPower = diffusemultiplier > 0.f ? diffusemultiplier : 1.f; + if (eType == TP_FREESPOTLIGHT) + { + f4Diffuse /= fHotspotPower; + } + } // necessary rotations were already done during t3d->e3d conversion m_rotation_init_done = true; diff --git a/model/Model3d.h b/model/Model3d.h index cd472b69..47987bf4 100644 --- a/model/Model3d.h +++ b/model/Model3d.h @@ -115,7 +115,7 @@ public: f4Emision { 1.0f,1.0f,1.0f,1.0f }; glm::vec3 DiffuseOverride { -1.f }; normalization m_normalizenormals { normalization::none }; // indicates vectors need to be normalized due to scaling etc - float diffuseMultiplier {1.0}; + float fHotspotPower { 1.0f }; // natężenie światła punktowego (hotspotpower/100), kolor określa tylko f4Diffuse float fWireSize { 0.0f }; // nie używane, ale wczytywane float fSquareMaxDist { 10000.0f * 10000.0f }; float fSquareMinDist { 0.0f }; diff --git a/rendering/opengl46/opengl46locallights.cpp b/rendering/opengl46/opengl46locallights.cpp index d38d84d0..cf8c3015 100644 --- a/rendering/opengl46/opengl46locallights.cpp +++ b/rendering/opengl46/opengl46locallights.cpp @@ -385,9 +385,7 @@ void opengl46_local_lights::add_light_point(TSubModel const &Submodel, glm::mat4 auto const diffuse{Submodel.DiffuseOverride.r < 0.f ? // -1 indicates no override glm::vec3{Submodel.f4Diffuse} : Submodel.DiffuseOverride}; - // hotspotpower of the model; this renderer keeps it apart from the colour - auto const multiplier{Submodel.diffuseMultiplier > 0.f ? Submodel.diffuseMultiplier : 1.f}; - auto const color{to_linear(diffuse) * (Brightness * multiplier * Submodel.fVisible * std::min(Submodel.f4Emision.a, 1.f))}; + auto const color{to_linear(diffuse) * (Brightness * Submodel.fHotspotPower * Submodel.fVisible * std::min(Submodel.f4Emision.a, 1.f))}; if (max_component(color) <= LIGHT_THRESHOLD) { return;