@needle-tools/materialx 1.0.1-next.b9467c8 → 1.0.1-next.b9638d9

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.
@@ -1,227 +0,0 @@
1
- import { Camera, DoubleSide, FrontSide, GLSL3, Matrix3, Matrix4, Mesh, Object3D, ShaderMaterial, Texture, Vector3 } from "three";
2
- import { debug } from "./utils.js";
3
- import { MaterialXEnvironment, state } from "./materialx.js";
4
- import { getUniformValues, Loaders } from "./materialx.helper.js";
5
- import { Context } from "@needle-tools/engine";
6
-
7
-
8
- // Add helper matrices for uniform updates (similar to MaterialX example)
9
- const identityMatrix = new Matrix4();
10
- const normalMat = new Matrix3();
11
- const viewProjMat = new Matrix4();
12
- const worldViewPos = new Vector3();
13
-
14
- declare type MaterialXMaterialInitParameters = {
15
- name: string,
16
- shader: any,
17
- loaders: Loaders,
18
- transparent?: boolean,
19
- }
20
-
21
- export class MaterialXMaterial extends ShaderMaterial {
22
-
23
- // copy(source: MaterialXMaterial): this {
24
- // super.copy(source);
25
- // this.name = source.name;
26
- // this.uniforms = { ...source.uniforms }; // Shallow copy of uniforms
27
- // this.envMapIntensity = source.envMapIntensity;
28
- // this.envMap = source.envMap;
29
- // this.updateUniforms = source.updateUniforms; // Copy the update function
30
- // return this;
31
- // }
32
-
33
- constructor(init?: MaterialXMaterialInitParameters) {
34
-
35
- // TODO: we need to properly copy the uniforms and other properties from the source material
36
- if (!init) {
37
- super();
38
- return;
39
- }
40
-
41
- // Get vertex and fragment shader source, and remove #version directive for newer js.
42
- // It's added by three.js glslVersion.
43
- let vertexShader = init.shader.getSourceCode("vertex");
44
- let fragmentShader = init.shader.getSourceCode("pixel");
45
-
46
- vertexShader = vertexShader.replace(/^#version.*$/gm, '').trim();
47
- fragmentShader = fragmentShader.replace(/^#version.*$/gm, '').trim();
48
-
49
- // MaterialX uses different attribute names than js defaults,
50
- // so we patch the MaterialX shaders to match the js standard names.
51
- // Otherwise, we'd have to modify the mesh attributes (see original MaterialX for reference).
52
-
53
- // Patch vertexShader
54
- vertexShader = vertexShader.replace(/\bi_position\b/g, 'position');
55
- vertexShader = vertexShader.replace(/\bi_normal\b/g, 'normal');
56
- vertexShader = vertexShader.replace(/\bi_texcoord_0\b/g, 'uv');
57
- vertexShader = vertexShader.replace(/\bi_texcoord_1\b/g, 'uv1');
58
- vertexShader = vertexShader.replace(/\bi_tangent\b/g, 'tangent');
59
- vertexShader = vertexShader.replace(/\bi_color_0\b/g, 'color');
60
-
61
- // Patch fragmentShader
62
- fragmentShader = fragmentShader.replace(/\bi_position\b/g, 'position');
63
- fragmentShader = fragmentShader.replace(/\bi_normal\b/g, 'normal');
64
- fragmentShader = fragmentShader.replace(/\bi_texcoord_0\b/g, 'uv');
65
- fragmentShader = fragmentShader.replace(/\bi_texcoord_1\b/g, 'uv1');
66
- fragmentShader = fragmentShader.replace(/\bi_tangent\b/g, 'tangent');
67
- fragmentShader = fragmentShader.replace(/\bi_color_0\b/g, 'color');
68
-
69
- // Remove `in vec3 position;` and so on since they're already declared by ShaderMaterial
70
- vertexShader = vertexShader.replace(/in\s+vec3\s+position;/g, '');
71
- vertexShader = vertexShader.replace(/in\s+vec3\s+normal;/g, '');
72
- vertexShader = vertexShader.replace(/in\s+vec3\s+uv;/g, '');
73
- vertexShader = vertexShader.replace(/in\s+vec3\s+uv1;/g, '');
74
- vertexShader = vertexShader.replace(/in\s+vec4\s+tangent;/g, '');
75
- vertexShader = vertexShader.replace(/in\s+vec4\s+color;/g, '');
76
-
77
- // Patch uv 2-component to 3-component (`texcoord_0 = uv;` needs to be replaced with `texcoord_0 = vec3(uv, 0.0);`)
78
- // TODO what if we actually have a 3-component UV? Not sure what three.js does then
79
- vertexShader = vertexShader.replace(/texcoord_0 = uv;/g, 'texcoord_0 = vec3(uv, 0.0);');
80
-
81
- // Patch units – seems MaterialX uses different units and we end up with wrong light values?
82
- // result.direction = light.position - position;
83
- fragmentShader = fragmentShader.replace(
84
- /result\.direction\s*=\s*light\.position\s*-\s*position;/g,
85
- 'result.direction = (light.position - position) * 10.0 / 1.0;');
86
-
87
- // Add tonemapping and colorspace handling
88
- // Replace `out vec4 out1;` with `out vec4 gl_FragColor;`
89
- fragmentShader = fragmentShader.replace(
90
- /out\s+vec4\s+out1;/,
91
- 'layout(location = 0) out vec4 pc_fragColor;\n#define gl_FragColor pc_fragColor');
92
-
93
- // Replace `out1 = vec4(<CAPTURE>)` with `gl_FragColor = vec4(<CAPTURE>)` and tonemapping/colorspace handling
94
- fragmentShader = fragmentShader.replace(/^\s*out1\s*=\s*vec4\((.*)\);/gm, `
95
- gl_FragColor = vec4($1);
96
- #include <tonemapping_fragment>
97
- #include <colorspace_fragment>`);
98
-
99
- const searchPath = ""; // Could be derived from the asset path if needed
100
- const flipV = false; // Set based on your geometry requirements
101
- const isTransparent = init.transparent ?? false;
102
- super({
103
- name: init.name,
104
- uniforms: {
105
- ...getUniformValues(init.shader.getStage('vertex'), init.loaders, searchPath, flipV),
106
- ...getUniformValues(init.shader.getStage('pixel'), init.loaders, searchPath, flipV),
107
- },
108
- vertexShader: vertexShader,
109
- fragmentShader: fragmentShader,
110
- glslVersion: GLSL3,
111
- transparent: isTransparent,
112
- side: FrontSide,
113
- depthTest: true,
114
- depthWrite: !isTransparent,
115
- });
116
-
117
-
118
-
119
- Object.assign(this.uniforms, {
120
- u_envMatrix: { value: new Matrix4() },
121
- u_envRadiance: { value: null, type: 't' },
122
- u_envRadianceMips: { value: 8, type: 'i' },
123
- // TODO we need to figure out how we can set a PMREM here... doing many texture samples is prohibitively expensive
124
- u_envRadianceSamples: { value: 8, type: 'i' },
125
- u_envIrradiance: { value: null, type: 't' },
126
- u_refractionEnv: { value: true },
127
- u_numActiveLightSources: { value: 0 },
128
- u_lightData: { value: [] }, // Array of light data
129
- });
130
-
131
- if (debug) {
132
- // Get lighting and environment data from MaterialX environment
133
- console.group("[MaterialX]: ", name);
134
- console.log("Vertex shader length:", vertexShader.length, vertexShader);
135
- console.log("Fragment shader length:", fragmentShader.length, fragmentShader);
136
- console.groupEnd();
137
- }
138
-
139
- }
140
-
141
-
142
- envMapIntensity: number = 1.0; // Default intensity for environment map
143
- envMap: Texture | null = null; // Environment map texture, can be set externally
144
- updateUniforms = (context: Context, environment: MaterialXEnvironment, object: Object3D, camera: Camera) => {
145
-
146
- const uniforms = this.uniforms;
147
-
148
- if (!uniforms) return;
149
-
150
- // TODO remove. Not sure why this is needed, but without it
151
- // we currently get some "swimming" where matrices are not up to date.
152
- camera.updateMatrixWorld(true);
153
-
154
- // Update standard transformation matrices
155
- if (uniforms.u_worldMatrix) {
156
- if (!uniforms.u_worldMatrix.value?.isMatrix4) uniforms.u_worldMatrix.value = new Matrix4();
157
- uniforms.u_worldMatrix.value = object.matrixWorld;
158
- }
159
-
160
- if (uniforms.u_viewProjectionMatrix) {
161
- if (!uniforms.u_viewProjectionMatrix.value?.isMatrix4) uniforms.u_viewProjectionMatrix.value = new Matrix4();
162
- uniforms.u_viewProjectionMatrix.value.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
163
- }
164
-
165
- if (uniforms.u_viewPosition) {
166
- if (!uniforms.u_viewPosition.value?.isVector3) uniforms.u_viewPosition.value = new Vector3();
167
- uniforms.u_viewPosition.value.copy(camera.getWorldPosition(worldViewPos));
168
- }
169
-
170
- if (uniforms.u_worldInverseTransposeMatrix) {
171
- if (!uniforms.u_worldInverseTransposeMatrix.value?.isMatrix4) uniforms.u_worldInverseTransposeMatrix.value = new Matrix4();
172
- uniforms.u_worldInverseTransposeMatrix.value.setFromMatrix3(normalMat.getNormalMatrix(object.matrixWorld));
173
- }
174
-
175
- // Update time uniforms
176
- if (uniforms.u_time) {
177
- uniforms.u_time.value = context.time.time;
178
- }
179
- if (uniforms.u_frame) {
180
- uniforms.u_frame.value = context.time.frame;
181
- }
182
-
183
- // Update light uniforms
184
- this.updateEnvironmentUniforms(environment);
185
-
186
- this.uniformsNeedUpdate = true;
187
- }
188
-
189
- private updateEnvironmentUniforms = (environment: MaterialXEnvironment) => {
190
-
191
- // Get lighting data from environment
192
- const lightData = environment.lightData || null;
193
- const lightCount = environment.lightCount || 0;
194
- const textures = environment.getTextures(this) || null;
195
-
196
- // Update each generated material's lighting uniforms
197
- if (!this.uniforms) return;
198
-
199
- // Update light count
200
- if (this.uniforms.u_numActiveLightSources && lightCount >= 0) {
201
- this.uniforms.u_numActiveLightSources.value = lightCount;
202
- }
203
-
204
- // Update light data if we have lights
205
- if (lightData) {
206
- this.uniforms.u_lightData.value = lightData;
207
- if (debug) console.log("[MaterialX] Updated light data for material", this.name, lightData, this.uniforms,);
208
- }
209
- else if (debug) console.warn("[MaterialX] No light data available to update uniforms for material", this.name);
210
-
211
- // Update environment uniforms
212
- if (this.uniforms.u_envMatrix) {
213
- this.uniforms.u_envMatrix.value = identityMatrix;
214
- }
215
- if (this.uniforms.u_envRadiance) {
216
- this.uniforms.u_envRadiance.value = textures.radianceTexture || null;
217
- }
218
- if (this.uniforms.u_envRadianceMips) {
219
- this.uniforms.u_envRadianceMips.value = Math.trunc(Math.log2(Math.max(textures.radianceTexture?.source.data.width ?? 0, textures.radianceTexture?.source.data.height ?? 0))) + 1;
220
- }
221
- if (this.uniforms.u_envIrradiance) {
222
- this.uniforms.u_envIrradiance.value = textures.irradianceTexture;
223
- }
224
-
225
- this.uniformsNeedUpdate = true;
226
- }
227
- }
@@ -1,50 +0,0 @@
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
- }