From a8a2ad5582159a00b011186d9d843df0104d1e7a Mon Sep 17 00:00:00 2001 From: German Khokhlov Date: Fri, 16 Oct 2026 14:29:31 +0400 Subject: [PATCH] refactor(ui): engine-specific sharpen defaults instead of reading 49 as 80 The baseline and the style presets name ENGINE_SHARPEN_DEFAULT, which resolves to 49 % on Cesium and 80 % on Navara. Share links and explicit calls restore their value unchanged. --- src/ui/stateOwners.test.mjs | 5 ++++ src/ui/visualEffects.test.mjs | 40 +++++++++++++++++--------- src/ui/visualPresets.js | 40 ++++++++++++++++---------- src/ui/visualSettings.js | 54 +++++++++++------------------------ 4 files changed, 73 insertions(+), 66 deletions(-) diff --git a/src/ui/stateOwners.test.mjs b/src/ui/stateOwners.test.mjs index 0c9ca8aab..12637fdd2 100644 --- a/src/ui/stateOwners.test.mjs +++ b/src/ui/stateOwners.test.mjs @@ -182,6 +182,7 @@ test('on Navara, presets set the Sharpen slider to 80 % and the engine draws it' governorRequestRender() {}, holdContinuousRender() {}, releaseContinuousRender() {}, + setKeyholeFadeTuning() {}, }, readHud: () => ({ getVariant: () => 'tactical', setMode() {} }), }); @@ -195,5 +196,9 @@ test('on Navara, presets set the Sharpen slider to 80 % and the engine draws it' { enabled: true }, { amount: 1.7000000000000002 }, ]); + // A share link carries an explicit value: 49 stays 49 on Navara. + await owner.restoreShareState({ sharpenIntensity: 49, sharpen: true }); + assert.equal(elements._sharpenSlider.value, '49'); + assert.deepEqual(sharpen.at(-1), { amount: 1.08 }); owner.destroy(); }); diff --git a/src/ui/visualEffects.test.mjs b/src/ui/visualEffects.test.mjs index 40f6de9dc..a564008ca 100644 --- a/src/ui/visualEffects.test.mjs +++ b/src/ui/visualEffects.test.mjs @@ -5,10 +5,10 @@ import { GLOBAL_POST_DEFAULTS, STYLE_PRESET_DEFAULTS, MILITARY_DETECTION_PRESET, - NAVARA_SHARPEN_INTENSITY_DEFAULT, - SHARPEN_INTENSITY_DEFAULT, + ENGINE_SHARPEN_DEFAULT, + SHARPEN_INTENSITY_DEFAULTS, + presetSharpenIntensity, sharpenAmount, - sharpenIntensityForEngine, } from './visualPresets.js'; function fixture(engine = null) { @@ -234,15 +234,26 @@ test('with a viewer the Cesium stage sharpens and the engine is left alone', () f.effects.destroy(); }); -test('Navara reads the Cesium sharpen default as 80 %, other values stay', () => { - assert.equal(SHARPEN_INTENSITY_DEFAULT, 49); - assert.equal(NAVARA_SHARPEN_INTENSITY_DEFAULT, 80); - assert.equal(sharpenIntensityForEngine(49, 'navara'), 80); - assert.equal(sharpenIntensityForEngine(49, 'cesium'), 49); - assert.equal(sharpenIntensityForEngine(65, 'navara'), 65); - assert.equal(sharpenIntensityForEngine(0, 'navara'), 0); - for (const preset of Object.values(STYLE_PRESET_DEFAULTS)) - assert.equal(preset.sharpen.intensity, SHARPEN_INTENSITY_DEFAULT); +test('presets and the baseline take the engine default sharpen: Cesium 49 %, Navara 80 %', () => { + assert.deepEqual(SHARPEN_INTENSITY_DEFAULTS, { cesium: 49, navara: 80 }); + for (const preset of [ + GLOBAL_POST_DEFAULTS, + ...Object.values(STYLE_PRESET_DEFAULTS), + ]) { + assert.equal(preset.sharpen.intensity, ENGINE_SHARPEN_DEFAULT); + assert.equal( + presetSharpenIntensity(preset.sharpen.intensity, 'cesium'), + 49, + ); + assert.equal( + presetSharpenIntensity(preset.sharpen.intensity, 'navara'), + 80, + ); + } + assert.equal(presetSharpenIntensity(ENGINE_SHARPEN_DEFAULT, undefined), 49); + // An explicit value is never remapped: 49 stays 49 on Navara. + assert.equal(presetSharpenIntensity(49, 'navara'), 49); + assert.equal(presetSharpenIntensity(65, 'cesium'), 65); }); test('stop revokes pending work immediately but retains stages until final destruction', () => { @@ -292,7 +303,10 @@ test('destroying one instance does not remove another pipeline or clock', () => test('existing baseline and military presets keep one detection default', () => { assert.equal(GLOBAL_POST_DEFAULTS.detectionMode, 'DENSE'); assert.equal(GLOBAL_POST_DEFAULTS.detectionDensity, 75); - assert.equal(GLOBAL_POST_DEFAULTS.sharpen.intensity, 49); + assert.equal( + presetSharpenIntensity(GLOBAL_POST_DEFAULTS.sharpen.intensity, 'cesium'), + 49, + ); assert.equal(GLOBAL_POST_DEFAULTS.detectionFadePct, 7); assert.equal(GLOBAL_POST_DEFAULTS.detectionOutsideOpacityPct, 1); for (const name of ['retro', 'surveillance', 'thermal']) { diff --git a/src/ui/visualPresets.js b/src/ui/visualPresets.js index 34d948e3b..dbf950d85 100644 --- a/src/ui/visualPresets.js +++ b/src/ui/visualPresets.js @@ -40,20 +40,30 @@ export const MILITARY_DETECTION_PRESET = Object.freeze({ densityPct: 75, }); -/** The Sharpen slider's default (%) on Cesium, in every preset. */ -export const SHARPEN_INTENSITY_DEFAULT = 49; -/** The Sharpen slider's default (%) on the Navara engine. */ -export const NAVARA_SHARPEN_INTENSITY_DEFAULT = 80; +/** The Sharpen slider's default (%) on each globe engine. */ +export const SHARPEN_INTENSITY_DEFAULTS = Object.freeze({ + cesium: 49, + navara: 80, +}); /** - * The sharpen intensity (%) a default, a preset or a share link sets on an - * engine: Navara reads Cesium's default (49, every preset's value) as its own - * default (80); any other value, and everything on Cesium, stays as given. + * A preset's sharpen intensity that means "the engine's default" + * (SHARPEN_INTENSITY_DEFAULTS): the baseline and every style preset use it, + * so Cesium opens and switches styles at 49 % and Navara at 80 %. */ -export function sharpenIntensityForEngine(pct, engineKind) { - return engineKind === 'navara' && pct === SHARPEN_INTENSITY_DEFAULT - ? NAVARA_SHARPEN_INTENSITY_DEFAULT - : pct; +export const ENGINE_SHARPEN_DEFAULT = 'engine-default'; + +/** + * The intensity (%) a preset sets on an engine: its engine's default for + * ENGINE_SHARPEN_DEFAULT (Cesium's for an unknown engine), else the explicit + * value as given. Share links and scene shots carry explicit values and do + * not come through here. + */ +export function presetSharpenIntensity(intensity, engineKind) { + if (intensity !== ENGINE_SHARPEN_DEFAULT) return intensity; + return ( + SHARPEN_INTENSITY_DEFAULTS[engineKind] ?? SHARPEN_INTENSITY_DEFAULTS.cesium + ); } /** The unsharp mask's `amount` for a slider value normalized to 0..1. */ @@ -62,7 +72,7 @@ export const sharpenAmount = (value) => 0.1 + value * 2.0; /** Baseline post-processing settings applied on first load (before share-link restore). */ export const GLOBAL_POST_DEFAULTS = { bloom: { enabled: false, intensity: BLOOM_INTENSITY_DEFAULT }, - sharpen: { enabled: true, intensity: SHARPEN_INTENSITY_DEFAULT }, + sharpen: { enabled: true, intensity: ENGINE_SHARPEN_DEFAULT }, hudVariant: 'tactical', hudVisible: true, // Detection is ON for EVERY style on a first run, Normal included (owner @@ -88,7 +98,7 @@ export const GLOBAL_POST_DEFAULTS = { export const STYLE_PRESET_DEFAULTS = { retro: { bloom: { enabled: false, intensity: BLOOM_INTENSITY_DEFAULT }, - sharpen: { enabled: true, intensity: SHARPEN_INTENSITY_DEFAULT }, + sharpen: { enabled: true, intensity: ENGINE_SHARPEN_DEFAULT }, styleParams: { retro: { pixelation: 1.0, @@ -102,7 +112,7 @@ export const STYLE_PRESET_DEFAULTS = { }, surveillance: { bloom: { enabled: false, intensity: BLOOM_INTENSITY_DEFAULT }, - sharpen: { enabled: true, intensity: SHARPEN_INTENSITY_DEFAULT }, + sharpen: { enabled: true, intensity: ENGINE_SHARPEN_DEFAULT }, styleParams: { surveillance: { gain: 0.18, @@ -117,7 +127,7 @@ export const STYLE_PRESET_DEFAULTS = { }, thermal: { bloom: { enabled: false, intensity: BLOOM_INTENSITY_DEFAULT }, - sharpen: { enabled: true, intensity: SHARPEN_INTENSITY_DEFAULT }, + sharpen: { enabled: true, intensity: ENGINE_SHARPEN_DEFAULT }, styleParams: { thermal: { sensitivity: 0.85, diff --git a/src/ui/visualSettings.js b/src/ui/visualSettings.js index 2b4ec59cd..8a5e69a55 100644 --- a/src/ui/visualSettings.js +++ b/src/ui/visualSettings.js @@ -1,6 +1,6 @@ import { STYLE_STATUS_LABELS, - sharpenIntensityForEngine, + presetSharpenIntensity, } from './visualPresets.js'; import { UiLifetime } from './uiLifetime.js'; import { @@ -95,15 +95,7 @@ export class VisualSettings { this._setBloomIntensity(intensity, { syncShare: false }); } if (typeof sharpenIntensity === 'number' && this._sharpenSlider) { - const pct = Math.max( - 0, - Math.min( - 100, - Math.round( - sharpenIntensityForEngine(sharpenIntensity, this._engineKind), - ), - ), - ); + const pct = Math.max(0, Math.min(100, Math.round(sharpenIntensity))); this._sharpenSlider.value = String(pct); this._sharpenSliderValue.textContent = `${pct}%`; this._applySharpenIntensity(pct / 100); @@ -201,8 +193,8 @@ export class VisualSettings { readDisplayPortalActive, }); this._lifetime = new UiLifetime(); - // Defaults, presets and share links read Cesium's sharpen default as the - // engine's own (sharpenIntensityForEngine). + // The baseline and the style presets take this engine's default sharpen + // (presetSharpenIntensity); share links restore their explicit value. this._engineKind = engine?.kind ?? 'cesium'; this._visualEffects = new VisualEffects({ viewer, @@ -759,16 +751,12 @@ export class VisualSettings { } const sharpenInput = preset.sharpen || {}; - if (typeof sharpenInput.intensity === 'number' && this._sharpenSlider) { - const sharpenPct = Math.max( - 0, - Math.min( - 100, - Math.round( - sharpenIntensityForEngine(sharpenInput.intensity, this._engineKind), - ), - ), - ); + const presetSharpen = presetSharpenIntensity( + sharpenInput.intensity, + this._engineKind, + ); + if (typeof presetSharpen === 'number' && this._sharpenSlider) { + const sharpenPct = Math.max(0, Math.min(100, Math.round(presetSharpen))); this._sharpenSlider.value = String(sharpenPct); this._sharpenSliderValue.textContent = `${sharpenPct}%`; this._applySharpenIntensity(sharpenPct / 100); @@ -819,22 +807,12 @@ export class VisualSettings { this._setBloomEnabled(defaults.bloom.enabled); } - if ( - typeof defaults.sharpen?.intensity === 'number' && - this._sharpenSlider - ) { - const sharpenPct = Math.max( - 0, - Math.min( - 100, - Math.round( - sharpenIntensityForEngine( - defaults.sharpen.intensity, - this._engineKind, - ), - ), - ), - ); + const defaultSharpen = presetSharpenIntensity( + defaults.sharpen?.intensity, + this._engineKind, + ); + if (typeof defaultSharpen === 'number' && this._sharpenSlider) { + const sharpenPct = Math.max(0, Math.min(100, Math.round(defaultSharpen))); this._sharpenSlider.value = String(sharpenPct); this._sharpenSliderValue.textContent = `${sharpenPct}%`; this._applySharpenIntensity(sharpenPct / 100);