feat(lighting): flicker proporcional al radi amb overrides per emissor

This commit is contained in:
JailDesigner committed 2026-05-13 19:38:34 +02:00
1 parent 3a42c7958a
commit 2272d3a37a
13 files changed
+298 -150

No files matched your search

+38 -22
View File
@@ -67,6 +67,32 @@ namespace Lighting {
std::uint8_t b{255};
};
// Forma del gradient. Compartida per tots els emissors per evitar
// duplicar la corba a cada YAML d'entitat. Càrrega via loadConfig.
struct GradientConfig {
float inner_ratio{0.8F};
float mid_ratio{0.9F};
float inner_intensity{1.0F};
float mid_intensity{0.9F};
float outer_intensity{0.8F};
};
// Paràmetres del flicker per a emissors amb `flicker=true`. La
// forma final del radi és la suma d'una sinusoide "respiració"
// (wave_*) i una sinusoide secundària de freqüència més alta
// (noise_*) que aporta la sensació d'inquietud. Les fases es
// deriven de la seed estable de cada emissor — sense estat per
// emissor. Les amplituds són **ràtios** sobre el radi base (p.ex.
// 0.05 = 5% del radi): així una torxa de radi 40 i una de radi 24
// tenen el mateix percentatge d'oscil·lació visual, no els mateixos
// píxels (que es notarien més en la petita).
struct FlickerConfig {
float wave_amplitude_ratio{0.05F};
float wave_frequency_hz{3.0F};
float noise_amplitude_ratio{0.025F};
float noise_frequency_hz{7.0F};
};
// Posició al canvas (en píxels, mateixa unitat que la resta del
// motor) i radi efectiu de l'emissor. El centre és el del sprite
// visible: és l'entitat qui sap on cau (veure `Entity::getLightCenter`).
@@ -82,28 +108,12 @@ namespace Lighting {
int seed{0};
bool flicker{false};
Color color{};
};
// Forma del gradient. Compartida per tots els emissors per evitar
// duplicar la corba a cada YAML d'entitat. Càrrega via loadConfig.
struct GradientConfig {
float inner_ratio{0.8F};
float mid_ratio{0.9F};
float inner_intensity{1.0F};
float mid_intensity{0.9F};
float outer_intensity{0.8F};
};
// Paràmetres del flicker per a emissors amb `flicker=true`. La
// forma final del radi és la suma d'una sinusoide "respiració"
// (wave_*) i una sinusoide secundària de freqüència més alta
// (noise_*) que aporta la sensació d'inquietud. Les fases es
// deriven de la posició de cada emissor — sense estat per emissor.
struct FlickerConfig {
float wave_amplitude_px{2.0F};
float wave_frequency_hz{3.0F};
float noise_amplitude_px{1.0F};
float noise_frequency_hz{7.0F};
// Paràmetres del flicker resolts per a aquest emissor (combinació
// global + override del tipus/sala/spawn). Només té sentit si
// `flicker == true`; en cas contrari s'ignoren. Per defecte
// s'inicialitza amb els defaults compilats — el caller (game_scene)
// hi posa el resolt correcte.
FlickerConfig flicker_params{};
};
// Llegeix `yaml_path` (data/config/lighting.yaml) i pobla la
@@ -119,6 +129,12 @@ namespace Lighting {
// Defaults::Lighting fins que loadConfig() es crida.
[[nodiscard]] auto config() -> const GradientConfig&;
// Defaults globals del flicker (data/config/lighting.yaml, bloc
// `flicker:`). Els callers del construct path d'entitats el llegeixen
// per inicialitzar la `FlickerConfig` de cada emissor, i aplicar a
// sobre els overrides per tipus/sala/spawn.
[[nodiscard]] auto flickerConfig() -> const FlickerConfig&;
// Aplica la pasada d'il·luminació al canvas in-place. `mode`
// selecciona la composició (vegeu el comentari de la capçalera).
// `room_light` és l'atenuació ambient de la sala (0..1, 1 = sense