feat(lighting): corba additive separada al config
This commit is contained in:
1 parent
771ff1f6cd
commit
dacc4a9909
7 files changed
+100
-34
No files matched your search
@@ -26,9 +26,9 @@ namespace Lighting {
|
||||
return buf_;
|
||||
}
|
||||
|
||||
// Configuració global, inicialitzada amb els defaults compilats.
|
||||
// loadConfig() la reemplaça si troba el fitxer.
|
||||
auto activeConfig() -> GradientConfig& {
|
||||
// Corba activa del mode subtractive. loadConfig() la reemplaça
|
||||
// si troba el bloc `gradient:` al YAML.
|
||||
auto activeSubtractiveConfig() -> GradientConfig& {
|
||||
static GradientConfig cfg_{
|
||||
.inner_ratio = Defaults::Lighting::INNER_RATIO,
|
||||
.mid_ratio = Defaults::Lighting::MID_RATIO,
|
||||
@@ -39,6 +39,22 @@ namespace Lighting {
|
||||
return cfg_;
|
||||
}
|
||||
|
||||
// Corba activa del mode additive. Defaults baixos a propòsit:
|
||||
// en additive la intensitat és l'alfa del color afegit, així
|
||||
// que valors petits (0.05..0.15) donen el "halo subtil" que
|
||||
// sol voler-se. loadConfig() la reemplaça si troba el bloc
|
||||
// `gradient_additive:` al YAML.
|
||||
auto activeAdditiveConfig() -> GradientConfig& {
|
||||
static GradientConfig cfg_{
|
||||
.inner_ratio = Defaults::Lighting::INNER_RATIO_ADDITIVE,
|
||||
.mid_ratio = Defaults::Lighting::MID_RATIO_ADDITIVE,
|
||||
.inner_intensity = Defaults::Lighting::INNER_INTENSITY_ADDITIVE,
|
||||
.mid_intensity = Defaults::Lighting::MID_INTENSITY_ADDITIVE,
|
||||
.outer_intensity = Defaults::Lighting::OUTER_INTENSITY_ADDITIVE,
|
||||
};
|
||||
return cfg_;
|
||||
}
|
||||
|
||||
auto activeFlicker() -> FlickerConfig& {
|
||||
static FlickerConfig fc_{
|
||||
.wave_amplitude_px = Defaults::Lighting::FLICKER_WAVE_AMPLITUDE_PX,
|
||||
@@ -232,9 +248,22 @@ namespace Lighting {
|
||||
} // namespace
|
||||
|
||||
auto config() -> const GradientConfig& {
|
||||
return activeConfig();
|
||||
return activeSubtractiveConfig();
|
||||
}
|
||||
|
||||
namespace {
|
||||
// Llegeix els 5 camps de `GradientConfig` d'un node YAML — qualsevol
|
||||
// camp absent conserva el valor compilat dels defaults. Compartit
|
||||
// entre els blocs `gradient:` i `gradient_additive:`.
|
||||
void readGradient(const fkyaml::node& g, GradientConfig& cfg) {
|
||||
readField(g, "inner_ratio", cfg.inner_ratio);
|
||||
readField(g, "mid_ratio", cfg.mid_ratio);
|
||||
readField(g, "inner_intensity", cfg.inner_intensity);
|
||||
readField(g, "mid_intensity", cfg.mid_intensity);
|
||||
readField(g, "outer_intensity", cfg.outer_intensity);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void loadConfig(const std::string& yaml_path) {
|
||||
auto bytes = Resource::Helper::loadFile(yaml_path);
|
||||
if (bytes.empty()) {
|
||||
@@ -246,13 +275,10 @@ namespace Lighting {
|
||||
const auto* end = begin + bytes.size();
|
||||
auto yaml = fkyaml::node::deserialize(begin, end);
|
||||
if (yaml.contains("gradient")) {
|
||||
const auto& g = yaml["gradient"];
|
||||
auto& cfg = activeConfig();
|
||||
readField(g, "inner_ratio", cfg.inner_ratio);
|
||||
readField(g, "mid_ratio", cfg.mid_ratio);
|
||||
readField(g, "inner_intensity", cfg.inner_intensity);
|
||||
readField(g, "mid_intensity", cfg.mid_intensity);
|
||||
readField(g, "outer_intensity", cfg.outer_intensity);
|
||||
readGradient(yaml["gradient"], activeSubtractiveConfig());
|
||||
}
|
||||
if (yaml.contains("gradient_additive")) {
|
||||
readGradient(yaml["gradient_additive"], activeAdditiveConfig());
|
||||
}
|
||||
if (yaml.contains("flicker")) {
|
||||
const auto& f = yaml["flicker"];
|
||||
@@ -285,7 +311,7 @@ namespace Lighting {
|
||||
if (lum.size() != TOTAL) { lum.resize(TOTAL); }
|
||||
std::ranges::fill(lum, room);
|
||||
|
||||
const auto& cfg = activeConfig();
|
||||
const auto& cfg = activeSubtractiveConfig();
|
||||
const auto& fc = activeFlicker();
|
||||
const float T_S = static_cast<float>(SDL_GetTicks()) / 1000.0F;
|
||||
for (const auto& e : emitters) {
|
||||
@@ -303,7 +329,7 @@ namespace Lighting {
|
||||
// canvas, sense buffer intermig.
|
||||
void applyAdditive(std::uint32_t* canvas, int width, int height, std::uint8_t room, std::span<const Emitter> emitters) {
|
||||
darkenCanvas(canvas, width, height, room);
|
||||
const auto& cfg = activeConfig();
|
||||
const auto& cfg = activeAdditiveConfig();
|
||||
const auto& fc = activeFlicker();
|
||||
const float T_S = static_cast<float>(SDL_GetTicks()) / 1000.0F;
|
||||
for (const auto& e : emitters) {
|
||||
@@ -327,7 +353,7 @@ namespace Lighting {
|
||||
const std::uint8_t ROOM = toByte(room_light);
|
||||
if (ROOM == 255 && emitters.empty()) { return; }
|
||||
|
||||
if (mode == Mode::Additive) {
|
||||
if (mode == Mode::ADDITIVE) {
|
||||
applyAdditive(canvas, width, height, ROOM, emitters);
|
||||
} else {
|
||||
applySubtractive(canvas, width, height, ROOM, emitters);
|
||||
|
||||
@@ -33,6 +33,14 @@
|
||||
// inner_ratio..mid_ratio → mid_intensity
|
||||
// mid_ratio..1.0 → outer_intensity
|
||||
//
|
||||
// La corba viu en dos blocs separats al YAML perquè la mateixa escala
|
||||
// 0..1 té significats molt diferents per mode:
|
||||
// `gradient:` → corba del mode subtractive (1.0 = "no fosqueix")
|
||||
// `gradient_additive:` → corba del mode additive (1.0 = "afegeix
|
||||
// el color sencer i satura"). Es vol molt més
|
||||
// baixa per a no inundar la sala de color.
|
||||
// Cada mode llegeix la seva pròpia corba — no es comparteixen valors.
|
||||
//
|
||||
// Combinació entre emissors:
|
||||
// SUBTRACTIVE → per a cada píxel es pren el màxim de la intensitat
|
||||
// aportada per cada emissor que el solapa (no se sumen intensitats).
|
||||
@@ -45,8 +53,8 @@ namespace Lighting {
|
||||
// Mode de composició. La sala el selecciona via `lighting.mode:
|
||||
// additive | subtractive` (default subtractive si manca, retrocompat).
|
||||
enum class Mode : std::uint8_t {
|
||||
Subtractive,
|
||||
Additive,
|
||||
SUBTRACTIVE,
|
||||
ADDITIVE,
|
||||
};
|
||||
|
||||
// Color emès. Default blanc (sense modificació quan s'usa en mode
|
||||
@@ -104,7 +112,10 @@ namespace Lighting {
|
||||
// simplement reemplaça la configuració activa.
|
||||
void loadConfig(const std::string& yaml_path);
|
||||
|
||||
// Configuració activa (per a debug/inspectors). Inicialitzada amb els
|
||||
// Configuració activa (per a debug/inspectors). Retorna sempre la
|
||||
// corba subtractive — la corba additive viu en paral·lel al cpp i,
|
||||
// si algun dia es necessita inspeccionar des de fora, caldrà afegir
|
||||
// una variant `configAdditive()`. Inicialitzada amb els
|
||||
// Defaults::Lighting fins que loadConfig() es crida.
|
||||
[[nodiscard]] auto config() -> const GradientConfig&;
|
||||
|
||||
|
||||
Reference in new issue
Block a user