feat(assets): EXT_materials_bump für gltf-transform
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
3321a029fa
commit
0ebe8adb8b
4 files changed
+997
-5
No files matched your search
@@ -0,0 +1,65 @@
|
||||
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]);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user