Files
webeditor3d/tests/unit/precomputed-shader-sky-environment-cache.test.ts
Victor Giers ba3db722f3 auto-git:
[change] tests/unit/precomputed-shader-sky-environment-cache.test.ts
2026-04-22 18:01:12 +02:00

98 lines
3.1 KiB
TypeScript

import { Texture } from "three";
import { describe, expect, it, vi } from "vitest";
import { createDefaultProjectTimeSettings } from "../../src/document/project-time-settings";
import { createDefaultWorldSettings } from "../../src/document/world-settings";
import { PrecomputedShaderSkyEnvironmentCache } from "../../src/rendering/precomputed-shader-sky-environment-cache";
import {
resolveWorldShaderSkyEnvironmentPhaseStates,
resolveWorldShaderSkyRenderState,
type WorldShaderSkyRenderState
} from "../../src/rendering/world-shader-sky";
import {
resolveRuntimeDayNightWorldState,
resolveRuntimeTimeState
} from "../../src/runtime-three/runtime-project-time";
describe("PrecomputedShaderSkyEnvironmentCache", () => {
it("builds representative shader environment textures once per phase-cache key", () => {
const world = createDefaultWorldSettings();
const time = createDefaultProjectTimeSettings();
world.background = {
mode: "shader"
};
const buildEnvironmentTexture = vi.fn(() => ({
texture: new Texture(),
dispose: vi.fn()
}));
const cache = new PrecomputedShaderSkyEnvironmentCache({
buildEnvironmentTexture
});
const states = resolveWorldShaderSkyEnvironmentPhaseStates(world, time);
cache.syncPhaseTextures(states);
cache.syncPhaseTextures(states);
expect(buildEnvironmentTexture).toHaveBeenCalledTimes(4);
});
it("blends between the active precomputed phase textures during twilight", () => {
const world = createDefaultWorldSettings();
const time = createDefaultProjectTimeSettings();
const buildOrder: string[] = [];
const phaseTextures: Record<"day" | "dawn" | "dusk" | "night", Texture> = {
day: new Texture(),
dawn: new Texture(),
dusk: new Texture(),
night: new Texture()
};
const blendedTexture = new Texture();
time.sunriseTimeOfDayHours = 7;
time.sunsetTimeOfDayHours = 20;
time.dawnDurationHours = 2;
time.duskDurationHours = 2;
world.background = {
mode: "shader"
};
const cache = new PrecomputedShaderSkyEnvironmentCache({
buildEnvironmentTexture: vi.fn((state: WorldShaderSkyRenderState) => {
buildOrder.push(state.time.dayPhase);
return {
texture: phaseTextures[state.time.dayPhase],
dispose: vi.fn()
};
}),
phaseBlendTextureResolver: {
resolveBlendTexture: vi.fn().mockReturnValue(blendedTexture)
}
});
const noonTime = resolveRuntimeTimeState(time, {
timeOfDayHours: 7.5,
dayCount: 0,
dayLengthMinutes: 24
});
const noonWorld = resolveRuntimeDayNightWorldState(
world,
time,
{
timeOfDayHours: 7.5,
dayCount: 0,
dayLengthMinutes: 24
},
noonTime
);
const twilightSky = resolveWorldShaderSkyRenderState(
world,
noonWorld,
noonTime,
time
);
const states = resolveWorldShaderSkyEnvironmentPhaseStates(world, time);
cache.syncPhaseTextures(states);
expect(buildOrder).toEqual(["day", "dawn", "dusk", "night"]);
expect(cache.resolveEnvironmentTexture(twilightSky!)).toBe(blendedTexture);
});
});