@needle-tools/materialx 1.1.0 → 1.1.1
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/package.json +1 -1
- package/src/loader/loader.three.ts +6 -3
- package/src/materialx.helper.ts +48 -3
- package/src/materialx.material.ts +21 -10
package/package.json
CHANGED
|
@@ -239,13 +239,16 @@ export class MaterialXLoader implements GLTFLoaderPlugin {
|
|
|
239
239
|
const elementName = (renderableElement as any).getNamePath ? (renderableElement as any).getNamePath() : (renderableElement as any).getName();
|
|
240
240
|
|
|
241
241
|
const shader = state.materialXGenerator.generate(elementName, renderableElement, state.materialXGenContext);
|
|
242
|
+
|
|
242
243
|
const shaderMaterial = new MaterialXMaterial({
|
|
243
244
|
name: material_extension.name,
|
|
244
245
|
shader,
|
|
245
|
-
transparent: isTransparent,
|
|
246
|
-
side: material_def.doubleSided ? DoubleSide : FrontSide,
|
|
247
246
|
context: this.context,
|
|
248
|
-
|
|
247
|
+
parameters: {
|
|
248
|
+
transparent: isTransparent,
|
|
249
|
+
side: material_def.doubleSided ? DoubleSide : FrontSide,
|
|
250
|
+
...this.options.parameters,
|
|
251
|
+
},
|
|
249
252
|
loaders: {
|
|
250
253
|
cacheKey: this.options.cacheKey || "",
|
|
251
254
|
getTexture: async url => {
|
package/src/materialx.helper.ts
CHANGED
|
@@ -466,12 +466,57 @@ export function getUniformValues(shaderStage: MaterialX.ShaderStage, loaders: Lo
|
|
|
466
466
|
for (let i = 0; i < uniforms.size(); ++i) {
|
|
467
467
|
const variable = uniforms.get(i);
|
|
468
468
|
const value = variable.getValue()?.getData();
|
|
469
|
-
const
|
|
470
|
-
|
|
471
|
-
|
|
469
|
+
const uniformName = variable.getVariable();
|
|
470
|
+
const type = variable.getType().getName();
|
|
471
|
+
if (debug) console.log("Adding uniform", { path: variable.getPath(), name: uniformName, value: value, type: type });
|
|
472
|
+
threeUniforms[uniformName] = toThreeUniform(uniforms, type, value, uniformName, loaders, searchPath);
|
|
472
473
|
}
|
|
473
474
|
}
|
|
474
475
|
}
|
|
475
476
|
|
|
476
477
|
return threeUniforms;
|
|
477
478
|
}
|
|
479
|
+
|
|
480
|
+
export function generateMaterialPropertiesForUniforms(material: THREE.ShaderMaterial, shaderStage: MaterialX.ShaderStage) {
|
|
481
|
+
|
|
482
|
+
const uniformBlocks = shaderStage.getUniformBlocks()
|
|
483
|
+
for (const [blockName, uniforms] of Object.entries(uniformBlocks)) {
|
|
484
|
+
// Seems struct uniforms (like in LightData) end up here as well, we should filter those out.
|
|
485
|
+
if (blockName === "LightData") continue;
|
|
486
|
+
|
|
487
|
+
if (!uniforms.empty()) {
|
|
488
|
+
for (let i = 0; i < uniforms.size(); ++i) {
|
|
489
|
+
const variable = uniforms.get(i);
|
|
490
|
+
const uniformName = variable.getVariable();
|
|
491
|
+
let key = variable.getPath().split('/').pop();
|
|
492
|
+
switch (key) {
|
|
493
|
+
case "_Color":
|
|
494
|
+
key = "color";
|
|
495
|
+
break;
|
|
496
|
+
case "_Roughness":
|
|
497
|
+
key = "roughness";
|
|
498
|
+
break;
|
|
499
|
+
case "_Metallic":
|
|
500
|
+
key = "metalness";
|
|
501
|
+
break;
|
|
502
|
+
}
|
|
503
|
+
if (key) {
|
|
504
|
+
Object.defineProperty(material, key, {
|
|
505
|
+
get: function () {
|
|
506
|
+
return this.uniforms?.[uniformName].value
|
|
507
|
+
},
|
|
508
|
+
set: function (v) {
|
|
509
|
+
const uniforms = this.uniforms;
|
|
510
|
+
if (!uniforms || !uniforms[uniformName]) {
|
|
511
|
+
console.warn(`[MaterialX] Uniform ${uniformName} not found in ${this.name} uniforms`);
|
|
512
|
+
return;
|
|
513
|
+
}
|
|
514
|
+
this.uniforms[uniformName].value = v;
|
|
515
|
+
this.uniformsNeedUpdate = true;
|
|
516
|
+
}
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { BufferGeometry, Camera, FrontSide, GLSL3, Group, IUniform, MaterialParameters, Matrix3, Matrix4, Object3D, Scene, ShaderMaterial, Texture, Vector3, WebGLRenderer } from "three";
|
|
2
2
|
import { debug, getFrame, getTime } from "./utils.js";
|
|
3
3
|
import { MaterialXContext, MaterialXEnvironment } from "./materialx.js";
|
|
4
|
-
import { getUniformValues, Loaders } from "./materialx.helper.js";
|
|
4
|
+
import { generateMaterialPropertiesForUniforms, getUniformValues, Loaders } from "./materialx.helper.js";
|
|
5
|
+
import { cloneUniforms, cloneUniformsGroups } from "three/src/renderers/shaders/UniformsUtils.js";
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
// Add helper matrices for uniform updates (similar to MaterialX example)
|
|
@@ -14,9 +15,7 @@ declare type MaterialXMaterialInitParameters = {
|
|
|
14
15
|
loaders: Loaders,
|
|
15
16
|
context: MaterialXContext,
|
|
16
17
|
// Optional parameters
|
|
17
|
-
|
|
18
|
-
side?: MaterialParameters['side'],
|
|
19
|
-
precision?: MaterialParameters['precision'],
|
|
18
|
+
parameters?: MaterialParameters,
|
|
20
19
|
}
|
|
21
20
|
|
|
22
21
|
type Uniforms = Record<string, IUniform & { needsUpdate?: boolean }>;
|
|
@@ -27,10 +26,19 @@ export class MaterialXMaterial extends ShaderMaterial {
|
|
|
27
26
|
copy(source: MaterialXMaterial): this {
|
|
28
27
|
super.copy(source);
|
|
29
28
|
this._context = source._context;
|
|
29
|
+
this._shader = source._shader;
|
|
30
|
+
this.uniforms = cloneUniforms(source.uniforms) as Uniforms;
|
|
31
|
+
this.uniformsGroups = cloneUniformsGroups(source.uniformsGroups);
|
|
32
|
+
this.envMapIntensity = source.envMapIntensity;
|
|
33
|
+
this.envMap = source.envMap;
|
|
34
|
+
generateMaterialPropertiesForUniforms(this, this._shader.getStage('pixel'));
|
|
35
|
+
generateMaterialPropertiesForUniforms(this, this._shader.getStage('vertex'));
|
|
36
|
+
this.needsUpdate = true;
|
|
30
37
|
return this;
|
|
31
38
|
}
|
|
32
39
|
|
|
33
40
|
private _context: MaterialXContext | null = null;
|
|
41
|
+
private _shader: any;
|
|
34
42
|
|
|
35
43
|
constructor(init?: MaterialXMaterialInitParameters) {
|
|
36
44
|
|
|
@@ -63,7 +71,7 @@ export class MaterialXMaterial extends ShaderMaterial {
|
|
|
63
71
|
vertexShader = vertexShader.replace(/\bi_color_0\b/g, 'color');
|
|
64
72
|
|
|
65
73
|
// Patch fragmentShader
|
|
66
|
-
const precision = init.precision || "highp" as Precision;
|
|
74
|
+
const precision = init.parameters?.precision || "highp" as Precision;
|
|
67
75
|
fragmentShader = fragmentShader.replace(/precision mediump float;/g, `precision ${precision} float;`);
|
|
68
76
|
fragmentShader = fragmentShader.replace(/#define M_FLOAT_EPS 1e-8/g, precision === "highp" ? `#define M_FLOAT_EPS 1e-8` : `#define M_FLOAT_EPS 1e-3`);
|
|
69
77
|
|
|
@@ -124,19 +132,20 @@ export class MaterialXMaterial extends ShaderMaterial {
|
|
|
124
132
|
if (hasColor) defines['USE_COLOR'] = '';
|
|
125
133
|
|
|
126
134
|
const searchPath = ""; // Could be derived from the asset path if needed
|
|
127
|
-
const isTransparent = init.transparent ?? false;
|
|
135
|
+
const isTransparent = init.parameters?.transparent ?? false;
|
|
128
136
|
super({
|
|
129
137
|
name: init.name,
|
|
130
138
|
uniforms: {},
|
|
131
139
|
vertexShader: vertexShader,
|
|
132
140
|
fragmentShader: fragmentShader,
|
|
133
141
|
glslVersion: GLSL3,
|
|
134
|
-
transparent: isTransparent,
|
|
135
|
-
side: init.side ? init.side : FrontSide,
|
|
136
142
|
depthTest: true,
|
|
137
143
|
depthWrite: !isTransparent,
|
|
138
144
|
defines: defines,
|
|
145
|
+
...init.parameters, // Spread any additional parameters passed to the material
|
|
139
146
|
});
|
|
147
|
+
this._context = init.context;
|
|
148
|
+
this._shader = init.shader;
|
|
140
149
|
|
|
141
150
|
Object.assign(this.uniforms, {
|
|
142
151
|
...getUniformValues(init.shader.getStage('vertex'), init.loaders, searchPath),
|
|
@@ -158,7 +167,9 @@ export class MaterialXMaterial extends ShaderMaterial {
|
|
|
158
167
|
u_lightData: { value: [], needsUpdate: false }, // Array of light data. We need to set needsUpdate to false until we actually update it
|
|
159
168
|
});
|
|
160
169
|
|
|
161
|
-
this
|
|
170
|
+
generateMaterialPropertiesForUniforms(this, init.shader.getStage('pixel'));
|
|
171
|
+
generateMaterialPropertiesForUniforms(this, init.shader.getStage('vertex'));
|
|
172
|
+
|
|
162
173
|
|
|
163
174
|
if (debug) {
|
|
164
175
|
// Get lighting and environment data from MaterialX environment
|
|
@@ -216,7 +227,7 @@ export class MaterialXMaterial extends ShaderMaterial {
|
|
|
216
227
|
if (frame === undefined) frame = getFrame();
|
|
217
228
|
uniforms.u_frame.value = frame;
|
|
218
229
|
}
|
|
219
|
-
|
|
230
|
+
|
|
220
231
|
// Update light uniforms
|
|
221
232
|
this.updateEnvironmentUniforms(environment);
|
|
222
233
|
|