@needle-tools/materialx 1.7.0-next.0d06218 → 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 +4 -0
- package/LICENSE.txt +131 -0
- package/bin/JsMaterialXCore.js +1 -1
- package/bin/JsMaterialXGenShader.js +1 -1
- package/package.json +9 -2
- package/src/constants.js +4 -5
- package/src/materialx.helper.d.ts +1 -1
- package/src/materialx.helper.js +16 -5
- package/src/materialx.js +22 -6
- package/src/materialx.material.js +113 -35
- package/src/utils.js +16 -9
- package/src/utils.texture.js +3 -3
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
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.7.0-next.
|
|
4
|
+
"version": "1.7.0-next.57183d6",
|
|
5
5
|
"type": "module",
|
|
6
|
+
"license": "PolyForm-Noncommercial-1.0.0",
|
|
6
7
|
"main": "index.js",
|
|
7
8
|
"types": "index.d.ts",
|
|
8
9
|
"exports": {
|
|
@@ -26,7 +27,10 @@
|
|
|
26
27
|
"three": ">=0.160.0"
|
|
27
28
|
},
|
|
28
29
|
"scripts": {
|
|
29
|
-
"test": "node --import=./tests/unit/register-json-loader.js --test tests/unit/**/*.test.js"
|
|
30
|
+
"test": "node --import=./tests/unit/register-json-loader.js --test tests/unit/**/*.test.js",
|
|
31
|
+
"test:runtime:node": "node tests/runtime/materialx-runtime-smoke.mjs",
|
|
32
|
+
"test:runtime:deno": "deno run --allow-read --no-lock --node-modules-dir=auto tests/runtime/materialx-runtime-smoke.mjs",
|
|
33
|
+
"test:runtime:bun": "bun tests/runtime/materialx-runtime-smoke.mjs"
|
|
30
34
|
},
|
|
31
35
|
"devDependencies": {
|
|
32
36
|
"@needle-tools/engine": "4.x",
|
|
@@ -35,6 +39,9 @@
|
|
|
35
39
|
"jsdom": "^29.0.1",
|
|
36
40
|
"three": "npm:@needle-tools/three@^0.169.5"
|
|
37
41
|
},
|
|
42
|
+
"overrides": {
|
|
43
|
+
"@needle-tools/gltf-progressive": "3.6.0-beta.2"
|
|
44
|
+
},
|
|
38
45
|
"files": [
|
|
39
46
|
"index.js",
|
|
40
47
|
"index.d.ts",
|
package/src/constants.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Node.js
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import pkg from '../package.json';
|
|
1
|
+
// Keep the runtime version tied to package.json. The import attribute is
|
|
2
|
+
// required by browsers and Node.js for JSON modules; bundlers also understand
|
|
3
|
+
// this shape.
|
|
4
|
+
import pkg from '../package.json' with { type: 'json' };
|
|
6
5
|
export const VERSION = pkg.version;
|
|
@@ -16,7 +16,7 @@ export interface LightData {
|
|
|
16
16
|
outer_angle: number;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
export function prepareEnvTexture(texture: THREE.Texture, capabilities
|
|
19
|
+
export function prepareEnvTexture(texture: THREE.Texture, capabilities?: any): THREE.Texture;
|
|
20
20
|
|
|
21
21
|
export function getLightRotation(): THREE.Matrix4;
|
|
22
22
|
|
package/src/materialx.helper.js
CHANGED
|
@@ -21,7 +21,7 @@ const IMAGE_PATH_SEPARATOR = "/";
|
|
|
21
21
|
export function prepareEnvTexture(texture, capabilities) {
|
|
22
22
|
const newTexture = new THREE.DataTexture(texture.image.data, texture.image.width, texture.image.height, /** @type {any} */(texture.format), texture.type);
|
|
23
23
|
newTexture.wrapS = THREE.RepeatWrapping;
|
|
24
|
-
newTexture.anisotropy = capabilities
|
|
24
|
+
newTexture.anisotropy = capabilities?.getMaxAnisotropy?.() ?? 1;
|
|
25
25
|
newTexture.minFilter = THREE.LinearMipmapLinearFilter;
|
|
26
26
|
newTexture.magFilter = THREE.LinearFilter;
|
|
27
27
|
newTexture.generateMipmaps = true;
|
|
@@ -71,10 +71,22 @@ function fromMatrix(matrix, dimension) {
|
|
|
71
71
|
* @property {(path: string) => Promise<THREE.Texture | null | void>} getTexture - Get a texture by path
|
|
72
72
|
*/
|
|
73
73
|
|
|
74
|
+
/**
|
|
75
|
+
* @param {string} src
|
|
76
|
+
* @returns {HTMLImageElement | { src: string }}
|
|
77
|
+
*/
|
|
78
|
+
function createPortableImage(src) {
|
|
79
|
+
if (typeof Image !== 'undefined') {
|
|
80
|
+
const image = new Image();
|
|
81
|
+
image.src = src;
|
|
82
|
+
return image;
|
|
83
|
+
}
|
|
84
|
+
return { src };
|
|
85
|
+
}
|
|
86
|
+
|
|
74
87
|
const defaultTexture = new THREE.Texture();
|
|
75
88
|
defaultTexture.needsUpdate = true;
|
|
76
|
-
defaultTexture.image =
|
|
77
|
-
defaultTexture.image.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAAAXNSR0IB2cksfwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAANQTFRFr6+vGqg52AAAAAxJREFUeJxjZGBEgQAAWAAJLpjsTQAAAABJRU5ErkJggg=="
|
|
89
|
+
defaultTexture.image = createPortableImage("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAAAXNSR0IB2cksfwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAANQTFRFr6+vGqg52AAAAAxJREFUeJxjZGBEgQAAWAAJLpjsTQAAAABJRU5ErkJggg==");
|
|
78
90
|
// defaultTexture.image.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAAXNSR0IB2cksfwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAB5QTFRFAAAABAQEw8PD////v7+/vb29Xl5eQEBA+/v7PDw8GPBYkgAAAB1JREFUeJxjZGBgYFQSABIUMlxgDGMGBtaIAnIZAKwQCSDYUEZEAAAAAElFTkSuQmCC";
|
|
79
91
|
// defaultTexture.wrapS = THREE.RepeatWrapping;
|
|
80
92
|
// defaultTexture.wrapT = THREE.RepeatWrapping;
|
|
@@ -84,8 +96,7 @@ defaultTexture.image.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAA
|
|
|
84
96
|
|
|
85
97
|
const defaultNormalTexture = new THREE.Texture();
|
|
86
98
|
defaultNormalTexture.needsUpdate = true;
|
|
87
|
-
defaultNormalTexture.image =
|
|
88
|
-
defaultNormalTexture.image.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIBAMAAAA2IaO4AAAAAXNSR0IB2cksfwAAAAlwSFlzAAALEwAACxMBAJqcGAAAABJQTFRFgYH4gIH4gYH3gIH3gIH5gID4m94ORAAAADFJREFUeJxjZBBkfMdo9P/BB0aBj/8FGB0ufghgFGT4r8wo+P8rD2Pgo3sMjIz8jAwAMLoN0ZjS5hgAAAAASUVORK5CYII=";
|
|
99
|
+
defaultNormalTexture.image = createPortableImage("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIBAMAAAA2IaO4AAAAAXNSR0IB2cksfwAAAAlwSFlzAAALEwAACxMBAJqcGAAAABJQTFRFgYH4gIH4gYH3gIH3gIH5gID4m94ORAAAADFJREFUeJxjZBBkfMdo9P/BB0aBj/8FGB0ufghgFGT4r8wo+P8rD2Pgo3sMjIz8jAwAMLoN0ZjS5hgAAAAASUVORK5CYII=");
|
|
89
100
|
|
|
90
101
|
/**
|
|
91
102
|
* @param {string} key
|
package/src/materialx.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import MaterialX from "../bin/JsMaterialXGenShader.js";
|
|
2
2
|
import { debug, waitForNetworkIdle } from "./utils.js";
|
|
3
3
|
import { renderPMREMToEquirect, renderPMREMToPrefilteredEquirect } from "./utils.texture.js";
|
|
4
|
-
import { CubeUVReflectionMapping, Light, Mesh, MeshBasicMaterial, Object3D, PlaneGeometry, PMREMGenerator, Scene, Texture
|
|
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";
|
|
@@ -17,6 +17,19 @@ function isTextureLike(value) {
|
|
|
17
17
|
return !!value && typeof value === "object" && /** @type {{ isTexture?: unknown }} */(value).isTexture === true;
|
|
18
18
|
}
|
|
19
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
|
+
|
|
20
33
|
|
|
21
34
|
/**
|
|
22
35
|
* Preloads the MaterialX WebAssembly module.
|
|
@@ -69,7 +82,10 @@ export async function ready() {
|
|
|
69
82
|
|
|
70
83
|
const location = globalThis.NEEDLE_MATERIALX_LOCATION;
|
|
71
84
|
|
|
72
|
-
if (
|
|
85
|
+
if (isNodeRuntime()) {
|
|
86
|
+
urls = await getNodePackageAssetPaths();
|
|
87
|
+
}
|
|
88
|
+
else if (location === "package" || location === "bin/" || location === "./bin/" || location === "../bin/") {
|
|
73
89
|
// Use local files from the @needle-tools/materialx npm package.
|
|
74
90
|
// Vite's ?url suffix copies these files to the output directory
|
|
75
91
|
// and returns their URL automatically — no CDN download needed.
|
|
@@ -229,7 +245,7 @@ export class MaterialXEnvironment {
|
|
|
229
245
|
|
|
230
246
|
/**
|
|
231
247
|
* Initialize with Needle Engine context
|
|
232
|
-
* @param {WebGLRenderer} renderer
|
|
248
|
+
* @param {import("three").WebGLRenderer} renderer
|
|
233
249
|
* @returns {Promise<boolean>}
|
|
234
250
|
*/
|
|
235
251
|
async initialize(renderer) {
|
|
@@ -243,7 +259,7 @@ export class MaterialXEnvironment {
|
|
|
243
259
|
/**
|
|
244
260
|
* @param {number} frame
|
|
245
261
|
* @param {Scene} scene
|
|
246
|
-
* @param {WebGLRenderer} renderer
|
|
262
|
+
* @param {import("three").WebGLRenderer} renderer
|
|
247
263
|
*/
|
|
248
264
|
update(frame, scene, renderer) {
|
|
249
265
|
if (!this._initializePromise) {
|
|
@@ -334,13 +350,13 @@ export class MaterialXEnvironment {
|
|
|
334
350
|
|
|
335
351
|
/** @type {PMREMGenerator | null} */
|
|
336
352
|
_pmremGenerator = null;
|
|
337
|
-
/** @type {WebGLRenderer | null} */
|
|
353
|
+
/** @type {import("three").WebGLRenderer | null} */
|
|
338
354
|
_renderer = null;
|
|
339
355
|
/** @type {Map<Texture | null, Map<string, EnvironmentTextureSet>>} */
|
|
340
356
|
_texturesCache = new Map();
|
|
341
357
|
|
|
342
358
|
/**
|
|
343
|
-
* @param {WebGLRenderer} renderer
|
|
359
|
+
* @param {import("three").WebGLRenderer} renderer
|
|
344
360
|
* @returns {Promise<boolean>}
|
|
345
361
|
*/
|
|
346
362
|
async _initialize(renderer) {
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { BufferGeometry, Camera, Euler, FrontSide, GLSL3, Group, Matrix4, Object3D, Scene, ShaderMaterial, Texture,
|
|
1
|
+
import { BufferGeometry, Camera, Euler, FrontSide, GLSL3, Group, Matrix4, Object3D, Scene, ShaderMaterial, Texture, Vector3 } from "three";
|
|
2
2
|
import { debug, getFrame, getTime } from "./utils.js";
|
|
3
3
|
import { MaterialXEnvironment } from "./materialx.js";
|
|
4
4
|
import { generateMaterialPropertiesForUniforms, getUniformValues, getLightTypeIds } from "./materialx.helper.js";
|
|
5
|
-
import { cloneUniforms, cloneUniformsGroups, mergeUniforms } from "three/src/renderers/shaders/UniformsUtils.js";
|
|
6
5
|
|
|
7
6
|
export const DEFAULT_ENVIRONMENT_RADIANCE_MODE = "three-pmrem";
|
|
8
7
|
|
|
@@ -15,6 +14,83 @@ const worldViewProjectionMat = new Matrix4();
|
|
|
15
14
|
const envMat = new Matrix4();
|
|
16
15
|
const envRotation = new Euler();
|
|
17
16
|
|
|
17
|
+
// Local copy of Three.js UniformsUtils.cloneUniforms from
|
|
18
|
+
// three/src/renderers/shaders/UniformsUtils.js. Keep this in sync with the
|
|
19
|
+
// minimum supported Three.js version when Three changes uniform cloning.
|
|
20
|
+
function cloneUniforms(src) {
|
|
21
|
+
const dst = {};
|
|
22
|
+
for (const uniformName in src) {
|
|
23
|
+
dst[uniformName] = {};
|
|
24
|
+
for (const propertyName in src[uniformName]) {
|
|
25
|
+
const property = src[uniformName][propertyName];
|
|
26
|
+
if (property && (
|
|
27
|
+
property.isColor ||
|
|
28
|
+
property.isMatrix3 || property.isMatrix4 ||
|
|
29
|
+
property.isVector2 || property.isVector3 || property.isVector4 ||
|
|
30
|
+
property.isTexture || property.isQuaternion
|
|
31
|
+
)) {
|
|
32
|
+
dst[uniformName][propertyName] = property.isRenderTargetTexture ? null : property.clone();
|
|
33
|
+
}
|
|
34
|
+
else if (Array.isArray(property)) {
|
|
35
|
+
dst[uniformName][propertyName] = property.slice();
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
dst[uniformName][propertyName] = property;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return dst;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Local copy of Three.js UniformsUtils.mergeUniforms from
|
|
46
|
+
// three/src/renderers/shaders/UniformsUtils.js. Copied to avoid importing from
|
|
47
|
+
// three/src, which breaks package consumers using Three's public ESM surface.
|
|
48
|
+
function mergeUniforms(uniforms) {
|
|
49
|
+
const merged = {};
|
|
50
|
+
for (const uniformSet of uniforms) {
|
|
51
|
+
const tmp = cloneUniforms(uniformSet);
|
|
52
|
+
for (const propertyName in tmp) {
|
|
53
|
+
merged[propertyName] = tmp[propertyName];
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return merged;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Local copy of Three.js UniformsUtils.cloneUniformsGroups from
|
|
60
|
+
// three/src/renderers/shaders/UniformsUtils.js. Keep alongside cloneUniforms
|
|
61
|
+
// and mergeUniforms so ShaderMaterial.clone() stays behavior-compatible.
|
|
62
|
+
function cloneUniformsGroups(src) {
|
|
63
|
+
return src.map(group => group.clone());
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function createThreeLightUniforms() {
|
|
67
|
+
return {
|
|
68
|
+
ambientLightColor: { value: [] },
|
|
69
|
+
lightProbe: { value: [] },
|
|
70
|
+
directionalLights: { value: [], properties: { direction: {}, color: {} } },
|
|
71
|
+
directionalLightShadows: { value: [], properties: { shadowIntensity: 1, shadowBias: {}, shadowNormalBias: {}, shadowRadius: {}, shadowMapSize: {} } },
|
|
72
|
+
directionalShadowMap: { value: [] },
|
|
73
|
+
directionalShadowMatrix: { value: [] },
|
|
74
|
+
spotLights: { value: [], properties: { color: {}, position: {}, direction: {}, distance: {}, coneCos: {}, penumbraCos: {}, decay: {} } },
|
|
75
|
+
spotLightShadows: { value: [], properties: { shadowIntensity: 1, shadowBias: {}, shadowNormalBias: {}, shadowRadius: {}, shadowMapSize: {} } },
|
|
76
|
+
spotLightMap: { value: [] },
|
|
77
|
+
spotShadowMap: { value: [] },
|
|
78
|
+
spotLightMatrix: { value: [] },
|
|
79
|
+
pointLights: { value: [], properties: { color: {}, position: {}, decay: {}, distance: {} } },
|
|
80
|
+
pointLightShadows: { value: [], properties: { shadowIntensity: 1, shadowBias: {}, shadowNormalBias: {}, shadowRadius: {}, shadowMapSize: {}, shadowCameraNear: {}, shadowCameraFar: {} } },
|
|
81
|
+
pointShadowMap: { value: [] },
|
|
82
|
+
pointShadowMatrix: { value: [] },
|
|
83
|
+
hemisphereLights: { value: [], properties: { direction: {}, skyColor: {}, groundColor: {} } },
|
|
84
|
+
rectAreaLights: { value: [], properties: { color: {}, position: {}, width: {}, height: {} } },
|
|
85
|
+
ltc_1: { value: null },
|
|
86
|
+
ltc_2: { value: null },
|
|
87
|
+
probesSH: { value: null },
|
|
88
|
+
probesMin: { value: new Vector3() },
|
|
89
|
+
probesMax: { value: new Vector3() },
|
|
90
|
+
probesResolution: { value: new Vector3() },
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
18
94
|
const CUBE_UV_REFLECTION_FUNCTIONS = `
|
|
19
95
|
float mx_cubeuv_getFace(vec3 direction) {
|
|
20
96
|
vec3 absDirection = abs(direction);
|
|
@@ -623,37 +699,39 @@ $2`
|
|
|
623
699
|
this.environmentRadianceMode = environmentRadianceMode;
|
|
624
700
|
this.specularAntialiasing = specularAntialiasing;
|
|
625
701
|
|
|
626
|
-
Object.assign(this.uniforms,
|
|
627
|
-
// Three.js light uniforms (required when lights: true)
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
702
|
+
Object.assign(this.uniforms,
|
|
703
|
+
// Three.js light uniforms (required when lights: true). These use
|
|
704
|
+
// Three's merge/clone semantics; generated MaterialX texture
|
|
705
|
+
// uniforms below must keep their original object identity so async
|
|
706
|
+
// texture resolution updates the same uniform object.
|
|
707
|
+
mergeUniforms([createThreeLightUniforms()]),
|
|
708
|
+
getUniformValues(init.shader.getStage('vertex'), init.loaders, searchPath, pendingTextureLoads),
|
|
709
|
+
getUniformValues(init.shader.getStage('pixel'), init.loaders, searchPath, pendingTextureLoads),
|
|
710
|
+
{
|
|
711
|
+
u_worldMatrix: { value: new Matrix4() },
|
|
712
|
+
u_worldInverseMatrix: { value: new Matrix4() },
|
|
713
|
+
u_worldTransposeMatrix: { value: new Matrix4() },
|
|
714
|
+
u_worldInverseTransposeMatrix: { value: new Matrix4() },
|
|
715
|
+
u_worldViewMatrix: { value: new Matrix4() },
|
|
716
|
+
u_viewProjectionMatrix: { value: new Matrix4() },
|
|
717
|
+
u_worldViewProjectionMatrix: { value: new Matrix4() },
|
|
718
|
+
u_viewPosition: { value: new Vector3() },
|
|
719
|
+
|
|
720
|
+
u_envMatrix: { value: new Matrix4() },
|
|
721
|
+
u_envRadiance: { value: null, type: 't' },
|
|
722
|
+
u_envRadianceMips: { value: 8, type: 'i' },
|
|
723
|
+
u_envRadianceCubeUVTexelWidth: { value: 1 / 768 },
|
|
724
|
+
u_envRadianceCubeUVTexelHeight: { value: 1 / 1024 },
|
|
725
|
+
u_envRadianceCubeUVMaxMip: { value: 8 },
|
|
726
|
+
// TODO we need to figure out how we can set a PMREM here... doing many texture samples is prohibitively expensive
|
|
727
|
+
u_envRadianceSamples: { value: 8, type: 'i' },
|
|
728
|
+
u_envIrradiance: { value: null, type: 't' },
|
|
729
|
+
envMapIntensity: { value: 1.0 },
|
|
730
|
+
u_refractionEnv: { value: true },
|
|
731
|
+
u_refractionTwoSided: { value: false },
|
|
732
|
+
u_numActiveLightSources: { value: 0 },
|
|
733
|
+
u_lightData: { value: [], needsUpdate: false }, // Array of light data. We need to set needsUpdate to false until we actually update it
|
|
734
|
+
});
|
|
657
735
|
this.ready = Promise.all(pendingTextureLoads).then(() => undefined);
|
|
658
736
|
|
|
659
737
|
generateMaterialPropertiesForUniforms(this, init.shader.getStage('pixel'));
|
|
@@ -673,7 +751,7 @@ $2`
|
|
|
673
751
|
_missingTangentsWarned = false;
|
|
674
752
|
|
|
675
753
|
/**
|
|
676
|
-
* @param {WebGLRenderer} renderer
|
|
754
|
+
* @param {import("three").WebGLRenderer} renderer
|
|
677
755
|
* @param {Scene} _scene
|
|
678
756
|
* @param {Camera} camera
|
|
679
757
|
* @param {BufferGeometry} geometry
|
|
@@ -710,7 +788,7 @@ $2`
|
|
|
710
788
|
specularAntialiasing = true;
|
|
711
789
|
|
|
712
790
|
/**
|
|
713
|
-
* @param {WebGLRenderer} _renderer
|
|
791
|
+
* @param {import("three").WebGLRenderer} _renderer
|
|
714
792
|
* @param {Object3D} object
|
|
715
793
|
* @param {Camera} camera
|
|
716
794
|
* @param {number} [time]
|
package/src/utils.js
CHANGED
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
* @returns {boolean|string} Parameter value or false if not found
|
|
8
8
|
*/
|
|
9
9
|
export function getParam(name) {
|
|
10
|
-
const
|
|
10
|
+
const search = globalThis.location?.search ?? globalThis.window?.location?.search;
|
|
11
|
+
if (!search) return false;
|
|
12
|
+
const urlParams = new URLSearchParams(search);
|
|
11
13
|
const param = urlParams.get(name);
|
|
12
14
|
if (param == null || param === "0" || param === "false") return false;
|
|
13
15
|
if (param === "") return true;
|
|
@@ -35,22 +37,26 @@ export function getFrame() {
|
|
|
35
37
|
return frame;
|
|
36
38
|
}
|
|
37
39
|
|
|
38
|
-
const
|
|
40
|
+
const performanceApi = globalThis.performance
|
|
41
|
+
|| globalThis.window?.performance
|
|
42
|
+
|| /** @type {any} */ (globalThis.window)?.webkitPerformance
|
|
43
|
+
|| /** @type {any} */ (globalThis.window)?.mozPerformance
|
|
44
|
+
|| { now: () => Date.now() };
|
|
39
45
|
|
|
40
46
|
function updateTime() {
|
|
41
|
-
time =
|
|
47
|
+
time = performanceApi.now() / 1000; // Convert to seconds
|
|
42
48
|
frame++;
|
|
43
|
-
|
|
49
|
+
globalThis.requestAnimationFrame?.(updateTime);
|
|
44
50
|
}
|
|
45
51
|
|
|
46
|
-
|
|
52
|
+
globalThis.requestAnimationFrame?.(updateTime);
|
|
47
53
|
|
|
48
54
|
|
|
49
55
|
|
|
50
56
|
|
|
51
57
|
export async function waitForNetworkIdle() {
|
|
52
|
-
if (typeof requestIdleCallback !== "undefined") {
|
|
53
|
-
return new Promise(res => requestIdleCallback(res));
|
|
58
|
+
if (typeof globalThis.requestIdleCallback !== "undefined") {
|
|
59
|
+
return new Promise(res => globalThis.requestIdleCallback(res));
|
|
54
60
|
}
|
|
55
61
|
else {
|
|
56
62
|
console.debug("[MaterialX] Can not wait for network idle, using fallback");
|
|
@@ -61,5 +67,6 @@ export async function waitForNetworkIdle() {
|
|
|
61
67
|
|
|
62
68
|
export function isDevEnvironment() {
|
|
63
69
|
// check if we're in localhost or using an ip address
|
|
64
|
-
|
|
65
|
-
}
|
|
70
|
+
const hostname = globalThis.location?.hostname ?? globalThis.window?.location?.hostname;
|
|
71
|
+
return hostname === "localhost" || !!hostname && /^\d{1,3}(\.\d{1,3}){3}$/.test(hostname);
|
|
72
|
+
}
|
package/src/utils.texture.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Scene, WebGLRenderTarget, PlaneGeometry, OrthographicCamera, ShaderMaterial, RGBAFormat, FloatType, LinearFilter, Mesh, EquirectangularReflectionMapping, RepeatWrapping, LinearMipMapLinearFilter, DataTexture, UnsignedByteType, Vector4 } from 'three';
|
|
2
2
|
import { getParam } from './utils.js';
|
|
3
3
|
|
|
4
4
|
const debug = getParam("debugmaterialx");
|
|
@@ -96,7 +96,7 @@ function createPrefilteredEquirectMaterial(pmremTexture, cubeUVSize) {
|
|
|
96
96
|
|
|
97
97
|
/**
|
|
98
98
|
* Renders a PMREM environment map to an equirectangular texture with specified roughness
|
|
99
|
-
* @param {WebGLRenderer} renderer - Three.js WebGL renderer
|
|
99
|
+
* @param {import("three").WebGLRenderer} renderer - Three.js WebGL renderer
|
|
100
100
|
* @param {Texture} pmremTexture - PMREM texture (2D CubeUV layout) to convert
|
|
101
101
|
* @param {number} [roughness=0.0] - Roughness value (0.0 to 1.0)
|
|
102
102
|
* @param {number} [width=1024] - Output texture width
|
|
@@ -249,7 +249,7 @@ export function renderPMREMToEquirect(renderer, pmremTexture, roughness = 0.0, w
|
|
|
249
249
|
/**
|
|
250
250
|
* Renders a Three.js PMREM CubeUV texture to an equirectangular texture whose mip
|
|
251
251
|
* levels encode increasing roughness for MaterialX SPECULAR_ENVIRONMENT_PREFILTER.
|
|
252
|
-
* @param {WebGLRenderer} renderer
|
|
252
|
+
* @param {import("three").WebGLRenderer} renderer
|
|
253
253
|
* @param {Texture} pmremTexture
|
|
254
254
|
* @param {number} [width=2048]
|
|
255
255
|
* @param {number} [height=1024]
|