@needle-tools/materialx 1.0.1 → 1.0.2-next.c468cd8
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 +5 -0
- package/README.md +5 -0
- package/codegen/register_types.ts +4 -0
- package/index.ts +1 -1
- package/package.json +19 -4
- package/src/index.ts +2 -2
- package/src/loader/loader.needle.ts +27 -40
- package/src/loader/loader.three.ts +142 -397
- package/src/materialx.helper.ts +478 -0
- package/src/materialx.material.ts +217 -0
- package/src/materialx.ts +161 -128
- package/src/materialx.types.d.ts +50 -0
- package/src/textureHelper.ts +6 -6
- package/src/utils.ts +39 -4
- package/src/helper.js +0 -457
package/src/materialx.ts
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import { Context, delay, isDevEnvironment, ObjectUtils } from "@needle-tools/engine";
|
|
1
|
+
import { Context, delay, isDevEnvironment, ObjectUtils, GameObject, onBeforeRender } from "@needle-tools/engine";
|
|
2
|
+
import type { MaterialX as MX } from "./materialx.types.js";
|
|
2
3
|
import MaterialX from "../bin/JsMaterialXGenShader.js";
|
|
3
4
|
import { debug } from "./utils.js";
|
|
4
5
|
import { renderPMREMToEquirect } from "./textureHelper.js";
|
|
5
|
-
import { Light, MeshBasicMaterial, Object3D, PMREMGenerator } from "three";
|
|
6
|
-
import { registerLights } from "./helper.js";
|
|
6
|
+
import { Light, Material, MeshBasicMaterial, Object3D, PMREMGenerator, Texture } from "three";
|
|
7
|
+
import { registerLights, getLightData } from "./materialx.helper.js";
|
|
8
|
+
import type { MaterialXMaterial } from "./materialx.material.js";
|
|
7
9
|
|
|
8
10
|
|
|
9
|
-
// Global MaterialX module instance - initialized lazily
|
|
10
11
|
export const state = new class {
|
|
11
|
-
materialXModule:
|
|
12
|
+
materialXModule: MX.MODULE | null = null;
|
|
12
13
|
materialXGenerator: any = null;
|
|
13
14
|
materialXGenContext: any = null;
|
|
14
15
|
materialXStdLib: any = null;
|
|
@@ -22,14 +23,14 @@ export const state = new class {
|
|
|
22
23
|
}
|
|
23
24
|
}
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
export async function
|
|
26
|
+
/** Initialize the MaterialX module. Must be awaited before trying to create materials */
|
|
27
|
+
export async function ready(): Promise<void> {
|
|
27
28
|
if (state.materialXInitPromise) {
|
|
28
29
|
return state.materialXInitPromise;
|
|
29
30
|
}
|
|
30
31
|
return state.materialXInitPromise = (async () => {
|
|
31
32
|
if (state.materialXModule) return; // Already initialized
|
|
32
|
-
if (debug) console.log("Initializing
|
|
33
|
+
if (debug) console.log("[MaterialX] Initializing WASM module...");
|
|
33
34
|
try {
|
|
34
35
|
|
|
35
36
|
const urls: Array<string> = await Promise.all([
|
|
@@ -44,7 +45,7 @@ export async function initializeMaterialX(): Promise<void> {
|
|
|
44
45
|
|
|
45
46
|
const module = await MaterialX({
|
|
46
47
|
locateFile: (path: string, scriptDirectory: string) => {
|
|
47
|
-
if (debug) console.debug("MaterialX
|
|
48
|
+
if (debug) console.debug("[MaterialX] locateFile called:", { path, scriptDirectory });
|
|
48
49
|
|
|
49
50
|
if (path.includes("JsMaterialXCore.wasm")) {
|
|
50
51
|
return JsMaterialXCore; // Use the URL for the core WASM file
|
|
@@ -59,8 +60,8 @@ export async function initializeMaterialX(): Promise<void> {
|
|
|
59
60
|
return scriptDirectory + path;
|
|
60
61
|
},
|
|
61
62
|
});
|
|
62
|
-
if (debug) console.log("
|
|
63
|
-
state.materialXModule = module
|
|
63
|
+
if (debug) console.log("[MaterialX] module loaded", module);
|
|
64
|
+
state.materialXModule = module as MX.MODULE
|
|
64
65
|
|
|
65
66
|
// Initialize shader generator and context
|
|
66
67
|
state.materialXGenerator = module.EsslShaderGenerator.create();
|
|
@@ -71,158 +72,190 @@ export async function initializeMaterialX(): Promise<void> {
|
|
|
71
72
|
state.materialXStdLib = module.loadStandardLibraries(state.materialXGenContext);
|
|
72
73
|
tempDoc.setDataLibrary(state.materialXStdLib);
|
|
73
74
|
|
|
74
|
-
//
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
//
|
|
78
|
-
//
|
|
79
|
-
//
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
//
|
|
83
|
-
//
|
|
75
|
+
// TODO ShaderInterfaceType.SHADER_INTERFACE_REDUCED would be better, but doesn't actually seem to be supported in the MaterialX javascript bindings
|
|
76
|
+
state.materialXGenContext.getOptions().shaderInterfaceType = state.materialXModule.ShaderInterfaceType.SHADER_INTERFACE_COMPLETE;
|
|
77
|
+
|
|
78
|
+
// SPECULAR_ENVIRONMENT_NONE: Do not use specular environment maps.
|
|
79
|
+
// SPECULAR_ENVIRONMENT_FIS: Use Filtered Importance Sampling for specular environment/indirect lighting.
|
|
80
|
+
// SPECULAR_ENVIRONMENT_PREFILTER: Use pre-filtered environment maps for specular environment/indirect lighting.
|
|
81
|
+
state.materialXGenContext.getOptions().hwSpecularEnvironmentMethod = state.materialXModule.HwSpecularEnvironmentMethod.SPECULAR_ENVIRONMENT_FIS;
|
|
82
|
+
|
|
83
|
+
// TRANSMISSION_REFRACTION: Use a refraction approximation for transmission rendering.
|
|
84
|
+
// TRANSMISSION_OPACITY: Use opacity for transmission rendering.
|
|
85
|
+
// state.materialXGenContext.getOptions().hwTransmissionRenderMethod = state.materialXModule.HwTransmissionRenderMethod.TRANSMISSION_REFRACTION;
|
|
86
|
+
|
|
87
|
+
// Turned off because we're doing color space conversion the three.js way
|
|
88
|
+
state.materialXGenContext.getOptions().hwSrgbEncodeOutput = false;
|
|
89
|
+
|
|
90
|
+
// Enables the generation of a prefiltered environment map.
|
|
91
|
+
// TODO Would be great to use but requires setting more uniforms (like u_envPrefilterMip).
|
|
92
|
+
// When set to true, the u_envRadiance map is expected to be a prefiltered environment map.
|
|
93
|
+
// state.materialXGenContext.getOptions().hwWriteEnvPrefilter = true;
|
|
94
|
+
|
|
95
|
+
// Set a reasonable default for max active lights
|
|
96
|
+
state.materialXGenContext.getOptions().hwMaxActiveLightSources = 4;
|
|
84
97
|
|
|
85
98
|
// This prewarms the shader generation context to have all light types
|
|
86
|
-
await registerLights(state.materialXModule,
|
|
99
|
+
await registerLights(state.materialXModule, state.materialXGenContext);
|
|
87
100
|
|
|
88
|
-
if (debug) console.log("MaterialX
|
|
101
|
+
if (debug) console.log("[MaterialX] Generator initialized successfully");
|
|
89
102
|
} catch (error) {
|
|
90
|
-
console.error("Failed to load MaterialX module:", error);
|
|
103
|
+
console.error("[MaterialX] Failed to load MaterialX module:", error);
|
|
91
104
|
throw error;
|
|
92
105
|
}
|
|
93
106
|
})();
|
|
94
107
|
}
|
|
95
108
|
|
|
109
|
+
type EnvironmentTextureSet = {
|
|
110
|
+
radianceTexture: Texture | null;
|
|
111
|
+
irradianceTexture: Texture | null;
|
|
112
|
+
}
|
|
113
|
+
|
|
96
114
|
// MaterialX Environment Manager - handles lighting and environment setup
|
|
97
115
|
export class MaterialXEnvironment {
|
|
98
|
-
private
|
|
99
|
-
private
|
|
100
|
-
private
|
|
101
|
-
private
|
|
102
|
-
private
|
|
103
|
-
|
|
116
|
+
private _context: Context | null = null;
|
|
117
|
+
private _lights: Array<Light> = [];
|
|
118
|
+
private _lightData: any = null;
|
|
119
|
+
private _lightCount: number = 0;
|
|
120
|
+
private _initializePromise: Promise<boolean> | null = null;
|
|
121
|
+
|
|
122
|
+
private _unsubscribehook: (() => void) | null = null;
|
|
104
123
|
|
|
105
124
|
constructor() {
|
|
106
|
-
if (debug) console.log("MaterialX Environment created");
|
|
125
|
+
if (debug) console.log("[MaterialX] Environment created");
|
|
107
126
|
}
|
|
108
127
|
|
|
109
|
-
|
|
110
|
-
|
|
128
|
+
// Initialize with Needle Engine context
|
|
129
|
+
async initialize(context: Context): Promise<boolean> {
|
|
130
|
+
if (this._initializePromise) {
|
|
131
|
+
return this._initializePromise;
|
|
132
|
+
}
|
|
133
|
+
return this._initializePromise = this._initialize(context);
|
|
111
134
|
}
|
|
112
135
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
if (
|
|
117
|
-
|
|
118
|
-
return;
|
|
136
|
+
get lightData() { return this._lightData; }
|
|
137
|
+
get lightCount() { return this._lightCount || 0; }
|
|
138
|
+
getTextures(material: MaterialXMaterial) {
|
|
139
|
+
if (material.envMap) {
|
|
140
|
+
// If the material has its own envMap, we don't use the irradiance texture
|
|
141
|
+
return this._getTextures(material.envMap);
|
|
119
142
|
}
|
|
120
|
-
|
|
121
|
-
registerLights(materialXModule, this.lights, materialXGenContext);
|
|
143
|
+
return this._getTextures(this._context?.scene.environment);
|
|
122
144
|
}
|
|
123
|
-
*/
|
|
124
145
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
if (!this.context) {
|
|
128
|
-
console.warn("No Needle context available for MaterialX environment initialization");
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
146
|
+
private _pmremGenerator: PMREMGenerator | null = null;
|
|
147
|
+
private readonly _texturesCache: Map<Texture | null, EnvironmentTextureSet> = new Map();
|
|
131
148
|
|
|
132
|
-
|
|
133
|
-
if (this.initialized) {
|
|
134
|
-
if (debug) console.log("MaterialX environment already initialized, skipping");
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
149
|
+
private _initialize: (context: Context) => Promise<boolean> = async (context: Context) => {
|
|
137
150
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
if (debug) console.log("Disposing previous radiance texture");
|
|
141
|
-
this.radianceTexture.dispose();
|
|
142
|
-
this.radianceTexture = null;
|
|
143
|
-
}
|
|
144
|
-
if (this.irradianceTexture) {
|
|
145
|
-
if (debug) console.log("Disposing previous irradiance texture");
|
|
146
|
-
this.irradianceTexture.dispose();
|
|
147
|
-
this.irradianceTexture = null;
|
|
148
|
-
}
|
|
151
|
+
this._context = context;
|
|
152
|
+
this._pmremGenerator = new PMREMGenerator(context.renderer);
|
|
149
153
|
|
|
150
|
-
|
|
151
|
-
|
|
154
|
+
this._unsubscribehook?.();
|
|
155
|
+
this._unsubscribehook = onBeforeRender(() => {
|
|
156
|
+
this.updateLighting(false);
|
|
157
|
+
this._getTextures(context.scene.environment);
|
|
158
|
+
})
|
|
152
159
|
|
|
153
160
|
// TODO remove this delay; we should wait for the scene lighting to be ready
|
|
154
161
|
// and then update the uniforms
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
await delay(200);
|
|
158
|
-
envMap = this.context.scene.environment;
|
|
159
|
-
}
|
|
160
|
-
var pmrem = new PMREMGenerator(renderer);
|
|
161
|
-
const target = pmrem.fromEquirectangular(envMap);
|
|
162
|
-
|
|
163
|
-
const radianceRenderTarget = renderPMREMToEquirect(renderer, target.texture, 0.0, 1024, 512, target.height);
|
|
164
|
-
const irradianceRenderTarget = renderPMREMToEquirect(renderer, target.texture, 1.0, 32, 16, target.height);
|
|
165
|
-
|
|
166
|
-
this.radianceTexture = radianceRenderTarget.texture;
|
|
167
|
-
this.irradianceTexture = irradianceRenderTarget.texture;
|
|
168
|
-
|
|
169
|
-
// Clean up PMREM generator and its render target
|
|
170
|
-
target.dispose();
|
|
171
|
-
pmrem.dispose();
|
|
172
|
-
|
|
173
|
-
if (debug) {
|
|
174
|
-
console.log({ radiance: this.radianceTexture, irradiance: this.irradianceTexture });
|
|
175
|
-
// Show both of them on cubes in the scene
|
|
176
|
-
const unlitMat = new MeshBasicMaterial();
|
|
177
|
-
const radianceMat = unlitMat.clone();
|
|
178
|
-
radianceMat.map = this.radianceTexture;
|
|
179
|
-
const radianceCube = ObjectUtils.createPrimitive("Cube", { material: radianceMat });
|
|
180
|
-
const irradianceMat = unlitMat.clone();
|
|
181
|
-
irradianceMat.map = this.irradianceTexture;
|
|
182
|
-
const irradianceCube = ObjectUtils.createPrimitive("Cube", { material: irradianceMat });
|
|
183
|
-
this.context.scene.add(radianceCube);
|
|
184
|
-
this.context.scene.add(irradianceCube);
|
|
185
|
-
radianceCube.position.set(2, 0, 0);
|
|
186
|
-
radianceCube.scale.y = 0.00001;
|
|
187
|
-
irradianceCube.position.set(-2, 0, 0);
|
|
188
|
-
irradianceCube.scale.y = 0.00001;
|
|
189
|
-
// await this.initializeLighting(defaultLightRigXml, renderer);
|
|
190
|
-
console.log("MaterialX environment initialized from Needle context", this, this.context.scene);
|
|
162
|
+
while (!context.scene.environment) {
|
|
163
|
+
await delay(5);
|
|
191
164
|
}
|
|
165
|
+
this._getTextures(context.scene.environment);
|
|
166
|
+
|
|
167
|
+
// if (debug) {
|
|
168
|
+
// console.log({ radiance: this._radianceTexture, irradiance: this._irradianceTexture });
|
|
169
|
+
// // Show both of them on cubes in the scene
|
|
170
|
+
// const unlitMat = new MeshBasicMaterial();
|
|
171
|
+
// unlitMat.side = 2;
|
|
172
|
+
// const radianceMat = unlitMat.clone();
|
|
173
|
+
// radianceMat.map = this._radianceTexture;
|
|
174
|
+
// const radianceCube = ObjectUtils.createPrimitive("Quad", { material: radianceMat });
|
|
175
|
+
// const irradianceMat = unlitMat.clone();
|
|
176
|
+
// irradianceMat.map = this._irradianceTexture;
|
|
177
|
+
// const irradianceCube = ObjectUtils.createPrimitive("Quad", { material: irradianceMat });
|
|
178
|
+
// context.scene.add(radianceCube);
|
|
179
|
+
// context.scene.add(irradianceCube);
|
|
180
|
+
// radianceCube.position.set(2, 0, 0);
|
|
181
|
+
// irradianceCube.position.set(-2, 0, 0);
|
|
182
|
+
// console.log("[MaterialX] environment initialized from Needle context", this, this._context.scene);
|
|
183
|
+
// }
|
|
184
|
+
|
|
185
|
+
this.updateLighting(true);
|
|
192
186
|
|
|
193
|
-
//
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
if ((object as Light).isLight) lights.push(object as Light);
|
|
197
|
-
});
|
|
187
|
+
// Mark as initialized
|
|
188
|
+
return true;
|
|
189
|
+
}
|
|
198
190
|
|
|
199
|
-
|
|
191
|
+
// Reset the environment to allow re-initialization
|
|
192
|
+
reset() {
|
|
193
|
+
if (debug) console.log("[MaterialX] Resetting environment");
|
|
194
|
+
this._initializePromise = null;
|
|
195
|
+
this._lights = [];
|
|
196
|
+
this._lightData = null;
|
|
197
|
+
this._lightCount = 0;
|
|
198
|
+
this._pmremGenerator?.dispose();
|
|
199
|
+
this._pmremGenerator = null;
|
|
200
|
+
for(const textureSet of this._texturesCache.values()) {
|
|
201
|
+
textureSet.radianceTexture?.dispose();
|
|
202
|
+
textureSet.irradianceTexture?.dispose();
|
|
203
|
+
}
|
|
204
|
+
this._texturesCache.clear();
|
|
200
205
|
|
|
201
|
-
|
|
202
|
-
this.
|
|
206
|
+
this._unsubscribehook?.();
|
|
207
|
+
this._unsubscribehook = null;
|
|
203
208
|
}
|
|
204
209
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
210
|
+
private _getTextures(texture: Texture | null | undefined): {
|
|
211
|
+
radianceTexture: Texture | null,
|
|
212
|
+
irradianceTexture: Texture | null
|
|
213
|
+
} {
|
|
209
214
|
|
|
210
|
-
|
|
211
|
-
|
|
215
|
+
let res: EnvironmentTextureSet | undefined = this._texturesCache.get(texture || null);
|
|
216
|
+
if (res) {
|
|
217
|
+
return res;
|
|
218
|
+
}
|
|
212
219
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
this.
|
|
218
|
-
this.
|
|
220
|
+
if (this._context && this._pmremGenerator && texture) {
|
|
221
|
+
if (debug) console.log("[MaterialX] Generating environment textures", texture.name);
|
|
222
|
+
|
|
223
|
+
const target = this._pmremGenerator.fromEquirectangular(texture);
|
|
224
|
+
const radianceRenderTarget = renderPMREMToEquirect(this._context.renderer, target.texture, 0.0, 1024, 512, target.height);
|
|
225
|
+
const irradianceRenderTarget = renderPMREMToEquirect(this._context.renderer, target.texture, 1.0, 32, 16, target.height);
|
|
226
|
+
target.dispose();
|
|
227
|
+
res = {
|
|
228
|
+
radianceTexture: radianceRenderTarget.texture,
|
|
229
|
+
irradianceTexture: irradianceRenderTarget.texture
|
|
230
|
+
}
|
|
219
231
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
232
|
+
else {
|
|
233
|
+
res = {
|
|
234
|
+
radianceTexture: null,
|
|
235
|
+
irradianceTexture: null
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
this._texturesCache.set(texture || null, res);
|
|
239
|
+
return res;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
private updateLighting = (collectLights: boolean = false) => {
|
|
243
|
+
if (!this._context) return;
|
|
244
|
+
|
|
245
|
+
// Find lights in scene
|
|
246
|
+
if (collectLights) {
|
|
247
|
+
const lights = new Array<Light>();
|
|
248
|
+
this._context.scene.traverse((object: Object3D) => {
|
|
249
|
+
if ((object as Light).isLight && GameObject.isActiveInHierarchy(object))
|
|
250
|
+
lights.push(object as Light);
|
|
251
|
+
});
|
|
252
|
+
this._lights = lights;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
if (state.materialXGenContext) {
|
|
256
|
+
const { lightData, lightCount } = getLightData(this._lights, state.materialXGenContext);
|
|
257
|
+
this._lightData = lightData;
|
|
258
|
+
this._lightCount = lightCount;
|
|
223
259
|
}
|
|
224
|
-
this.initialized = false;
|
|
225
|
-
// this.lights = [];
|
|
226
|
-
this.lightData = null;
|
|
227
260
|
}
|
|
228
261
|
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
export namespace MaterialX {
|
|
5
|
+
|
|
6
|
+
export type MODULE = {
|
|
7
|
+
ShaderInterfaceType: any;
|
|
8
|
+
HwSpecularEnvironmentMethod: any;
|
|
9
|
+
HwShaderGenerator: {
|
|
10
|
+
bindLightShader(def: any, id: number, genContext: GenContext): void;
|
|
11
|
+
unbindLightShaders(context: any): void;
|
|
12
|
+
};
|
|
13
|
+
createDocument(): Document;
|
|
14
|
+
readFromXmlString(doc: Document, xml: string, unknown: string): void;
|
|
15
|
+
loadStandardLibraries(genContext: GenContext): StandardLibrary;
|
|
16
|
+
isTransparentSurface(renderableElement: any, target: string): boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
export type GenContext = {
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export type StandardLibrary = {
|
|
24
|
+
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// https://github.com/AcademySoftwareFoundation/MaterialX/blob/b74787db6544283dc32afc8085ebc93cabe937cb/source/MaterialXGenShader/ShaderStage.h#L56
|
|
28
|
+
export type ShaderStage = {
|
|
29
|
+
getUniformBlocks(): Record<string, any>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export type Document = {
|
|
33
|
+
setDataLibrary(lib: StandardLibrary): void;
|
|
34
|
+
importLibrary(lib: Document): void;
|
|
35
|
+
|
|
36
|
+
getNodes(): Node[];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export type Node = {
|
|
40
|
+
getType(): string;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export type Matrix = {
|
|
44
|
+
numRows(): number;
|
|
45
|
+
numColumns(): number;
|
|
46
|
+
get size(): number;
|
|
47
|
+
getItem(row: number, col: number): number;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
}
|
package/src/textureHelper.ts
CHANGED
|
@@ -40,7 +40,7 @@ export function renderPMREMToEquirect(renderer: WebGLRenderer, pmremTexture: Tex
|
|
|
40
40
|
} else {
|
|
41
41
|
imageHeight = 256; // Final fallback
|
|
42
42
|
}
|
|
43
|
-
|
|
43
|
+
|
|
44
44
|
const maxMip = Math.log2(imageHeight) - 2;
|
|
45
45
|
const cubeUVHeight = imageHeight;
|
|
46
46
|
const cubeUVWidth = 3 * Math.max(Math.pow(2, maxMip), 7 * 16);
|
|
@@ -129,14 +129,14 @@ export function renderPMREMToEquirect(renderer: WebGLRenderer, pmremTexture: Tex
|
|
|
129
129
|
const currentAutoClear = renderer.autoClear;
|
|
130
130
|
const currentXrEnabled = renderer.xr.enabled;
|
|
131
131
|
const currentShadowMapEnabled = renderer.shadowMap.enabled;
|
|
132
|
-
|
|
132
|
+
|
|
133
133
|
renderTarget.texture.generateMipmaps = true;
|
|
134
|
-
|
|
134
|
+
|
|
135
135
|
try {
|
|
136
136
|
// Disable XR and shadow mapping during our render to avoid interference
|
|
137
137
|
renderer.xr.enabled = false;
|
|
138
138
|
renderer.shadowMap.enabled = false;
|
|
139
|
-
|
|
139
|
+
|
|
140
140
|
// Render to our target
|
|
141
141
|
renderer.autoClear = true;
|
|
142
142
|
renderer.setRenderTarget(renderTarget);
|
|
@@ -148,7 +148,7 @@ export function renderPMREMToEquirect(renderer: WebGLRenderer, pmremTexture: Tex
|
|
|
148
148
|
renderer.autoClear = currentAutoClear;
|
|
149
149
|
renderer.xr.enabled = currentXrEnabled;
|
|
150
150
|
renderer.shadowMap.enabled = currentShadowMapEnabled;
|
|
151
|
-
|
|
151
|
+
|
|
152
152
|
// Clean up temporary objects
|
|
153
153
|
geometry.dispose();
|
|
154
154
|
material.dispose();
|
|
@@ -159,7 +159,7 @@ export function renderPMREMToEquirect(renderer: WebGLRenderer, pmremTexture: Tex
|
|
|
159
159
|
renderTarget.texture.mapping = EquirectangularReflectionMapping;
|
|
160
160
|
|
|
161
161
|
// Log mipmap infos
|
|
162
|
-
if (debug) console.log('PMREM to Equirect Render Target:', {
|
|
162
|
+
if (debug) console.log('[MaterialX] PMREM to Equirect Render Target:', {
|
|
163
163
|
width: renderTarget.width,
|
|
164
164
|
height: renderTarget.height,
|
|
165
165
|
mipmaps: renderTarget.texture.mipmaps?.length,
|
package/src/utils.ts
CHANGED
|
@@ -2,10 +2,7 @@ import { Context, getParam } from "@needle-tools/engine";
|
|
|
2
2
|
import { Mesh } from "three";
|
|
3
3
|
|
|
4
4
|
export const debug = getParam("debugmaterialx");
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
export const debugUpdate = getParam("debugmaterialxupdate");
|
|
9
6
|
|
|
10
7
|
/**
|
|
11
8
|
* =====================================
|
|
@@ -33,6 +30,44 @@ const patchWebGL2 = () => {
|
|
|
33
30
|
}
|
|
34
31
|
return uniform4fv.call(this, location, v);
|
|
35
32
|
};
|
|
33
|
+
|
|
34
|
+
const uniform3fv = WebGL2RenderingContext.prototype.uniform3fv;
|
|
35
|
+
WebGL2RenderingContext.prototype.uniform3fv = function (location: WebGLUniformLocation | null, v: Float32Array | number[]) {
|
|
36
|
+
if (location) {
|
|
37
|
+
const uniformName = programAndNameToUniformLocation.get(location);
|
|
38
|
+
if (true) console.log("Calling uniform3fv", { location, v, name: uniformName?.name });
|
|
39
|
+
}
|
|
40
|
+
return uniform3fv.call(this, location, v);
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const uniform3iv = WebGL2RenderingContext.prototype.uniform3iv;
|
|
44
|
+
WebGL2RenderingContext.prototype.uniform3iv = function (location: WebGLUniformLocation | null, v: Int32Array | number[]) {
|
|
45
|
+
if (location) {
|
|
46
|
+
const uniformName = programAndNameToUniformLocation.get(location);
|
|
47
|
+
if (true) console.log("Calling uniform3iv", { location, v, name: uniformName?.name });
|
|
48
|
+
}
|
|
49
|
+
return uniform3iv.call(this, location, v);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const uniform3uiv = WebGL2RenderingContext.prototype.uniform3uiv;
|
|
53
|
+
WebGL2RenderingContext.prototype.uniform3uiv = function (location: WebGLUniformLocation | null, v: Uint32Array | number[]) {
|
|
54
|
+
if (location) {
|
|
55
|
+
const uniformName = programAndNameToUniformLocation.get(location);
|
|
56
|
+
if (true) console.log("Calling uniform3uiv", { location, v, name: uniformName?.name });
|
|
57
|
+
}
|
|
58
|
+
return uniform3uiv.call(this, location, v);
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const uniform3f = WebGL2RenderingContext.prototype.uniform3f;
|
|
62
|
+
WebGL2RenderingContext.prototype.uniform3f = function (location: WebGLUniformLocation
|
|
63
|
+
| null, x: number, y: number, z: number) {
|
|
64
|
+
if (location) {
|
|
65
|
+
const uniformName = programAndNameToUniformLocation.get(location);
|
|
66
|
+
if (uniformName?.name !== "diffuse")
|
|
67
|
+
if (true) console.log("Calling uniform3f", { location, x, y, z, name: uniformName?.name });
|
|
68
|
+
}
|
|
69
|
+
return uniform3f.call(this, location, x, y, z);
|
|
70
|
+
};
|
|
36
71
|
};
|
|
37
72
|
// patchWebGL2();
|
|
38
73
|
|