Files
gta6/tests/bumpExtension.test.js
2026-09-14 10:39:39 +02:00

66 lines
3.6 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, expect, it } from "vitest";
import { Document, NodeIO } from "@gltf-transform/core";
import { KHRTextureTransform } from "@gltf-transform/extensions";
import { dedup, prune } from "@gltf-transform/functions";
import sharp from "sharp";
import { EXT_MATERIALS_BUMP, EXTMaterialsBump } from "../tools/assets/bumpExtension.mjs";
/** 8 × 8 px mit wechselnden Werten — prune() ersetzt einfarbige Texturen sonst durch Faktoren. */
function pattern() {
const data = Buffer.alloc(8 * 8 * 3);
for (let i = 0; i < data.length; i++) data[i] = (i * 37) & 0xff;
return sharp(data, { raw: { width: 8, height: 8, channels: 3 } }).png().toBuffer();
}
/** Ein Dreieck mit dem Material cont_a_side, Bump-Stärke 2,2 und Wellenteilung [3.2, 1]. */
async function bumpDocument() {
const document = new Document();
document.createBuffer();
const bumpExtension = document.createExtension(EXTMaterialsBump);
const transformExtension = document.createExtension(KHRTextureTransform);
const texture = document.createTexture("wellblech").setImage(await pattern()).setMimeType("image/png");
const bump = bumpExtension.createBump().setBumpFactor(2.2).setBumpTexture(texture);
bump.getBumpTextureInfo().setExtension("KHR_texture_transform", transformExtension.createTransform().setScale([3.2, 1]));
const material = document.createMaterial("cont_a_side").setExtension(EXT_MATERIALS_BUMP, bump);
const positions = document.createAccessor().setType("VEC3").setArray(new Float32Array([0, 0, 0, 1, 0, 0, 0, 1, 0]));
const primitive = document.createPrimitive().setMaterial(material).setAttribute("POSITION", positions);
document.createScene().addChild(document.createNode().setMesh(document.createMesh().addPrimitive(primitive)));
return document;
}
/** JSON-Teil einer .glb: 12 Byte Kopf, dann Länge und Typ des ersten Blocks, dann das JSON. */
function glbJson(glb) {
const view = new DataView(glb.buffer, glb.byteOffset, glb.byteLength);
return JSON.parse(new TextDecoder().decode(glb.subarray(20, 20 + view.getUint32(12, true))));
}
describe("EXT_materials_bump", () => {
const io = () => new NodeIO().registerExtensions([EXTMaterialsBump, KHRTextureTransform]);
// Bruch: @gltf-transform verwirft die Erweiterung (Wellblech flach), prune entfernt die Textur als
// unbenutzt, oder die Wellenteilung an der bumpTexture geht verloren (Wellen 3,2-mal zu breit).
it("übersteht dedup, prune, Schreiben und Einlesen mit Stärke, Textur und Teilung", async () => {
const document = await bumpDocument();
await document.transform(dedup(), prune());
const read = await io().readBinary(await io().writeBinary(document));
const bump = read.getRoot().listMaterials()[0].getExtension(EXT_MATERIALS_BUMP);
expect(bump.getBumpFactor()).toBe(2.2);
expect(bump.getBumpTexture().getSize()).toEqual([8, 8]);
expect(bump.getBumpTextureInfo().getExtension("KHR_texture_transform").getScale()).toEqual([3.2, 1]);
});
// Bruch: Feldnamen oder Aufbau weichen von der Spezifikation ab — three.js (GLTFLoader) liest
// genau materials[i].extensions.EXT_materials_bump.bumpFactor und .bumpTexture.index.
it("schreibt das JSON so, wie three.js es liest", async () => {
const json = glbJson(await io().writeBinary(await bumpDocument()));
expect(json.extensionsUsed).toContain(EXT_MATERIALS_BUMP);
const def = json.materials[0].extensions[EXT_MATERIALS_BUMP];
expect(def.bumpFactor).toBe(2.2);
expect(json.textures[def.bumpTexture.index]).toBeDefined();
expect(def.bumpTexture.extensions.KHR_texture_transform.scale).toEqual([3.2, 1]);
});
});