@needle-tools/materialx 1.0.1-next.df0e959 → 1.0.2-next.81f48e0
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 +1 -1
- package/codegen/register_types.ts +2 -0
- package/package.json +1 -1
- package/src/loader/loader.needle.ts +22 -33
- package/src/loader/loader.three.ts +123 -393
- package/src/materialx.helper.ts +477 -0
- package/src/materialx.material.ts +217 -0
- package/src/materialx.ts +125 -92
- 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 -490
package/src/materialx.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import { Context, delay, isDevEnvironment, ObjectUtils, GameObject } 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, Texture } 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
11
|
export const state = new class {
|
|
10
|
-
materialXModule:
|
|
12
|
+
materialXModule: MX.MODULE | null = null;
|
|
11
13
|
materialXGenerator: any = null;
|
|
12
14
|
materialXGenContext: any = null;
|
|
13
15
|
materialXStdLib: any = null;
|
|
@@ -59,7 +61,7 @@ export async function ready(): Promise<void> {
|
|
|
59
61
|
},
|
|
60
62
|
});
|
|
61
63
|
if (debug) console.log("[MaterialX] module loaded", module);
|
|
62
|
-
state.materialXModule = module
|
|
64
|
+
state.materialXModule = module as MX.MODULE
|
|
63
65
|
|
|
64
66
|
// Initialize shader generator and context
|
|
65
67
|
state.materialXGenerator = module.EsslShaderGenerator.create();
|
|
@@ -71,7 +73,6 @@ export async function ready(): Promise<void> {
|
|
|
71
73
|
tempDoc.setDataLibrary(state.materialXStdLib);
|
|
72
74
|
|
|
73
75
|
// TODO ShaderInterfaceType.SHADER_INTERFACE_REDUCED would be better, but doesn't actually seem to be supported in the MaterialX javascript bindings
|
|
74
|
-
const options = state.materialXGenContext.getOptions();
|
|
75
76
|
state.materialXGenContext.getOptions().shaderInterfaceType = state.materialXModule.ShaderInterfaceType.SHADER_INTERFACE_COMPLETE;
|
|
76
77
|
|
|
77
78
|
// SPECULAR_ENVIRONMENT_NONE: Do not use specular environment maps.
|
|
@@ -95,9 +96,9 @@ export async function ready(): Promise<void> {
|
|
|
95
96
|
state.materialXGenContext.getOptions().hwMaxActiveLightSources = 4;
|
|
96
97
|
|
|
97
98
|
// This prewarms the shader generation context to have all light types
|
|
98
|
-
await registerLights(state.materialXModule,
|
|
99
|
+
await registerLights(state.materialXModule, state.materialXGenContext);
|
|
99
100
|
|
|
100
|
-
if (debug) console.log("[MaterialX]
|
|
101
|
+
if (debug) console.log("[MaterialX] Generator initialized successfully");
|
|
101
102
|
} catch (error) {
|
|
102
103
|
console.error("[MaterialX] Failed to load MaterialX module:", error);
|
|
103
104
|
throw error;
|
|
@@ -105,124 +106,156 @@ export async function ready(): Promise<void> {
|
|
|
105
106
|
})();
|
|
106
107
|
}
|
|
107
108
|
|
|
109
|
+
type EnvironmentTextureSet = {
|
|
110
|
+
radianceTexture: Texture | null;
|
|
111
|
+
irradianceTexture: Texture | null;
|
|
112
|
+
}
|
|
113
|
+
|
|
108
114
|
// MaterialX Environment Manager - handles lighting and environment setup
|
|
109
115
|
export class MaterialXEnvironment {
|
|
110
116
|
private _context: Context | null = null;
|
|
117
|
+
private _lights: Array<Light> = [];
|
|
111
118
|
private _lightData: any = null;
|
|
112
119
|
private _lightCount: number = 0;
|
|
113
|
-
private _radianceTexture: Texture | null = null;
|
|
114
|
-
private _irradianceTexture: Texture | null = null;
|
|
115
120
|
private _initializePromise: Promise<boolean> | null = null;
|
|
116
121
|
|
|
122
|
+
private _unsubscribehook: (() => void) | null = null;
|
|
123
|
+
|
|
117
124
|
constructor() {
|
|
118
125
|
if (debug) console.log("[MaterialX] Environment created");
|
|
119
126
|
}
|
|
120
127
|
|
|
121
128
|
// Initialize with Needle Engine context
|
|
122
|
-
async
|
|
123
|
-
|
|
124
|
-
// Prevent multiple initializations
|
|
129
|
+
async initialize(context: Context): Promise<boolean> {
|
|
125
130
|
if (this._initializePromise) {
|
|
126
|
-
if (debug) console.log("[MaterialX] environment already initialized, skipping");
|
|
127
131
|
return this._initializePromise;
|
|
128
132
|
}
|
|
129
|
-
|
|
130
133
|
return this._initializePromise = this._initialize(context);
|
|
131
134
|
}
|
|
132
135
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
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);
|
|
142
|
+
}
|
|
143
|
+
return this._getTextures(this._context?.scene.environment);
|
|
144
|
+
}
|
|
138
145
|
|
|
139
|
-
|
|
140
|
-
|
|
146
|
+
private _pmremGenerator: PMREMGenerator | null = null;
|
|
147
|
+
private readonly _texturesCache: Map<Texture | null, EnvironmentTextureSet> = new Map();
|
|
148
|
+
|
|
149
|
+
private _initialize: (context: Context) => Promise<boolean> = async (context: Context) => {
|
|
150
|
+
|
|
151
|
+
this._context = context;
|
|
152
|
+
this._pmremGenerator = new PMREMGenerator(context.renderer);
|
|
153
|
+
|
|
154
|
+
this._unsubscribehook?.();
|
|
155
|
+
this._unsubscribehook = onBeforeRender(() => {
|
|
156
|
+
this.updateLighting(false);
|
|
157
|
+
this._getTextures(context.scene.environment);
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
// TODO remove this delay; we should wait for the scene lighting to be ready
|
|
161
|
+
// and then update the uniforms
|
|
162
|
+
while (!context.scene.environment) {
|
|
163
|
+
await delay(5);
|
|
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);
|
|
186
|
+
|
|
187
|
+
// Mark as initialized
|
|
188
|
+
return true;
|
|
189
|
+
}
|
|
141
190
|
|
|
142
191
|
// Reset the environment to allow re-initialization
|
|
143
192
|
reset() {
|
|
144
193
|
if (debug) console.log("[MaterialX] Resetting environment");
|
|
145
|
-
if (this._radianceTexture) {
|
|
146
|
-
this._radianceTexture.dispose();
|
|
147
|
-
this._radianceTexture = null;
|
|
148
|
-
}
|
|
149
|
-
if (this._irradianceTexture) {
|
|
150
|
-
this._irradianceTexture.dispose();
|
|
151
|
-
this._irradianceTexture = null;
|
|
152
|
-
}
|
|
153
194
|
this._initializePromise = null;
|
|
154
|
-
|
|
195
|
+
this._lights = [];
|
|
155
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();
|
|
205
|
+
|
|
206
|
+
this._unsubscribehook?.();
|
|
207
|
+
this._unsubscribehook = null;
|
|
156
208
|
}
|
|
157
209
|
|
|
158
|
-
private
|
|
210
|
+
private _getTextures(texture: Texture | null | undefined): {
|
|
211
|
+
radianceTexture: Texture | null,
|
|
212
|
+
irradianceTexture: Texture | null
|
|
213
|
+
} {
|
|
159
214
|
|
|
160
|
-
this.
|
|
215
|
+
let res: EnvironmentTextureSet | undefined = this._texturesCache.get(texture || null);
|
|
216
|
+
if (res) {
|
|
217
|
+
return res;
|
|
218
|
+
}
|
|
161
219
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
this.
|
|
166
|
-
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
|
+
}
|
|
167
231
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
232
|
+
else {
|
|
233
|
+
res = {
|
|
234
|
+
radianceTexture: null,
|
|
235
|
+
irradianceTexture: null
|
|
236
|
+
}
|
|
172
237
|
}
|
|
238
|
+
this._texturesCache.set(texture || null, res);
|
|
239
|
+
return res;
|
|
240
|
+
}
|
|
173
241
|
|
|
174
|
-
|
|
175
|
-
|
|
242
|
+
private updateLighting = (collectLights: boolean = false) => {
|
|
243
|
+
if (!this._context) return;
|
|
176
244
|
|
|
177
|
-
//
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
const target = pmrem.fromEquirectangular(envMap);
|
|
186
|
-
|
|
187
|
-
const radianceRenderTarget = renderPMREMToEquirect(renderer, target.texture, 0.0, 1024, 512, target.height);
|
|
188
|
-
const irradianceRenderTarget = renderPMREMToEquirect(renderer, target.texture, 1.0, 32, 16, target.height);
|
|
189
|
-
|
|
190
|
-
this._radianceTexture = radianceRenderTarget.texture;
|
|
191
|
-
this._irradianceTexture = irradianceRenderTarget.texture;
|
|
192
|
-
|
|
193
|
-
// Clean up PMREM generator and its render target
|
|
194
|
-
target.dispose();
|
|
195
|
-
pmrem.dispose();
|
|
196
|
-
|
|
197
|
-
if (debug) {
|
|
198
|
-
console.log({ radiance: this._radianceTexture, irradiance: this._irradianceTexture });
|
|
199
|
-
// Show both of them on cubes in the scene
|
|
200
|
-
const unlitMat = new MeshBasicMaterial();
|
|
201
|
-
unlitMat.side = 2;
|
|
202
|
-
const radianceMat = unlitMat.clone();
|
|
203
|
-
radianceMat.map = this._radianceTexture;
|
|
204
|
-
const radianceCube = ObjectUtils.createPrimitive("Quad", { material: radianceMat });
|
|
205
|
-
const irradianceMat = unlitMat.clone();
|
|
206
|
-
irradianceMat.map = this._irradianceTexture;
|
|
207
|
-
const irradianceCube = ObjectUtils.createPrimitive("Quad", { material: irradianceMat });
|
|
208
|
-
this._context.scene.add(radianceCube);
|
|
209
|
-
this._context.scene.add(irradianceCube);
|
|
210
|
-
radianceCube.position.set(2, 0, 0);
|
|
211
|
-
irradianceCube.position.set(-2, 0, 0);
|
|
212
|
-
// await this.initializeLighting(defaultLightRigXml, renderer);
|
|
213
|
-
console.log("[MaterialX] environment initialized from Needle context", this, this._context.scene);
|
|
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;
|
|
214
253
|
}
|
|
215
254
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
});
|
|
222
|
-
|
|
223
|
-
const { lightData, lightCount } = await registerLights(state.materialXModule, lights, state.materialXGenContext);
|
|
224
|
-
this._lightData = lightData;
|
|
225
|
-
this._lightCount = lightCount;
|
|
226
|
-
return true;
|
|
255
|
+
if (state.materialXGenContext) {
|
|
256
|
+
const { lightData, lightCount } = getLightData(this._lights, state.materialXGenContext);
|
|
257
|
+
this._lightData = lightData;
|
|
258
|
+
this._lightCount = lightCount;
|
|
259
|
+
}
|
|
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
|
|