@needle-tools/materialx 1.0.0-alpha → 1.0.0-next.12f185d
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/README.md +1 -1
- package/codegen/register_types.ts +6 -6
- package/index.ts +4 -4
- package/package.json +27 -20
- package/package.needle.json +2 -2
- package/src/helper.js +457 -457
- package/src/index.ts +4 -4
- package/src/loader/loader.needle.ts +106 -106
- package/src/loader/loader.three.ts +555 -555
- package/src/materialx.ts +238 -220
- package/src/textureHelper.ts +169 -169
- package/src/utils.ts +57 -57
- package/tsconfig.json +20 -20
- package/.github/workflows/release.yml +0 -39
- package/bin/README.md +0 -5
- package/workspace.code-workspace +0 -18
package/src/textureHelper.ts
CHANGED
|
@@ -1,170 +1,170 @@
|
|
|
1
|
-
import { WebGLRenderer, Scene, WebGLRenderTarget, PlaneGeometry, OrthographicCamera, ShaderMaterial, RGBAFormat, FloatType, LinearFilter, Mesh, EquirectangularReflectionMapping, RepeatWrapping, LinearMipMapLinearFilter, Texture, WebGLUtils } from 'three';
|
|
2
|
-
import { getParam } from '@needle-tools/engine';
|
|
3
|
-
|
|
4
|
-
const debug = getParam("debugmaterialx");
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Renders a PMREM environment map to an equirectangular texture with specified roughness
|
|
8
|
-
* @param {WebGLRenderer} renderer - Three.js WebGL renderer
|
|
9
|
-
* @param {Texture} pmremTexture - PMREM texture (2D CubeUV layout) to convert
|
|
10
|
-
* @param {number} roughness - Roughness value (0.0 to 1.0)
|
|
11
|
-
* @param {number} width - Output texture width (default: 1024)
|
|
12
|
-
* @param {number} height - Output texture height (default: 512)
|
|
13
|
-
* @param {number} renderTargetHeight - Original render target height (optional, for proper PMREM parameter calculation)
|
|
14
|
-
* @returns {WebGLRenderTarget} Render target containing the equirectangular texture
|
|
15
|
-
* @example // Creating an equirectangular texture from a PMREM environment map at a certain roughness level:
|
|
16
|
-
* const pmremRenderTarget = pmremGenerator.fromEquirectangular(envMap);
|
|
17
|
-
* const equirectRenderTarget = await renderPMREMToEquirect(renderer, pmremRenderTarget.texture, 0.5, 2048, 1024, pmremRenderTarget.height);
|
|
18
|
-
|
|
19
|
-
// Use the rendered equirectangular texture
|
|
20
|
-
const equirectTexture = equirectRenderTarget.texture;
|
|
21
|
-
|
|
22
|
-
// Apply to your material or save/export
|
|
23
|
-
someMaterial.map = equirectTexture;
|
|
24
|
-
|
|
25
|
-
// Don't forget to dispose when done
|
|
26
|
-
// equirectRenderTarget.dispose();
|
|
27
|
-
*/
|
|
28
|
-
export function renderPMREMToEquirect(renderer: WebGLRenderer, pmremTexture: Texture, roughness = 0.0, width = 1024, height = 512, renderTargetHeight?: number) {
|
|
29
|
-
// TODO Validate inputs
|
|
30
|
-
// console.log(renderer, pmremTexture);
|
|
31
|
-
|
|
32
|
-
// Calculate PMREM parameters
|
|
33
|
-
// For PMREM CubeUV layout, we need the cube face size to calculate proper parameters
|
|
34
|
-
// Use renderTargetHeight if provided, otherwise try to derive from texture
|
|
35
|
-
let imageHeight;
|
|
36
|
-
if (renderTargetHeight) {
|
|
37
|
-
imageHeight = renderTargetHeight;
|
|
38
|
-
} else if (pmremTexture.image) {
|
|
39
|
-
imageHeight = pmremTexture.image.height / 4; // Fallback: assume CubeUV layout height / 4
|
|
40
|
-
} else {
|
|
41
|
-
imageHeight = 256; // Final fallback
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const maxMip = Math.log2(imageHeight) - 2;
|
|
45
|
-
const cubeUVHeight = imageHeight;
|
|
46
|
-
const cubeUVWidth = 3 * Math.max(Math.pow(2, maxMip), 7 * 16);
|
|
47
|
-
|
|
48
|
-
// Create render target for equirectangular output
|
|
49
|
-
const renderTarget = new WebGLRenderTarget(width, height, {
|
|
50
|
-
format: RGBAFormat,
|
|
51
|
-
type: FloatType,
|
|
52
|
-
minFilter: LinearMipMapLinearFilter,
|
|
53
|
-
magFilter: LinearFilter,
|
|
54
|
-
generateMipmaps: true,
|
|
55
|
-
wrapS: RepeatWrapping,
|
|
56
|
-
anisotropy: renderer.capabilities.getMaxAnisotropy(),
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
// Create fullscreen quad geometry and camera
|
|
60
|
-
const geometry = new PlaneGeometry(2, 2);
|
|
61
|
-
const camera = new OrthographicCamera(-1, 1, 1, -1, 0, 1);
|
|
62
|
-
|
|
63
|
-
// Create shader material for PMREM to equirectangular conversion
|
|
64
|
-
const material = new ShaderMaterial({
|
|
65
|
-
defines: {
|
|
66
|
-
USE_ENVMAP: '',
|
|
67
|
-
ENVMAP_TYPE_CUBE_UV: '',
|
|
68
|
-
CUBEUV_TEXEL_WIDTH: 1.0 / cubeUVWidth,
|
|
69
|
-
CUBEUV_TEXEL_HEIGHT: 1.0 / cubeUVHeight,
|
|
70
|
-
CUBEUV_MAX_MIP: (maxMip + 0) + '.0',
|
|
71
|
-
},
|
|
72
|
-
uniforms: {
|
|
73
|
-
envMap: { value: pmremTexture },
|
|
74
|
-
roughness: { value: roughness }
|
|
75
|
-
},
|
|
76
|
-
vertexShader: `
|
|
77
|
-
varying vec2 vUv;
|
|
78
|
-
|
|
79
|
-
void main() {
|
|
80
|
-
vUv = uv;
|
|
81
|
-
gl_Position = vec4(position.xy, 0.0, 1.0);
|
|
82
|
-
}
|
|
83
|
-
`,
|
|
84
|
-
fragmentShader: `
|
|
85
|
-
uniform sampler2D envMap;
|
|
86
|
-
uniform float roughness;
|
|
87
|
-
varying vec2 vUv;
|
|
88
|
-
|
|
89
|
-
#include <common>
|
|
90
|
-
#include <cube_uv_reflection_fragment>
|
|
91
|
-
|
|
92
|
-
void main() {
|
|
93
|
-
// Convert UV coordinates to equirectangular direction
|
|
94
|
-
vec2 uv = vUv;
|
|
95
|
-
|
|
96
|
-
// Map UV (0,1) to spherical coordinates
|
|
97
|
-
// Longitude: -π to π, Latitude: 0 to π
|
|
98
|
-
float phi = uv.x * 2.0 * PI - PI; // Longitude (-π to π)
|
|
99
|
-
float theta = uv.y * PI; // Latitude (0 to π)
|
|
100
|
-
// Rotate 90° around Y
|
|
101
|
-
phi -= PI / 2.0; // Adjust to match Three.js convention
|
|
102
|
-
|
|
103
|
-
// Convert spherical to cartesian coordinates
|
|
104
|
-
vec3 direction = vec3(
|
|
105
|
-
sin(theta) * cos(phi), // x
|
|
106
|
-
cos(theta), // y
|
|
107
|
-
sin(theta) * sin(phi) // z
|
|
108
|
-
);
|
|
109
|
-
|
|
110
|
-
// Sample the PMREM cube texture using the direction and roughness
|
|
111
|
-
#ifdef ENVMAP_TYPE_CUBE_UV
|
|
112
|
-
vec4 envColor = textureCubeUV(envMap, direction, roughness);
|
|
113
|
-
#else
|
|
114
|
-
vec4 envColor = vec4(1.0, 0.0, 1.0, 1.0); // Magenta fallback
|
|
115
|
-
#endif
|
|
116
|
-
|
|
117
|
-
gl_FragColor = vec4(envColor.rgb, 1.0);
|
|
118
|
-
}
|
|
119
|
-
`
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
// Create temporary scene and mesh for rendering
|
|
123
|
-
const tempScene = new Scene();
|
|
124
|
-
const mesh = new Mesh(geometry, material);
|
|
125
|
-
tempScene.add(mesh);
|
|
126
|
-
|
|
127
|
-
// Store current renderer state
|
|
128
|
-
const currentRenderTarget = renderer.getRenderTarget();
|
|
129
|
-
const currentAutoClear = renderer.autoClear;
|
|
130
|
-
const currentXrEnabled = renderer.xr.enabled;
|
|
131
|
-
const currentShadowMapEnabled = renderer.shadowMap.enabled;
|
|
132
|
-
|
|
133
|
-
renderTarget.texture.generateMipmaps = true;
|
|
134
|
-
|
|
135
|
-
try {
|
|
136
|
-
// Disable XR and shadow mapping during our render to avoid interference
|
|
137
|
-
renderer.xr.enabled = false;
|
|
138
|
-
renderer.shadowMap.enabled = false;
|
|
139
|
-
|
|
140
|
-
// Render to our target
|
|
141
|
-
renderer.autoClear = true;
|
|
142
|
-
renderer.setRenderTarget(renderTarget);
|
|
143
|
-
renderer.clear(); // Explicitly clear the render target
|
|
144
|
-
renderer.render(tempScene, camera);
|
|
145
|
-
} finally {
|
|
146
|
-
// Restore renderer state completely
|
|
147
|
-
renderer.setRenderTarget(currentRenderTarget);
|
|
148
|
-
renderer.autoClear = currentAutoClear;
|
|
149
|
-
renderer.xr.enabled = currentXrEnabled;
|
|
150
|
-
renderer.shadowMap.enabled = currentShadowMapEnabled;
|
|
151
|
-
|
|
152
|
-
// Clean up temporary objects
|
|
153
|
-
geometry.dispose();
|
|
154
|
-
material.dispose();
|
|
155
|
-
tempScene.remove(mesh);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
renderTarget.texture.name = 'PMREM_Equirectangular_Texture_' + roughness.toFixed(2);
|
|
159
|
-
renderTarget.texture.mapping = EquirectangularReflectionMapping;
|
|
160
|
-
|
|
161
|
-
// Log mipmap infos
|
|
162
|
-
if (debug) console.log('PMREM to Equirect Render Target:', {
|
|
163
|
-
width: renderTarget.width,
|
|
164
|
-
height: renderTarget.height,
|
|
165
|
-
mipmaps: renderTarget.texture.mipmaps?.length,
|
|
166
|
-
roughness: roughness,
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
return renderTarget;
|
|
1
|
+
import { WebGLRenderer, Scene, WebGLRenderTarget, PlaneGeometry, OrthographicCamera, ShaderMaterial, RGBAFormat, FloatType, LinearFilter, Mesh, EquirectangularReflectionMapping, RepeatWrapping, LinearMipMapLinearFilter, Texture, WebGLUtils } from 'three';
|
|
2
|
+
import { getParam } from '@needle-tools/engine';
|
|
3
|
+
|
|
4
|
+
const debug = getParam("debugmaterialx");
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Renders a PMREM environment map to an equirectangular texture with specified roughness
|
|
8
|
+
* @param {WebGLRenderer} renderer - Three.js WebGL renderer
|
|
9
|
+
* @param {Texture} pmremTexture - PMREM texture (2D CubeUV layout) to convert
|
|
10
|
+
* @param {number} roughness - Roughness value (0.0 to 1.0)
|
|
11
|
+
* @param {number} width - Output texture width (default: 1024)
|
|
12
|
+
* @param {number} height - Output texture height (default: 512)
|
|
13
|
+
* @param {number} renderTargetHeight - Original render target height (optional, for proper PMREM parameter calculation)
|
|
14
|
+
* @returns {WebGLRenderTarget} Render target containing the equirectangular texture
|
|
15
|
+
* @example // Creating an equirectangular texture from a PMREM environment map at a certain roughness level:
|
|
16
|
+
* const pmremRenderTarget = pmremGenerator.fromEquirectangular(envMap);
|
|
17
|
+
* const equirectRenderTarget = await renderPMREMToEquirect(renderer, pmremRenderTarget.texture, 0.5, 2048, 1024, pmremRenderTarget.height);
|
|
18
|
+
|
|
19
|
+
// Use the rendered equirectangular texture
|
|
20
|
+
const equirectTexture = equirectRenderTarget.texture;
|
|
21
|
+
|
|
22
|
+
// Apply to your material or save/export
|
|
23
|
+
someMaterial.map = equirectTexture;
|
|
24
|
+
|
|
25
|
+
// Don't forget to dispose when done
|
|
26
|
+
// equirectRenderTarget.dispose();
|
|
27
|
+
*/
|
|
28
|
+
export function renderPMREMToEquirect(renderer: WebGLRenderer, pmremTexture: Texture, roughness = 0.0, width = 1024, height = 512, renderTargetHeight?: number) {
|
|
29
|
+
// TODO Validate inputs
|
|
30
|
+
// console.log(renderer, pmremTexture);
|
|
31
|
+
|
|
32
|
+
// Calculate PMREM parameters
|
|
33
|
+
// For PMREM CubeUV layout, we need the cube face size to calculate proper parameters
|
|
34
|
+
// Use renderTargetHeight if provided, otherwise try to derive from texture
|
|
35
|
+
let imageHeight;
|
|
36
|
+
if (renderTargetHeight) {
|
|
37
|
+
imageHeight = renderTargetHeight;
|
|
38
|
+
} else if (pmremTexture.image) {
|
|
39
|
+
imageHeight = pmremTexture.image.height / 4; // Fallback: assume CubeUV layout height / 4
|
|
40
|
+
} else {
|
|
41
|
+
imageHeight = 256; // Final fallback
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const maxMip = Math.log2(imageHeight) - 2;
|
|
45
|
+
const cubeUVHeight = imageHeight;
|
|
46
|
+
const cubeUVWidth = 3 * Math.max(Math.pow(2, maxMip), 7 * 16);
|
|
47
|
+
|
|
48
|
+
// Create render target for equirectangular output
|
|
49
|
+
const renderTarget = new WebGLRenderTarget(width, height, {
|
|
50
|
+
format: RGBAFormat,
|
|
51
|
+
type: FloatType,
|
|
52
|
+
minFilter: LinearMipMapLinearFilter,
|
|
53
|
+
magFilter: LinearFilter,
|
|
54
|
+
generateMipmaps: true,
|
|
55
|
+
wrapS: RepeatWrapping,
|
|
56
|
+
anisotropy: renderer.capabilities.getMaxAnisotropy(),
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// Create fullscreen quad geometry and camera
|
|
60
|
+
const geometry = new PlaneGeometry(2, 2);
|
|
61
|
+
const camera = new OrthographicCamera(-1, 1, 1, -1, 0, 1);
|
|
62
|
+
|
|
63
|
+
// Create shader material for PMREM to equirectangular conversion
|
|
64
|
+
const material = new ShaderMaterial({
|
|
65
|
+
defines: {
|
|
66
|
+
USE_ENVMAP: '',
|
|
67
|
+
ENVMAP_TYPE_CUBE_UV: '',
|
|
68
|
+
CUBEUV_TEXEL_WIDTH: 1.0 / cubeUVWidth,
|
|
69
|
+
CUBEUV_TEXEL_HEIGHT: 1.0 / cubeUVHeight,
|
|
70
|
+
CUBEUV_MAX_MIP: (maxMip + 0) + '.0',
|
|
71
|
+
},
|
|
72
|
+
uniforms: {
|
|
73
|
+
envMap: { value: pmremTexture },
|
|
74
|
+
roughness: { value: roughness }
|
|
75
|
+
},
|
|
76
|
+
vertexShader: `
|
|
77
|
+
varying vec2 vUv;
|
|
78
|
+
|
|
79
|
+
void main() {
|
|
80
|
+
vUv = uv;
|
|
81
|
+
gl_Position = vec4(position.xy, 0.0, 1.0);
|
|
82
|
+
}
|
|
83
|
+
`,
|
|
84
|
+
fragmentShader: `
|
|
85
|
+
uniform sampler2D envMap;
|
|
86
|
+
uniform float roughness;
|
|
87
|
+
varying vec2 vUv;
|
|
88
|
+
|
|
89
|
+
#include <common>
|
|
90
|
+
#include <cube_uv_reflection_fragment>
|
|
91
|
+
|
|
92
|
+
void main() {
|
|
93
|
+
// Convert UV coordinates to equirectangular direction
|
|
94
|
+
vec2 uv = vUv;
|
|
95
|
+
|
|
96
|
+
// Map UV (0,1) to spherical coordinates
|
|
97
|
+
// Longitude: -π to π, Latitude: 0 to π
|
|
98
|
+
float phi = uv.x * 2.0 * PI - PI; // Longitude (-π to π)
|
|
99
|
+
float theta = uv.y * PI; // Latitude (0 to π)
|
|
100
|
+
// Rotate 90° around Y
|
|
101
|
+
phi -= PI / 2.0; // Adjust to match Three.js convention
|
|
102
|
+
|
|
103
|
+
// Convert spherical to cartesian coordinates
|
|
104
|
+
vec3 direction = vec3(
|
|
105
|
+
sin(theta) * cos(phi), // x
|
|
106
|
+
cos(theta), // y
|
|
107
|
+
sin(theta) * sin(phi) // z
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
// Sample the PMREM cube texture using the direction and roughness
|
|
111
|
+
#ifdef ENVMAP_TYPE_CUBE_UV
|
|
112
|
+
vec4 envColor = textureCubeUV(envMap, direction, roughness);
|
|
113
|
+
#else
|
|
114
|
+
vec4 envColor = vec4(1.0, 0.0, 1.0, 1.0); // Magenta fallback
|
|
115
|
+
#endif
|
|
116
|
+
|
|
117
|
+
gl_FragColor = vec4(envColor.rgb, 1.0);
|
|
118
|
+
}
|
|
119
|
+
`
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// Create temporary scene and mesh for rendering
|
|
123
|
+
const tempScene = new Scene();
|
|
124
|
+
const mesh = new Mesh(geometry, material);
|
|
125
|
+
tempScene.add(mesh);
|
|
126
|
+
|
|
127
|
+
// Store current renderer state
|
|
128
|
+
const currentRenderTarget = renderer.getRenderTarget();
|
|
129
|
+
const currentAutoClear = renderer.autoClear;
|
|
130
|
+
const currentXrEnabled = renderer.xr.enabled;
|
|
131
|
+
const currentShadowMapEnabled = renderer.shadowMap.enabled;
|
|
132
|
+
|
|
133
|
+
renderTarget.texture.generateMipmaps = true;
|
|
134
|
+
|
|
135
|
+
try {
|
|
136
|
+
// Disable XR and shadow mapping during our render to avoid interference
|
|
137
|
+
renderer.xr.enabled = false;
|
|
138
|
+
renderer.shadowMap.enabled = false;
|
|
139
|
+
|
|
140
|
+
// Render to our target
|
|
141
|
+
renderer.autoClear = true;
|
|
142
|
+
renderer.setRenderTarget(renderTarget);
|
|
143
|
+
renderer.clear(); // Explicitly clear the render target
|
|
144
|
+
renderer.render(tempScene, camera);
|
|
145
|
+
} finally {
|
|
146
|
+
// Restore renderer state completely
|
|
147
|
+
renderer.setRenderTarget(currentRenderTarget);
|
|
148
|
+
renderer.autoClear = currentAutoClear;
|
|
149
|
+
renderer.xr.enabled = currentXrEnabled;
|
|
150
|
+
renderer.shadowMap.enabled = currentShadowMapEnabled;
|
|
151
|
+
|
|
152
|
+
// Clean up temporary objects
|
|
153
|
+
geometry.dispose();
|
|
154
|
+
material.dispose();
|
|
155
|
+
tempScene.remove(mesh);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
renderTarget.texture.name = 'PMREM_Equirectangular_Texture_' + roughness.toFixed(2);
|
|
159
|
+
renderTarget.texture.mapping = EquirectangularReflectionMapping;
|
|
160
|
+
|
|
161
|
+
// Log mipmap infos
|
|
162
|
+
if (debug) console.log('PMREM to Equirect Render Target:', {
|
|
163
|
+
width: renderTarget.width,
|
|
164
|
+
height: renderTarget.height,
|
|
165
|
+
mipmaps: renderTarget.texture.mipmaps?.length,
|
|
166
|
+
roughness: roughness,
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
return renderTarget;
|
|
170
170
|
}
|
package/src/utils.ts
CHANGED
|
@@ -1,58 +1,58 @@
|
|
|
1
|
-
import { Context, getParam } from "@needle-tools/engine";
|
|
2
|
-
import { Mesh } from "three";
|
|
3
|
-
|
|
4
|
-
export const debug = getParam("debugmaterialx");
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* =====================================
|
|
12
|
-
* Unused
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
// Patch WebGL2 methods for debugging purposes
|
|
16
|
-
|
|
17
|
-
const patchWebGL2 = () => {
|
|
18
|
-
const getUniformLocation = WebGL2RenderingContext.prototype.getUniformLocation;
|
|
19
|
-
const programAndNameToUniformLocation = new WeakMap<WebGLUniformLocation, { program: WebGLProgram, name: string }>();
|
|
20
|
-
WebGL2RenderingContext.prototype.getUniformLocation = function (program: WebGLProgram, name: string) {
|
|
21
|
-
const location = getUniformLocation.call(this, program, name);
|
|
22
|
-
if (location) {
|
|
23
|
-
programAndNameToUniformLocation.set(location, { program, name });
|
|
24
|
-
}
|
|
25
|
-
return location;
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
const uniform4fv = WebGL2RenderingContext.prototype.uniform4fv;
|
|
29
|
-
WebGL2RenderingContext.prototype.uniform4fv = function (location: WebGLUniformLocation | null, v: Float32Array | number[]) {
|
|
30
|
-
if (location) {
|
|
31
|
-
const uniformName = programAndNameToUniformLocation.get(location);
|
|
32
|
-
if (true) console.log("Calling uniform4fv", { location, v, name: uniformName?.name });
|
|
33
|
-
}
|
|
34
|
-
return uniform4fv.call(this, location, v);
|
|
35
|
-
};
|
|
36
|
-
};
|
|
37
|
-
// patchWebGL2();
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
// TODO doesn't actually reset yet...
|
|
41
|
-
function resetShaders(ctx: Context) {
|
|
42
|
-
const scene = ctx.scene;
|
|
43
|
-
const gl = ctx.renderer;
|
|
44
|
-
console.log(gl.properties, gl.info)
|
|
45
|
-
scene.traverse(object => {
|
|
46
|
-
if ((object as Mesh).isMesh) {
|
|
47
|
-
const mesh = object as Mesh;
|
|
48
|
-
if (Array.isArray(mesh.material)) {
|
|
49
|
-
mesh.material.forEach(mat => gl.properties.remove(mat));
|
|
50
|
-
}
|
|
51
|
-
else {
|
|
52
|
-
gl.properties.remove(mesh.material);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
})
|
|
56
|
-
if (gl.info?.programs)
|
|
57
|
-
gl.info.programs.length = 0;
|
|
1
|
+
import { Context, getParam } from "@needle-tools/engine";
|
|
2
|
+
import { Mesh } from "three";
|
|
3
|
+
|
|
4
|
+
export const debug = getParam("debugmaterialx");
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* =====================================
|
|
12
|
+
* Unused
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
// Patch WebGL2 methods for debugging purposes
|
|
16
|
+
|
|
17
|
+
const patchWebGL2 = () => {
|
|
18
|
+
const getUniformLocation = WebGL2RenderingContext.prototype.getUniformLocation;
|
|
19
|
+
const programAndNameToUniformLocation = new WeakMap<WebGLUniformLocation, { program: WebGLProgram, name: string }>();
|
|
20
|
+
WebGL2RenderingContext.prototype.getUniformLocation = function (program: WebGLProgram, name: string) {
|
|
21
|
+
const location = getUniformLocation.call(this, program, name);
|
|
22
|
+
if (location) {
|
|
23
|
+
programAndNameToUniformLocation.set(location, { program, name });
|
|
24
|
+
}
|
|
25
|
+
return location;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const uniform4fv = WebGL2RenderingContext.prototype.uniform4fv;
|
|
29
|
+
WebGL2RenderingContext.prototype.uniform4fv = function (location: WebGLUniformLocation | null, v: Float32Array | number[]) {
|
|
30
|
+
if (location) {
|
|
31
|
+
const uniformName = programAndNameToUniformLocation.get(location);
|
|
32
|
+
if (true) console.log("Calling uniform4fv", { location, v, name: uniformName?.name });
|
|
33
|
+
}
|
|
34
|
+
return uniform4fv.call(this, location, v);
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
// patchWebGL2();
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
// TODO doesn't actually reset yet...
|
|
41
|
+
function resetShaders(ctx: Context) {
|
|
42
|
+
const scene = ctx.scene;
|
|
43
|
+
const gl = ctx.renderer;
|
|
44
|
+
console.log(gl.properties, gl.info)
|
|
45
|
+
scene.traverse(object => {
|
|
46
|
+
if ((object as Mesh).isMesh) {
|
|
47
|
+
const mesh = object as Mesh;
|
|
48
|
+
if (Array.isArray(mesh.material)) {
|
|
49
|
+
mesh.material.forEach(mat => gl.properties.remove(mat));
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
gl.properties.remove(mesh.material);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
})
|
|
56
|
+
if (gl.info?.programs)
|
|
57
|
+
gl.info.programs.length = 0;
|
|
58
58
|
}
|
package/tsconfig.json
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ESNext",
|
|
4
|
-
"useDefineForClassFields": true,
|
|
5
|
-
"module": "ESNext",
|
|
6
|
-
"lib": ["ESNext", "DOM"],
|
|
7
|
-
"moduleResolution": "Node",
|
|
8
|
-
"strict": true,
|
|
9
|
-
"sourceMap": true,
|
|
10
|
-
"resolveJsonModule": true,
|
|
11
|
-
"esModuleInterop": true,
|
|
12
|
-
"noEmit": true,
|
|
13
|
-
"noUnusedLocals": false,
|
|
14
|
-
"noUnusedParameters": true,
|
|
15
|
-
"noImplicitReturns": true,
|
|
16
|
-
"noImplicitAny": false,
|
|
17
|
-
"experimentalDecorators": true
|
|
18
|
-
},
|
|
19
|
-
"include": ["."]
|
|
20
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ESNext",
|
|
4
|
+
"useDefineForClassFields": true,
|
|
5
|
+
"module": "ESNext",
|
|
6
|
+
"lib": ["ESNext", "DOM"],
|
|
7
|
+
"moduleResolution": "Node",
|
|
8
|
+
"strict": true,
|
|
9
|
+
"sourceMap": true,
|
|
10
|
+
"resolveJsonModule": true,
|
|
11
|
+
"esModuleInterop": true,
|
|
12
|
+
"noEmit": true,
|
|
13
|
+
"noUnusedLocals": false,
|
|
14
|
+
"noUnusedParameters": true,
|
|
15
|
+
"noImplicitReturns": true,
|
|
16
|
+
"noImplicitAny": false,
|
|
17
|
+
"experimentalDecorators": true
|
|
18
|
+
},
|
|
19
|
+
"include": ["."]
|
|
20
|
+
}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
name: Release Workflow
|
|
2
|
-
on:
|
|
3
|
-
push:
|
|
4
|
-
branches:
|
|
5
|
-
- 'release/stable'
|
|
6
|
-
- 'release/next'
|
|
7
|
-
- 'release/experimental'
|
|
8
|
-
|
|
9
|
-
jobs:
|
|
10
|
-
run-release-script:
|
|
11
|
-
runs-on: ubuntu-latest
|
|
12
|
-
timeout-minutes: 5
|
|
13
|
-
defaults:
|
|
14
|
-
run:
|
|
15
|
-
working-directory: ./
|
|
16
|
-
steps:
|
|
17
|
-
- name: Checkout code
|
|
18
|
-
uses: actions/checkout@v4
|
|
19
|
-
with:
|
|
20
|
-
submodules: 'recursive' # Fetch all submodules recursively
|
|
21
|
-
token: ${{ secrets.GH_RELEASE_TOKEN }}
|
|
22
|
-
|
|
23
|
-
- name: Setup Node.js
|
|
24
|
-
uses: actions/setup-node@v4
|
|
25
|
-
with:
|
|
26
|
-
node-version: '22'
|
|
27
|
-
|
|
28
|
-
- name: Install dependencies
|
|
29
|
-
run: npm ci
|
|
30
|
-
|
|
31
|
-
- name: Publish to npm (stable branch)
|
|
32
|
-
if: startsWith(github.ref_name, 'release/stable')
|
|
33
|
-
run: npx --yes needle-publish-helper@stable publish "./dist" --webhook "${{ secrets.DISCORD_WEBHOOK }}" --access-token "${{ secrets.NPM_TOKEN }}" --tag "stable" --create-tag "release/"
|
|
34
|
-
|
|
35
|
-
- name: Publish to npm (next and experimental branches)
|
|
36
|
-
if: ${{ !startsWith(github.ref_name, 'release/stable') }}
|
|
37
|
-
run: npx --yes needle-publish-helper@stable publish "./dist" --webhook "${{ secrets.DISCORD_WEBHOOK }}" --access-token "${{ secrets.NPM_TOKEN }}" --tag "${{ github.ref_name }}" --version+tag --version+hash --create-tag "release/"
|
|
38
|
-
|
|
39
|
-
|
package/bin/README.md
DELETED
package/workspace.code-workspace
DELETED