@needle-tools/materialx 1.4.6 → 1.5.0-next.b9d5f3f
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/README.md +1 -0
- package/bin/JsMaterialXCore.js +1 -1
- package/bin/JsMaterialXCore.wasm +0 -0
- package/bin/JsMaterialXGenShader.js +1 -1
- package/bin/JsMaterialXGenShader.wasm +0 -0
- package/bin/revision.json +2 -2
- package/package.json +1 -1
- package/src/loader/loader.three.js +34 -6
- package/src/materialx.helper.js +5 -0
- package/src/materialx.js +1 -1
- package/src/materialx.material.js +13 -6
- package/src/materialx.types.d.ts +9 -0
- /package/bin/{SHA_309ccca5d7788f90d773248c88498ddc203dc260 → SHA_2f154972802486867cddc6a79b7ef86952020d3e} +0 -0
|
Binary file
|
package/bin/revision.json
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@needle-tools/materialx",
|
|
3
3
|
"description": "MaterialX material support for three.js and Needle Engine – render physically based MaterialX shaders in the browser via WebAssembly",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.5.0-next.b9d5f3f",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"types": "index.d.ts",
|
|
@@ -310,9 +310,21 @@ export async function createMaterialXMaterial(mtlx, materialNodeNameOrIndex, loa
|
|
|
310
310
|
|
|
311
311
|
if (debug) console.log("[MaterialX] Using renderable element for shader generation");
|
|
312
312
|
|
|
313
|
-
// Check transparency and
|
|
314
|
-
|
|
315
|
-
|
|
313
|
+
// Check transparency and alpha mode.
|
|
314
|
+
// getAlphaMode() is the source of truth: it checks both direct gltf_pbr nodes
|
|
315
|
+
// and inner gltf_pbr nodes inside custom shader graph nodegraphs.
|
|
316
|
+
// isTransparentSurface() is a fallback for non-gltf_pbr shaders.
|
|
317
|
+
const target = state.materialXGenerator.getTarget();
|
|
318
|
+
const alphaMode = typeof state.materialXModule.getAlphaMode === "function"
|
|
319
|
+
? state.materialXModule.getAlphaMode(renderableElement, target)
|
|
320
|
+
: (state.materialXModule.isTransparentSurface(renderableElement, target) ? "blend" : "opaque");
|
|
321
|
+
const isMask = alphaMode === "mask";
|
|
322
|
+
const isBlend = alphaMode === "blend";
|
|
323
|
+
// Both MASK and BLEND need alpha handling in the generated shader.
|
|
324
|
+
const needsAlpha = isMask || isBlend;
|
|
325
|
+
|
|
326
|
+
// hwTransparency must be true for both MASK and BLEND so the shader includes alpha handling code.
|
|
327
|
+
state.materialXGenContext.getOptions().hwTransparency = needsAlpha;
|
|
316
328
|
|
|
317
329
|
// Generate shaders using the element's name path
|
|
318
330
|
if (debug) console.log("[MaterialX] Generating MaterialX shaders...");
|
|
@@ -326,7 +338,10 @@ export async function createMaterialXMaterial(mtlx, materialNodeNameOrIndex, loa
|
|
|
326
338
|
shader,
|
|
327
339
|
context: context || {},
|
|
328
340
|
parameters: {
|
|
329
|
-
|
|
341
|
+
// MASK mode: no GL blending (discard handles cutout), BLEND mode: GL blending
|
|
342
|
+
transparent: isBlend,
|
|
343
|
+
// For MASK mode, set alphaTest so Three.js enables alpha testing
|
|
344
|
+
alphaTest: isMask ? 0.0001 : 0,
|
|
330
345
|
...options?.parameters,
|
|
331
346
|
},
|
|
332
347
|
loaders: loaders,
|
|
@@ -337,8 +352,21 @@ export async function createMaterialXMaterial(mtlx, materialNodeNameOrIndex, loa
|
|
|
337
352
|
return shaderMaterial;
|
|
338
353
|
|
|
339
354
|
} catch (error) {
|
|
340
|
-
//
|
|
341
|
-
|
|
355
|
+
// WASM exceptions arrive as integer pointers. Extract the detailed error message
|
|
356
|
+
// which includes shader compilation errors, line numbers, and error logs.
|
|
357
|
+
let errorMessage = error;
|
|
358
|
+
if (typeof error === "number" && state?.materialXModule) {
|
|
359
|
+
try {
|
|
360
|
+
const getDetailed = state.materialXModule.getExceptionDetailedMessage;
|
|
361
|
+
const getBasic = state.materialXModule.getExceptionMessage;
|
|
362
|
+
errorMessage = (typeof getDetailed === "function" ? getDetailed(error) : null)
|
|
363
|
+
|| (typeof getBasic === "function" ? getBasic(error) : null)
|
|
364
|
+
|| `WASM exception code ${error}`;
|
|
365
|
+
} catch (_) {
|
|
366
|
+
errorMessage = `WASM exception code ${error}`;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
console.error(`[MaterialX v${VERSION}] Error creating MaterialX material (${materialNodeNameOrIndex}):\n${errorMessage}\n→ MaterialX source:\n`, mtlx);
|
|
342
370
|
// Return a fallback material with stored MaterialX data
|
|
343
371
|
const fallbackMaterial = new MeshStandardMaterial();
|
|
344
372
|
fallbackMaterial.color.set(0xff00ff);
|
package/src/materialx.helper.js
CHANGED
|
@@ -222,6 +222,11 @@ function toThreeUniform(uniforms, type, value, name, loaders, searchPath) {
|
|
|
222
222
|
break;
|
|
223
223
|
case 'samplerCube':
|
|
224
224
|
case 'string':
|
|
225
|
+
case 'surfaceshader':
|
|
226
|
+
case 'displacementshader':
|
|
227
|
+
case 'volumeshader':
|
|
228
|
+
case 'lightshader':
|
|
229
|
+
// MaterialX closure/shader types — not real uniforms, skip silently
|
|
225
230
|
break;
|
|
226
231
|
default:
|
|
227
232
|
const key = type + ':' + name;
|
package/src/materialx.js
CHANGED
|
@@ -51,7 +51,7 @@ export async function ready() {
|
|
|
51
51
|
|
|
52
52
|
// NOTE: This must be a plain string literal (not a template) so that the
|
|
53
53
|
// makeFilesLocal Vite plugin can statically detect and localize this URL.
|
|
54
|
-
const defaultBaseUrl = "https://cdn.needle.tools/static/materialx/1.
|
|
54
|
+
const defaultBaseUrl = "https://cdn.needle.tools/static/materialx/1.5.0/";
|
|
55
55
|
|
|
56
56
|
/** @type {Array<string>} */
|
|
57
57
|
let urls;
|
|
@@ -143,12 +143,19 @@ export class MaterialXMaterial extends ShaderMaterial {
|
|
|
143
143
|
var hasColor = vertexShader.includes('in vec4 color;');
|
|
144
144
|
vertexShader = vertexShader.replace(/in\s+vec4\s+color;/g, '');
|
|
145
145
|
|
|
146
|
-
// Patch uv 2-component to 3-component
|
|
147
|
-
//
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
if (!
|
|
151
|
-
if (!
|
|
146
|
+
// Patch uv 2-component to 3-component. Three.js UVs are vec2 but MaterialX
|
|
147
|
+
// texcoords may be vec3. Replace all `= uv;` assignments where the type is vec3.
|
|
148
|
+
// This covers both vertex data connectors (texcoord_0 = uv) and displacement
|
|
149
|
+
// dependency outputs (uv_0_out = uv).
|
|
150
|
+
if (!uv_is_vec2) vertexShader = vertexShader.replace(/\bvec3 (\w+) = uv;/g, 'vec3 $1 = vec3(uv, 0.0);');
|
|
151
|
+
if (!uv1_is_vec2) vertexShader = vertexShader.replace(/\bvec3 (\w+) = uv1;/g, 'vec3 $1 = vec3(uv1, 0.0);');
|
|
152
|
+
if (!uv2_is_vec2) vertexShader = vertexShader.replace(/\bvec3 (\w+) = uv2;/g, 'vec3 $1 = vec3(uv2, 0.0);');
|
|
153
|
+
if (!uv3_is_vec2) vertexShader = vertexShader.replace(/\bvec3 (\w+) = uv3;/g, 'vec3 $1 = vec3(uv3, 0.0);');
|
|
154
|
+
// Also handle non-declaration assignments (e.g. `texcoord_0 = uv;`)
|
|
155
|
+
if (!uv_is_vec2) vertexShader = vertexShader.replace(/(\w+) = uv;/g, (match, name) => {
|
|
156
|
+
// Only replace if not already a vec3() call
|
|
157
|
+
return match.includes('vec3') ? match : `${name} = vec3(uv, 0.0);`;
|
|
158
|
+
});
|
|
152
159
|
|
|
153
160
|
// Patch units – seems MaterialX uses different units and we end up with wrong light values?
|
|
154
161
|
// result.direction = light.position - position;
|
package/src/materialx.types.d.ts
CHANGED
|
@@ -14,6 +14,13 @@ export namespace MaterialX {
|
|
|
14
14
|
readFromXmlString(doc: Document, xml: string, searchPath?: string): void;
|
|
15
15
|
loadStandardLibraries(genContext: GenContext): StandardLibrary;
|
|
16
16
|
isTransparentSurface(renderableElement: any, target: string): boolean;
|
|
17
|
+
/** Returns the alpha mode for a renderable element: "opaque", "mask", or "blend".
|
|
18
|
+
* Inspects the shader node (and its nodegraph implementation) for alpha_mode inputs. */
|
|
19
|
+
getAlphaMode?(renderableElement: any, target: string): string;
|
|
20
|
+
/** Extracts a detailed error message from a WASM exception pointer, including error logs. */
|
|
21
|
+
getExceptionDetailedMessage?(exceptionPtr: number): string;
|
|
22
|
+
/** Extracts a basic error message from a WASM exception pointer. */
|
|
23
|
+
getExceptionMessage?(exceptionPtr: number): string;
|
|
17
24
|
}
|
|
18
25
|
|
|
19
26
|
|
|
@@ -32,6 +39,8 @@ export namespace MaterialX {
|
|
|
32
39
|
export type Document = {
|
|
33
40
|
setDataLibrary(lib: StandardLibrary): void;
|
|
34
41
|
importLibrary(lib: Document): void;
|
|
42
|
+
/** Validates the document and returns validation result with error messages. */
|
|
43
|
+
validate?(): { valid: boolean; message: string };
|
|
35
44
|
|
|
36
45
|
getNodes(): Node[];
|
|
37
46
|
}
|
|
File without changes
|