mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-11 13:52:19 +00:00
Keep scaling the shared atmosphere vectors in place, and take a rebuilt globe's base from the value they had before any scaling
Pointing the scaled uniforms at the scaler's own vectors (bc1b56b6) left the atmosphere unscaled: takram's materials read the AtmosphereParameters.DEFAULT vectors themselves, so the frame dimmed (luma 161 against 214) and qa-navara-bloom found nothing to bloom. The scaler writes those vectors in place again, and a page-wide map keeps each one's value from before it was first scaled: a globe built later on the page takes its base from there instead of from the scaled value. Bloom measures as before (214.4 → 240.3), and qa-strict-context-loss passes 3 of 3 under eight busy threads.
This commit is contained in:
1 parent
bc1b56b63a
commit
06ae95ceb3
2 files changed
+33
-45
No files matched your search
+29
-38
@@ -253,70 +253,62 @@ const IRRADIANCE_OFF = Object.freeze({
|
|||||||
const VISIBLE = Object.freeze({ visible: true });
|
const VISIBLE = Object.freeze({ visible: true });
|
||||||
const HIDDEN = Object.freeze({ visible: false });
|
const HIDDEN = Object.freeze({ visible: false });
|
||||||
|
|
||||||
|
// Every luminance vector a scaler has written, with the value it had
|
||||||
|
// before: one map for the page, as the vectors are.
|
||||||
|
const unscaled = new WeakMap();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The atmosphere scale (viewOptions.js ATMOSPHERE_LUMINANCE_SCALE): each
|
* The atmosphere scale (viewOptions.js ATMOSPHERE_LUMINANCE_SCALE): each
|
||||||
* luminance factor is set to `scale` times the base value recorded the
|
* luminance factor is set to `scale` times the base value recorded the
|
||||||
* first time it is seen, so a vector Navara shares between materials, or
|
* first time it is seen, never multiplied in place, so a vector Navara
|
||||||
* copies into a rebuilt one, is never scaled twice. A scaled uniform points
|
* shares between materials, or copies into a rebuilt one, is never scaled
|
||||||
* at this scaler's own vector; the vector Navara built it with is never
|
* twice. The stars keep the base value: when they share the sky's vector,
|
||||||
* written. Those are takram's AtmosphereParameters.DEFAULT vectors, one per
|
* they get their own. Returns `apply()`, true when it changed a uniform.
|
||||||
* page: written in place, the next globe on the page (a rebuild after a lost
|
*
|
||||||
* context) recorded a scaled value as its base and drew the atmosphere
|
* The vectors are takram's AtmosphereParameters.DEFAULT ones, one per page
|
||||||
* scale² bright. The stars keep the base value. Returns `apply()`, true
|
* and read by every globe's materials, so the base of a vector an earlier
|
||||||
* when it changed what a uniform holds.
|
* globe already scaled is the value it had before that (`unscaled`): a
|
||||||
|
* globe rebuilt on the page after a lost context took the scaled value as
|
||||||
|
* its base and drew the atmosphere scale² bright.
|
||||||
*/
|
*/
|
||||||
export function createLuminanceScaler(scale, forEachUniform, handles) {
|
export function createLuminanceScaler(scale, forEachUniform, handles) {
|
||||||
if (scale === 1 || !forEachUniform) return () => false;
|
if (scale === 1 || !forEachUniform) return () => false;
|
||||||
// key -> the vectors uniforms point at, and the values they must hold
|
const bases = new Map(); // key -> { base, target }
|
||||||
const bases = new Map();
|
const scaledVectors = new WeakSet();
|
||||||
let changed = false;
|
let changed = false;
|
||||||
const entry = (key, value) => {
|
const entry = (key, value) => {
|
||||||
let found = bases.get(key);
|
let found = bases.get(key);
|
||||||
if (!found) {
|
if (!found) {
|
||||||
const baseValue = value.clone();
|
const base = unscaled.get(value) ?? value;
|
||||||
const targetValue = value.clone().multiplyScalar(scale);
|
|
||||||
found = {
|
found = {
|
||||||
base: baseValue.clone(),
|
base: base.clone(),
|
||||||
target: targetValue.clone(),
|
target: base.clone().multiplyScalar(scale),
|
||||||
baseValue,
|
|
||||||
targetValue,
|
|
||||||
};
|
};
|
||||||
bases.set(key, found);
|
bases.set(key, found);
|
||||||
}
|
}
|
||||||
return found;
|
return found;
|
||||||
};
|
};
|
||||||
// A material may write into the vector its uniform holds.
|
|
||||||
const restore = () => {
|
|
||||||
for (const { base, target, baseValue, targetValue } of bases.values()) {
|
|
||||||
if (!base.equals(baseValue)) {
|
|
||||||
base.copy(baseValue);
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
if (!target.equals(targetValue)) {
|
|
||||||
target.copy(targetValue);
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let applyScale = true;
|
let applyScale = true;
|
||||||
const record = (key, uniform) => entry(key, uniform.value);
|
const record = (key, uniform) => entry(key, uniform.value);
|
||||||
const scaleOne = (key, uniform, scaled) => {
|
const scaleOne = (key, uniform, scaled) => {
|
||||||
if (!scaled) return;
|
if (!scaled) return;
|
||||||
const { base, target } = entry(key, uniform.value);
|
const { base, target } = entry(key, uniform.value);
|
||||||
const desired = applyScale ? target : base;
|
const desired = applyScale ? target : base;
|
||||||
if (uniform.value === desired) return;
|
scaledVectors.add(uniform.value);
|
||||||
if (!uniform.value.equals(desired)) changed = true;
|
if (uniform.value.equals(desired)) return;
|
||||||
uniform.value = desired;
|
if (!unscaled.has(uniform.value))
|
||||||
|
unscaled.set(uniform.value, uniform.value.clone());
|
||||||
|
uniform.value.copy(desired);
|
||||||
|
changed = true;
|
||||||
};
|
};
|
||||||
const keepBase = (key, uniform, scaled) => {
|
const keepBase = (key, uniform, scaled) => {
|
||||||
if (scaled) return;
|
if (scaled) return;
|
||||||
const { base, target } = entry(key, uniform.value);
|
const { base } = entry(key, uniform.value);
|
||||||
// Never this scaler's own vectors: they change with the scale.
|
if (scaledVectors.has(uniform.value)) {
|
||||||
if (uniform.value === target || uniform.value === base) {
|
|
||||||
if (!uniform.value.equals(base)) changed = true;
|
|
||||||
uniform.value = base.clone();
|
uniform.value = base.clone();
|
||||||
|
changed = true;
|
||||||
} else if (!uniform.value.equals(base)) {
|
} else if (!uniform.value.equals(base)) {
|
||||||
uniform.value = base.clone();
|
uniform.value.copy(base);
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -325,7 +317,6 @@ export function createLuminanceScaler(scale, forEachUniform, handles) {
|
|||||||
changed = false;
|
changed = false;
|
||||||
// Bases first, from the values as Navara built them.
|
// Bases first, from the values as Navara built them.
|
||||||
forEachUniform(handles, record);
|
forEachUniform(handles, record);
|
||||||
restore();
|
|
||||||
forEachUniform(handles, scaleOne);
|
forEachUniform(handles, scaleOne);
|
||||||
forEachUniform(handles, keepBase);
|
forEachUniform(handles, keepBase);
|
||||||
return changed;
|
return changed;
|
||||||
|
|||||||
@@ -568,17 +568,14 @@ test('a second look on the page scales the shared atmosphere vectors from their
|
|||||||
};
|
};
|
||||||
const first = build();
|
const first = build();
|
||||||
near(first.sky[SKY].value.x, 1.5 * k);
|
near(first.sky[SKY].value.x, 1.5 * k);
|
||||||
assert.equal(
|
// The first globe's context is lost and a new one is built on the page:
|
||||||
pageDefault[SKY].value.x,
|
// its materials hold the vectors the first one scaled.
|
||||||
1.5,
|
|
||||||
'the shared vector is not written',
|
|
||||||
);
|
|
||||||
// The first globe's context is lost and a new one is built on the page.
|
|
||||||
const second = build();
|
const second = build();
|
||||||
near(second.sky[SKY].value.x, 1.5 * k);
|
near(second.sky[SKY].value.x, 1.5 * k);
|
||||||
near(second.clouds[SUN].value.x, 1.3 * k);
|
near(second.clouds[SUN].value.x, 1.3 * k);
|
||||||
|
near(pageDefault[SKY].value.x, 1.5 * k);
|
||||||
assert.equal(second.stars[SKY].value.x, 1.5);
|
assert.equal(second.stars[SKY].value.x, 1.5);
|
||||||
near(first.sky[SKY].value.x, 1.5 * k);
|
assert.equal(second.stars[SUN].value.x, 1.3);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('a value a material writes into the scaled vector is put back on the next frame', () => {
|
test('a value a material writes into the scaled vector is put back on the next frame', () => {
|
||||||
|
|||||||
Reference in new issue
Block a user