Ruling 55: asphalt_02 maß roh heller (Ø 89.5) als concrete_pavement_03 (Ø 65.9) und ließ Stadtflächen wie dunkle Flecken auf der Straße wirken. material.color kann eine Textur nur abdunkeln, also wird die Straße auf 0x999999 abgetönt statt die Stadtfläche zu verändern. Gemessen im gerenderten Bild an denselben Bildschirmregionen: Straße 93.0 -> 42.5, Stadtfläche 63.2 -> 63.0 (unverändert) — die Straße kommt jetzt deutlich dunkler heraus als die Stadtfläche, nicht nur als vorher sie selbst. Ruling 56: Brücken sind in den Daten dasselbe Straßenstück, nur über Wasser (geometry.js trennt sie einzig über roads.filter(r => r.bridge)) und bekommen jetzt asphalt_02 und denselben Farbton wie roads statt der Stadtflächentextur, damit an keinem Straße-Brücke-Übergang mehr eine Farbnaht entsteht. Neuer Test dafür (RED vor der Änderung, GREEN danach) plus ein erreichtes Brückenstück im Browser (Chunk 11_7) fotografiert. Ruling 57: metalnessMap entfernt. metalness steht fest auf 0, three multipliziert texelMetalness nur noch dazu (metalnessmap_fragment.glsl.js) und könnte das Ergebnis nie von 0 wegbewegen — reine Kosten ohne Wirkung. Ruling 58: anisotropy als optionaler Parameter von createMaterials()/loadSet() statt eines globalen Renderer-Zugriffs; main.js übergibt jetzt renderer.capabilities.getMaxAnisotropy(). Laufzeit bestätigt: alle drei Texturtypen auf allen Materialien tragen anisotropy 16 (= getMaxAnisotropy() auf diesem Gerät). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
34 lines
1.5 KiB
JavaScript
34 lines
1.5 KiB
JavaScript
import { describe, expect, it } from "vitest";
|
|
import { MATERIAL_KEYS, TEXTURES, waterNormalData } from "../src/world/materials.js";
|
|
import { buildChunkGeometry } from "../src/world/geometry.js";
|
|
|
|
describe("materials", () => {
|
|
it("deckt genau die Geometrie-Teile ab", () => {
|
|
const chunk = { chunk: [0, 0], origin: [0, 0], land: [], roads: [], centerlines: [], buildings: [], palms: [] };
|
|
expect(Object.keys(buildChunkGeometry(chunk)).sort()).toEqual([...MATERIAL_KEYS].sort());
|
|
});
|
|
|
|
it("nennt für jedes Material eine Textur", () => {
|
|
for (const key of MATERIAL_KEYS) expect(TEXTURES[key]).toBeTruthy();
|
|
});
|
|
|
|
it("deckt Strand und Park mit eigenen Materialien ab", () => {
|
|
expect(MATERIAL_KEYS).toContain("sand");
|
|
expect(MATERIAL_KEYS).toContain("park");
|
|
});
|
|
|
|
it("gibt Brücken dieselbe Textur wie Straßen, damit an der Übergangsnaht kein Farbsprung entsteht (Ruling 56)", () => {
|
|
// Brücken sind in den Daten dasselbe Straßenstück, nur über Wasser
|
|
// (geometry.js trennt sie einzig über roads.filter(r => r.bridge)).
|
|
expect(TEXTURES.bridges).toBe(TEXTURES.roads);
|
|
});
|
|
|
|
it("erzeugt eine Wellen-Normalmap mit neutraler Grundfarbe", () => {
|
|
const data = waterNormalData(32);
|
|
expect(data.length).toBe(32 * 32 * 4);
|
|
// Normalen zeigen im Mittel nach oben: Blaukanal nahe 255.
|
|
const blue = [...data].filter((_, i) => i % 4 === 2);
|
|
expect(blue.reduce((a, b) => a + b, 0) / blue.length).toBeGreaterThan(200);
|
|
});
|
|
});
|