mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 19:04:02 +00:00
fix(anime): fade the Milky Way out instead of masking the sky by depth
The far-plane mask in the anime shader read the post-process depth, which cannot tell the sky from far geometry: with a layer that clamps the near plane to 0.1 m (satellites) the whole Earth lost its cel bands, keyless terrain above the ellipsoid horizon did too, and the atmosphere, Sun and Moon stopped banding. Restore the anime shader from main and fade the Milky Way glow with the style instead: VisualEffects sets skyBox.milkyWayVisibility to 1 - anime intensity. scripts/qa-anime-space-mask.mjs checks all three cases headless and that the anime sky shows no bands. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
adeee12209
commit
e652e50d5c
6 files changed
+357
-7
No files matched your search
@@ -167,6 +167,8 @@ export class StarrySky {
|
||||
/** Matches `SkyBox#show`. */
|
||||
this.show = true;
|
||||
this.milkyWayIntensity = MILKY_WAY_INTENSITY;
|
||||
/** 0..1 multiplier a style sets to hide the glow (see visualEffects.js). */
|
||||
this.milkyWayVisibility = 1;
|
||||
this.starIntensity = STAR_INTENSITY;
|
||||
this._requestRender = requestRender;
|
||||
this._rotation = Cesium.Matrix3.clone(Cesium.Matrix3.IDENTITY);
|
||||
@@ -190,7 +192,7 @@ export class StarrySky {
|
||||
this._milkyWayUniforms = {
|
||||
...uniforms,
|
||||
u_milkyWay: () => this._cubeMap,
|
||||
u_intensity: () => this.milkyWayIntensity,
|
||||
u_intensity: () => this.milkyWayIntensity * this.milkyWayVisibility,
|
||||
};
|
||||
this._starUniforms = {
|
||||
...uniforms,
|
||||
|
||||
@@ -2,6 +2,7 @@ import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import * as Cesium from 'cesium';
|
||||
import {
|
||||
MILKY_WAY_INTENSITY,
|
||||
STARRY_SKY_CESIUM_VERSION,
|
||||
SKY_ROTATION_EPSILON_SECONDS,
|
||||
StarrySky,
|
||||
@@ -9,6 +10,9 @@ import {
|
||||
isSkyRotationCurrent,
|
||||
} from './starrySky.js';
|
||||
|
||||
const close = (actual, expected, epsilon = 1e-9) =>
|
||||
assert.ok(Math.abs(actual - expected) <= epsilon, `${actual} vs ${expected}`);
|
||||
|
||||
test('the sky-box adapter was validated against this engine version', () => {
|
||||
assert.equal(
|
||||
Cesium.VERSION,
|
||||
@@ -115,3 +119,11 @@ for (const iso of ['1970-01-01T00:00:00Z', '2060-01-01T00:00:00Z']) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
test('the Milky Way glow scales with its visibility, for styles that hide it', () => {
|
||||
const sky = new StarrySky({ requestRender: () => {} });
|
||||
close(sky._milkyWayUniforms.u_intensity(), MILKY_WAY_INTENSITY);
|
||||
sky.milkyWayVisibility = 0;
|
||||
assert.equal(sky._milkyWayUniforms.u_intensity(), 0);
|
||||
sky.destroy();
|
||||
});
|
||||
+2
-6
@@ -12,7 +12,6 @@ export const animeShader = {
|
||||
},
|
||||
fragmentShader: /* glsl */ `
|
||||
uniform sampler2D colorTexture;
|
||||
uniform sampler2D depthTexture;
|
||||
uniform vec2 colorTextureDimensions;
|
||||
uniform float intensity;
|
||||
uniform float saturation;
|
||||
@@ -39,12 +38,9 @@ export const animeShader = {
|
||||
vec2 texel = 1.0 / colorTextureDimensions;
|
||||
vec4 color = texture(colorTexture, uv);
|
||||
|
||||
// Cel-shade: quantize luminance into bands. Not the far plane: four
|
||||
// bands turn the faint Milky Way behind the globe into blotches. Its
|
||||
// packed depth reads a few 1e-7 short of 1.0.
|
||||
// Cel-shade: quantize luminance into bands
|
||||
float luma = dot(color.rgb, vec3(0.299, 0.587, 0.114));
|
||||
bool space = czm_readDepth(depthTexture, uv) > 0.99999;
|
||||
float bands = space ? 256.0 : mix(256.0, 4.0, intensity);
|
||||
float bands = mix(256.0, 4.0, intensity);
|
||||
float celLuma = floor(luma * bands + 0.5) / bands;
|
||||
float lumaScale = (luma > 0.001) ? celLuma / luma : 1.0;
|
||||
vec3 celColor = color.rgb * lumaScale;
|
||||
|
||||
@@ -112,6 +112,15 @@ export class VisualEffects {
|
||||
if (this.stopped || !stage) return;
|
||||
stage.uniforms.intensity = value;
|
||||
stage.enabled = value > 0.001;
|
||||
// Anime's four luminance bands turn the faint Milky Way into blotches, and
|
||||
// a post-process cannot tell the sky from far geometry reliably (near
|
||||
// plane clamps, keyless terrain above the ellipsoid horizon): fade the
|
||||
// glow out with the style instead. Stars survive as banded points.
|
||||
if (stage === this.stages.anime) {
|
||||
const sky = this.viewer.scene?.skyBox;
|
||||
if (sky && 'milkyWayVisibility' in sky)
|
||||
sky.milkyWayVisibility = 1 - value;
|
||||
}
|
||||
if (stage.enabled && stage.uniforms.time !== undefined)
|
||||
this.startAnimationLoop();
|
||||
this.requestRender('style-stage');
|
||||
|
||||
@@ -158,6 +158,27 @@ test('direct Cockpit intensity writes are reconciled before rendering', () => {
|
||||
f.effects.destroy();
|
||||
});
|
||||
|
||||
test('the anime stage fades the Milky Way out with its own intensity', () => {
|
||||
const f = fixture();
|
||||
const sky = { milkyWayVisibility: 1 };
|
||||
f.effects.viewer.scene.skyBox = sky;
|
||||
f.effects.initStyles();
|
||||
f.effects.setStageIntensity(f.effects.stages.thermal, 1);
|
||||
assert.equal(sky.milkyWayVisibility, 1, 'other styles keep the glow');
|
||||
f.effects.setStageIntensity(f.effects.stages.anime, 0.25);
|
||||
assert.equal(sky.milkyWayVisibility, 0.75);
|
||||
f.effects.setStageIntensity(f.effects.stages.anime, 1);
|
||||
assert.equal(sky.milkyWayVisibility, 0);
|
||||
f.effects.setStageIntensity(f.effects.stages.anime, 0);
|
||||
assert.equal(sky.milkyWayVisibility, 1);
|
||||
// A sky box without the knob (Cesium's own) is left alone.
|
||||
const plain = {};
|
||||
f.effects.viewer.scene.skyBox = plain;
|
||||
f.effects.setStageIntensity(f.effects.stages.anime, 1);
|
||||
assert.deepEqual(plain, {});
|
||||
f.effects.destroy();
|
||||
});
|
||||
|
||||
test('bloom retains its dead zone, normalized intensity and independent toggle', () => {
|
||||
const f = fixture();
|
||||
f.effects.initPostProcess();
|
||||
|
||||
Reference in new issue
Block a user