@needle-tools/materialx 1.6.0 → 1.7.0-next.57183d6
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 +19 -1
- package/LICENSE.txt +131 -0
- package/README.md +33 -1
- package/bin/JsMaterialXCore.js +5 -13
- package/bin/JsMaterialXCore.wasm +0 -0
- package/bin/JsMaterialXGenShader.data.txt +2127 -2453
- package/bin/JsMaterialXGenShader.js +5 -13
- package/bin/JsMaterialXGenShader.wasm +0 -0
- package/bin/revision.json +3 -3
- package/package.json +14 -3
- package/src/constants.js +4 -5
- package/src/index.d.ts +1 -2
- package/src/loader/loader.three.d.ts +10 -1
- package/src/loader/loader.three.js +26 -19
- package/src/materialx.d.ts +9 -5
- package/src/materialx.helper.d.ts +2 -2
- package/src/materialx.helper.js +113 -47
- package/src/materialx.js +104 -29
- package/src/materialx.material.d.ts +11 -2
- package/src/materialx.material.js +614 -34
- package/src/materialx.types.d.ts +65 -10
- package/src/utils.js +16 -9
- package/src/utils.texture.d.ts +11 -0
- package/src/utils.texture.js +195 -38
- /package/bin/{SHA_0e7685f37737511f2816949b9486d511a5fa71bd → SHA_ab218c56f016a9a2d398e8d306f3aeb439ae9e9e} +0 -0
package/src/materialx.js
CHANGED
|
@@ -1,11 +1,35 @@
|
|
|
1
1
|
import MaterialX from "../bin/JsMaterialXGenShader.js";
|
|
2
2
|
import { debug, waitForNetworkIdle } from "./utils.js";
|
|
3
|
-
import { renderPMREMToEquirect } from "./utils.texture.js";
|
|
4
|
-
import { Light, Mesh, MeshBasicMaterial, Object3D, PlaneGeometry, PMREMGenerator, Scene, Texture
|
|
3
|
+
import { renderPMREMToEquirect, renderPMREMToPrefilteredEquirect } from "./utils.texture.js";
|
|
4
|
+
import { CubeUVReflectionMapping, Light, Mesh, MeshBasicMaterial, Object3D, PlaneGeometry, PMREMGenerator, Scene, Texture } from "three";
|
|
5
5
|
import { registerLights, getLightData } from "./materialx.helper.js";
|
|
6
6
|
import { whiteTexture } from "./utils.texture.js";
|
|
7
7
|
import { VERSION } from "./constants.js";
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* Accept Texture instances from any Three.js copy. Tooling like the fidelity
|
|
11
|
+
* renderer can host scenes with a different Three.js module instance than this
|
|
12
|
+
* package, so `instanceof Texture` is too strict here.
|
|
13
|
+
* @param {unknown} value
|
|
14
|
+
* @returns {value is Texture}
|
|
15
|
+
*/
|
|
16
|
+
function isTextureLike(value) {
|
|
17
|
+
return !!value && typeof value === "object" && /** @type {{ isTexture?: unknown }} */(value).isTexture === true;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function isNodeRuntime() {
|
|
21
|
+
return !!globalThis.process?.versions?.node && globalThis.process?.type !== "renderer";
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async function getNodePackageAssetPaths() {
|
|
25
|
+
const { fileURLToPath } = await import(/* @vite-ignore */ "node:url");
|
|
26
|
+
return [
|
|
27
|
+
fileURLToPath(new URL("../bin/JsMaterialXCore.wasm", import.meta.url)),
|
|
28
|
+
fileURLToPath(new URL("../bin/JsMaterialXGenShader.wasm", import.meta.url)),
|
|
29
|
+
fileURLToPath(new URL("../bin/JsMaterialXGenShader.data.txt", import.meta.url)),
|
|
30
|
+
];
|
|
31
|
+
}
|
|
32
|
+
|
|
9
33
|
|
|
10
34
|
/**
|
|
11
35
|
* Preloads the MaterialX WebAssembly module.
|
|
@@ -51,14 +75,17 @@ export async function ready() {
|
|
|
51
75
|
|
|
52
76
|
// NOTE: This must be a plain string literal (not a template) so that the
|
|
53
77
|
// makeFilesLocal Vite plugin can statically detect and localize this URL.
|
|
54
|
-
const defaultBaseUrl = "https://cdn.needle.tools/static/materialx/1.
|
|
78
|
+
const defaultBaseUrl = "https://cdn.needle.tools/static/materialx/1.7.0/";
|
|
55
79
|
|
|
56
80
|
/** @type {Array<string>} */
|
|
57
81
|
let urls;
|
|
58
82
|
|
|
59
83
|
const location = globalThis.NEEDLE_MATERIALX_LOCATION;
|
|
60
84
|
|
|
61
|
-
if (
|
|
85
|
+
if (isNodeRuntime()) {
|
|
86
|
+
urls = await getNodePackageAssetPaths();
|
|
87
|
+
}
|
|
88
|
+
else if (location === "package" || location === "bin/" || location === "./bin/" || location === "../bin/") {
|
|
62
89
|
// Use local files from the @needle-tools/materialx npm package.
|
|
63
90
|
// Vite's ?url suffix copies these files to the output directory
|
|
64
91
|
// and returns their URL automatically — no CDN download needed.
|
|
@@ -121,7 +148,7 @@ export async function ready() {
|
|
|
121
148
|
// SPECULAR_ENVIRONMENT_NONE: Do not use specular environment maps.
|
|
122
149
|
// SPECULAR_ENVIRONMENT_FIS: Use Filtered Importance Sampling for specular environment/indirect lighting.
|
|
123
150
|
// SPECULAR_ENVIRONMENT_PREFILTER: Use pre-filtered environment maps for specular environment/indirect lighting.
|
|
124
|
-
state.materialXGenContext.getOptions().hwSpecularEnvironmentMethod = state.materialXModule.HwSpecularEnvironmentMethod.
|
|
151
|
+
state.materialXGenContext.getOptions().hwSpecularEnvironmentMethod = state.materialXModule.HwSpecularEnvironmentMethod.SPECULAR_ENVIRONMENT_PREFILTER;
|
|
125
152
|
|
|
126
153
|
// TRANSMISSION_REFRACTION: Use a refraction approximation for transmission rendering.
|
|
127
154
|
// TRANSMISSION_OPACITY: Use opacity for transmission rendering.
|
|
@@ -161,6 +188,7 @@ export async function ready() {
|
|
|
161
188
|
* @typedef {Object} EnvironmentTextureSet
|
|
162
189
|
* @property {Texture | null} radianceTexture
|
|
163
190
|
* @property {Texture | null} irradianceTexture
|
|
191
|
+
* @property {() => void} [dispose]
|
|
164
192
|
*/
|
|
165
193
|
|
|
166
194
|
/**
|
|
@@ -217,7 +245,7 @@ export class MaterialXEnvironment {
|
|
|
217
245
|
|
|
218
246
|
/**
|
|
219
247
|
* Initialize with Needle Engine context
|
|
220
|
-
* @param {WebGLRenderer} renderer
|
|
248
|
+
* @param {import("three").WebGLRenderer} renderer
|
|
221
249
|
* @returns {Promise<boolean>}
|
|
222
250
|
*/
|
|
223
251
|
async initialize(renderer) {
|
|
@@ -231,7 +259,7 @@ export class MaterialXEnvironment {
|
|
|
231
259
|
/**
|
|
232
260
|
* @param {number} frame
|
|
233
261
|
* @param {Scene} scene
|
|
234
|
-
* @param {WebGLRenderer} renderer
|
|
262
|
+
* @param {import("three").WebGLRenderer} renderer
|
|
235
263
|
*/
|
|
236
264
|
update(frame, scene, renderer) {
|
|
237
265
|
if (!this._initializePromise) {
|
|
@@ -285,9 +313,10 @@ export class MaterialXEnvironment {
|
|
|
285
313
|
this._pmremGenerator?.dispose();
|
|
286
314
|
this._pmremGenerator = null;
|
|
287
315
|
this._renderer = null;
|
|
288
|
-
for (const
|
|
289
|
-
textureSet.
|
|
290
|
-
|
|
316
|
+
for (const textureModeMap of this._texturesCache.values()) {
|
|
317
|
+
for (const textureSet of textureModeMap.values()) {
|
|
318
|
+
textureSet.dispose?.();
|
|
319
|
+
}
|
|
291
320
|
}
|
|
292
321
|
this._texturesCache.clear();
|
|
293
322
|
}
|
|
@@ -304,34 +333,34 @@ export class MaterialXEnvironment {
|
|
|
304
333
|
* @param {import("./materialx.material.js").MaterialXMaterial} material
|
|
305
334
|
*/
|
|
306
335
|
getTextures(material) {
|
|
336
|
+
const radianceMode = material.environmentRadianceMode ?? "three-pmrem";
|
|
307
337
|
if (material.envMap) {
|
|
308
338
|
// If the material has its own envMap, we don't use the irradiance texture
|
|
309
|
-
return this._getTextures(material.envMap);
|
|
339
|
+
return this._getTextures(material.envMap, radianceMode);
|
|
310
340
|
}
|
|
311
341
|
|
|
312
342
|
// Use the scene background for lighting if no environment is available
|
|
313
343
|
// If we don't do this we don't see the correct lighting for scenes exported with 'Environment Lighting: Color' and 'Environment Reflections: Skybox'
|
|
314
344
|
const skybox = this._scene.environment || this._scene.background;
|
|
315
|
-
if (skybox
|
|
316
|
-
return this._getTextures(skybox);
|
|
345
|
+
if (isTextureLike(skybox)) {
|
|
346
|
+
return this._getTextures(skybox, radianceMode);
|
|
317
347
|
}
|
|
318
|
-
return this._getTextures(null);
|
|
348
|
+
return this._getTextures(null, radianceMode);
|
|
319
349
|
}
|
|
320
350
|
|
|
321
351
|
/** @type {PMREMGenerator | null} */
|
|
322
352
|
_pmremGenerator = null;
|
|
323
|
-
/** @type {WebGLRenderer | null} */
|
|
353
|
+
/** @type {import("three").WebGLRenderer | null} */
|
|
324
354
|
_renderer = null;
|
|
325
|
-
/** @type {Map<Texture | null, EnvironmentTextureSet
|
|
355
|
+
/** @type {Map<Texture | null, Map<string, EnvironmentTextureSet>>} */
|
|
326
356
|
_texturesCache = new Map();
|
|
327
357
|
|
|
328
358
|
/**
|
|
329
|
-
* @param {WebGLRenderer} renderer
|
|
359
|
+
* @param {import("three").WebGLRenderer} renderer
|
|
330
360
|
* @returns {Promise<boolean>}
|
|
331
361
|
*/
|
|
332
362
|
async _initialize(renderer) {
|
|
333
363
|
this._isInitialized = false;
|
|
334
|
-
this._pmremGenerator = new PMREMGenerator(renderer);
|
|
335
364
|
this._renderer = renderer;
|
|
336
365
|
this.updateLighting(true);
|
|
337
366
|
this._isInitialized = true;
|
|
@@ -340,30 +369,65 @@ export class MaterialXEnvironment {
|
|
|
340
369
|
|
|
341
370
|
/**
|
|
342
371
|
* @param {Texture | null | undefined} texture
|
|
343
|
-
* @
|
|
372
|
+
* @param {"three-pmrem" | "materialx-prefiltered" | "materialx-fis"} [radianceMode]
|
|
373
|
+
* @returns {EnvironmentTextureSet}
|
|
344
374
|
*/
|
|
345
|
-
_getTextures(texture) {
|
|
375
|
+
_getTextures(texture, radianceMode = "three-pmrem") {
|
|
346
376
|
|
|
347
377
|
// Fallback to white texture if no texture is provided
|
|
348
378
|
if (!texture) {
|
|
349
379
|
texture = whiteTexture;
|
|
350
380
|
}
|
|
351
381
|
|
|
382
|
+
const cacheKey = texture || null;
|
|
383
|
+
let textureModeMap = this._texturesCache.get(cacheKey);
|
|
384
|
+
if (!textureModeMap) {
|
|
385
|
+
textureModeMap = new Map();
|
|
386
|
+
this._texturesCache.set(cacheKey, textureModeMap);
|
|
387
|
+
}
|
|
388
|
+
|
|
352
389
|
/** @type {EnvironmentTextureSet | undefined} */
|
|
353
|
-
let res =
|
|
390
|
+
let res = textureModeMap.get(radianceMode);
|
|
354
391
|
if (res) {
|
|
355
392
|
return res;
|
|
356
393
|
}
|
|
357
394
|
|
|
358
|
-
|
|
395
|
+
const isPmremTexture = texture.mapping === CubeUVReflectionMapping || texture.isRenderTargetTexture === true;
|
|
396
|
+
|
|
397
|
+
if (this._scene && this._renderer && texture) {
|
|
359
398
|
if (debug) console.log("[MaterialX] Generating environment textures", texture.name);
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
399
|
+
let radianceRenderTarget;
|
|
400
|
+
let irradianceRenderTarget;
|
|
401
|
+
|
|
402
|
+
if (isPmremTexture) {
|
|
403
|
+
// Scene.environment is often already PMREM-processed (CubeUV layout).
|
|
404
|
+
// Running PMREMGenerator on it again corrupts the sampling layout.
|
|
405
|
+
radianceRenderTarget = radianceMode === "materialx-prefiltered"
|
|
406
|
+
? renderPMREMToPrefilteredEquirect(this._renderer, texture)
|
|
407
|
+
: radianceMode === "materialx-fis"
|
|
408
|
+
? renderPMREMToEquirect(this._renderer, texture, 0.0, 1024, 512)
|
|
409
|
+
: null;
|
|
410
|
+
irradianceRenderTarget = renderPMREMToEquirect(this._renderer, texture, 1.0, 32, 16);
|
|
411
|
+
} else {
|
|
412
|
+
const target = this._getPMREMGenerator().fromEquirectangular(texture);
|
|
413
|
+
radianceRenderTarget = radianceMode === "materialx-prefiltered"
|
|
414
|
+
? renderPMREMToPrefilteredEquirect(this._renderer, target.texture, undefined, undefined, target.height)
|
|
415
|
+
: radianceMode === "three-pmrem"
|
|
416
|
+
? target
|
|
417
|
+
: null;
|
|
418
|
+
irradianceRenderTarget = renderPMREMToEquirect(this._renderer, target.texture, 1.0, 32, 16, target.height);
|
|
419
|
+
if (radianceMode !== "three-pmrem") {
|
|
420
|
+
target.dispose();
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
|
|
364
424
|
res = {
|
|
365
|
-
radianceTexture: radianceRenderTarget
|
|
366
|
-
irradianceTexture: irradianceRenderTarget.texture
|
|
425
|
+
radianceTexture: radianceRenderTarget?.texture ?? texture,
|
|
426
|
+
irradianceTexture: irradianceRenderTarget.texture,
|
|
427
|
+
dispose: () => {
|
|
428
|
+
radianceRenderTarget?.dispose();
|
|
429
|
+
irradianceRenderTarget?.dispose();
|
|
430
|
+
},
|
|
367
431
|
}
|
|
368
432
|
}
|
|
369
433
|
else {
|
|
@@ -372,10 +436,21 @@ export class MaterialXEnvironment {
|
|
|
372
436
|
irradianceTexture: null
|
|
373
437
|
}
|
|
374
438
|
}
|
|
375
|
-
|
|
439
|
+
textureModeMap.set(radianceMode, res);
|
|
376
440
|
return res;
|
|
377
441
|
}
|
|
378
442
|
|
|
443
|
+
/**
|
|
444
|
+
* @returns {PMREMGenerator}
|
|
445
|
+
*/
|
|
446
|
+
_getPMREMGenerator() {
|
|
447
|
+
if (!this._renderer) {
|
|
448
|
+
throw new Error("[MaterialX] Cannot create PMREMGenerator before renderer initialization.");
|
|
449
|
+
}
|
|
450
|
+
this._pmremGenerator ??= new PMREMGenerator(this._renderer);
|
|
451
|
+
return this._pmremGenerator;
|
|
452
|
+
}
|
|
453
|
+
|
|
379
454
|
/**
|
|
380
455
|
* @param {boolean} collectLights
|
|
381
456
|
*/
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { BufferGeometry, Camera, Group, IUniform, MaterialParameters, Object3D, Scene, ShaderMaterial, Texture, WebGLRenderer } from "three";
|
|
1
|
+
import { BufferGeometry, Camera, Euler, Group, IUniform, MaterialParameters, Object3D, Scene, ShaderMaterial, Texture, WebGLRenderer } from "three";
|
|
2
2
|
import { MaterialXContext, MaterialXEnvironment } from "./materialx.js";
|
|
3
|
+
import type { MaterialXEnvironmentRadianceMode } from "./materialx.js";
|
|
3
4
|
import { Callbacks } from "./materialx.helper.js";
|
|
4
5
|
|
|
5
6
|
declare type MaterialXMaterialInitParameters = {
|
|
@@ -9,6 +10,8 @@ declare type MaterialXMaterialInitParameters = {
|
|
|
9
10
|
loaders: Callbacks;
|
|
10
11
|
context: MaterialXContext;
|
|
11
12
|
parameters?: MaterialParameters;
|
|
13
|
+
environmentRadianceMode?: MaterialXEnvironmentRadianceMode;
|
|
14
|
+
specularAntialiasing?: boolean;
|
|
12
15
|
debug?: boolean;
|
|
13
16
|
}
|
|
14
17
|
|
|
@@ -17,6 +20,7 @@ type Precision = "highp" | "mediump" | "lowp";
|
|
|
17
20
|
|
|
18
21
|
export declare class MaterialXMaterial extends ShaderMaterial {
|
|
19
22
|
readonly shaderName: string | null;
|
|
23
|
+
readonly ready: Promise<void>;
|
|
20
24
|
|
|
21
25
|
copy(source: MaterialXMaterial): this;
|
|
22
26
|
|
|
@@ -31,7 +35,12 @@ export declare class MaterialXMaterial extends ShaderMaterial {
|
|
|
31
35
|
|
|
32
36
|
envMapIntensity: number;
|
|
33
37
|
envMap: Texture | null;
|
|
38
|
+
envMapRotation: Euler;
|
|
39
|
+
environmentRadianceMode: MaterialXEnvironmentRadianceMode;
|
|
40
|
+
specularAntialiasing: boolean;
|
|
34
41
|
updateUniforms(environment: MaterialXEnvironment, _renderer: WebGLRenderer, object: Object3D, camera: Camera, time?: number, frame?: number): void;
|
|
35
42
|
|
|
36
|
-
private updateEnvironmentUniforms(environment: MaterialXEnvironment): void;
|
|
43
|
+
private updateEnvironmentUniforms(environment: MaterialXEnvironment, scene: Scene): void;
|
|
37
44
|
}
|
|
45
|
+
|
|
46
|
+
export declare const DEFAULT_ENVIRONMENT_RADIANCE_MODE: MaterialXEnvironmentRadianceMode;
|