@needle-tools/engine 4.13.1-next.9fc3e64 → 4.14.0-next.31f837e

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.
Files changed (52) hide show
  1. package/dist/generateMeshBVH.worker-DFcS3P04.js +21 -0
  2. package/dist/{gltf-progressive-Dbi_Tfhb.js → gltf-progressive-8voIgNp_.js} +4 -4
  3. package/dist/{gltf-progressive-CaUGGjVL.umd.cjs → gltf-progressive-BRRBj-nY.umd.cjs} +1 -1
  4. package/dist/{gltf-progressive-DuAR0MQR.min.js → gltf-progressive-Dkh3tG4-.min.js} +1 -1
  5. package/dist/loader.worker-C6cXDgR1.js +23 -0
  6. package/dist/{materialx-BF23AVE8.umd.cjs → materialx-CxlgposR.umd.cjs} +1 -1
  7. package/dist/{materialx-fkoFuRh3.js → materialx-D66rYPqe.js} +2 -2
  8. package/dist/{materialx-B9ddsHcF.min.js → materialx-Dx8st96L.min.js} +1 -1
  9. package/dist/{needle-engine.bundle-Dqrh7aWw.umd.cjs → needle-engine.bundle-BQXG5qbQ.umd.cjs} +136 -143
  10. package/dist/{needle-engine.bundle-BZRE5G6O.js → needle-engine.bundle-Byl5i6zJ.js} +6120 -5904
  11. package/dist/{needle-engine.bundle-DwybonUg.min.js → needle-engine.bundle-D7w0XD7M.min.js} +147 -154
  12. package/dist/needle-engine.d.ts +61 -9
  13. package/dist/needle-engine.js +416 -415
  14. package/dist/needle-engine.min.js +1 -1
  15. package/dist/needle-engine.umd.cjs +1 -1
  16. package/dist/{postprocessing-DdM-tz1j.js → postprocessing-BkSpxpYB.js} +2 -2
  17. package/dist/{postprocessing-BVNrgYZK.min.js → postprocessing-Ce5-UWiA.min.js} +1 -1
  18. package/dist/{postprocessing-CI2TjWpu.umd.cjs → postprocessing-DFVElmAh.umd.cjs} +1 -1
  19. package/dist/{three-BW2s1Yl-.umd.cjs → three-Bad8p1pf.umd.cjs} +46 -46
  20. package/dist/{three-I__hSXzr.min.js → three-CWn13_u1.min.js} +33 -33
  21. package/dist/{three-VvRoMeIN.js → three-DFV1-P9z.js} +4209 -4209
  22. package/dist/{three-examples-BhfOE7NG.js → three-examples-43yqn3mL.js} +1 -1
  23. package/dist/{three-examples-Bpfu6ke_.umd.cjs → three-examples-CO-tx3Sp.umd.cjs} +1 -1
  24. package/dist/{three-examples-D8zAE_7t.min.js → three-examples-DKuJVGT4.min.js} +1 -1
  25. package/dist/{three-mesh-ui-BU55xDxJ.umd.cjs → three-mesh-ui-ChzVOraf.umd.cjs} +1 -1
  26. package/dist/{three-mesh-ui-C3QbemOV.min.js → three-mesh-ui-DyEA5HQF.min.js} +1 -1
  27. package/dist/{three-mesh-ui-CcMp-FQm.js → three-mesh-ui-fSAQJxdI.js} +1 -1
  28. package/dist/{vendor-COVQl0b8.umd.cjs → vendor-B51YffMU.umd.cjs} +1 -1
  29. package/dist/{vendor-BiyIZ61v.js → vendor-CgpZ5ivC.js} +1 -1
  30. package/dist/{vendor-DW7zqjuT.min.js → vendor-pe19S9r5.min.js} +1 -1
  31. package/lib/engine/api.d.ts +1 -0
  32. package/lib/engine/api.js +1 -0
  33. package/lib/engine/api.js.map +1 -1
  34. package/lib/engine/engine_lightdata.js +8 -6
  35. package/lib/engine/engine_lightdata.js.map +1 -1
  36. package/lib/engine/engine_materialpropertyblock.d.ts +47 -0
  37. package/lib/engine/engine_materialpropertyblock.js +412 -0
  38. package/lib/engine/engine_materialpropertyblock.js.map +1 -0
  39. package/lib/engine-components/ReflectionProbe.d.ts +0 -1
  40. package/lib/engine-components/ReflectionProbe.js +15 -76
  41. package/lib/engine-components/ReflectionProbe.js.map +1 -1
  42. package/lib/engine-components/RendererLightmap.d.ts +13 -9
  43. package/lib/engine-components/RendererLightmap.js +68 -81
  44. package/lib/engine-components/RendererLightmap.js.map +1 -1
  45. package/package.json +2 -2
  46. package/src/engine/api.ts +1 -0
  47. package/src/engine/engine_lightdata.ts +8 -6
  48. package/src/engine/engine_materialpropertyblock.ts +500 -0
  49. package/src/engine-components/ReflectionProbe.ts +17 -89
  50. package/src/engine-components/RendererLightmap.ts +76 -87
  51. package/dist/generateMeshBVH.worker-iyfPIK6R.js +0 -21
  52. package/dist/loader.worker-C1GG9A7C.js +0 -23
@@ -1,22 +1,19 @@
1
1
  import { NEEDLE_progressive } from "@needle-tools/gltf-progressive";
2
- import { Group, Material, Mesh, MeshPhysicalMaterial, Object3D, ShaderMaterial, Texture, Vector4, WebGLProgramParametersWithUniforms } from "three";
2
+ import { Group, Mesh, Object3D, ShaderMaterial, Texture, Vector2, Vector4 } from "three";
3
3
 
4
4
  import type { Context } from "../engine/engine_setup.js";
5
5
  import { getParam } from "../engine/engine_utils.js";
6
+ import { MaterialPropertyBlock } from "../engine/engine_materialpropertyblock.js";
6
7
  import { type Renderer } from "./Renderer.js";
7
8
 
8
9
  const debug = getParam("debuglightmaps");
9
10
 
10
- declare type MaterialWithLightmap = Material & { lightMap?: Texture | null };
11
-
12
- let cloningCounter = 0;
13
-
14
- const $lightmapVersion = Symbol("lightmap-material-version");
11
+ const $lightmapKey = Symbol("lightmapKey");
15
12
 
16
13
 
17
14
  /**
18
15
  * This component is automatically added by the {@link Renderer} component if the object has lightmap uvs AND we have a lightmap.
19
- *
16
+ *
20
17
  * @category Rendering
21
18
  * @group Components
22
19
  */
@@ -29,9 +26,13 @@ export class RendererLightmap {
29
26
  if (tex !== this.lightmapTexture) {
30
27
  this.lightmapTexture = tex;
31
28
  this.applyLightmap();
29
+ this.updatePropertyBlockTexture();
32
30
  if (this.lightmapTexture) {
33
31
  NEEDLE_progressive.assignTextureLOD(this.lightmapTexture, 0).then(res => {
34
- if ((res as Texture)?.isTexture) this.lightmapTexture = res as Texture;
32
+ if ((res as Texture)?.isTexture) {
33
+ this.lightmapTexture = res as Texture;
34
+ this.updatePropertyBlockTexture();
35
+ }
35
36
  })
36
37
  }
37
38
  }
@@ -41,13 +42,12 @@ export class RendererLightmap {
41
42
  private lightmapScaleOffset: Vector4 = new Vector4(1, 1, 0, 0);
42
43
 
43
44
  private readonly renderer: Renderer;
44
- private readonly clonedMaterials = new Array<Material>();
45
+ private _isApplied: boolean = false;
45
46
 
46
47
  private get context(): Context { return this.renderer.context; }
47
48
  private get gameObject() { return this.renderer.gameObject; }
49
+
48
50
  private lightmapTexture: Texture | null = null;
49
- private lightmapScaleOffsetUniform = { value: new Vector4(1, 1, 0, 0) };
50
- private lightmapUniform: { value: Texture | null } = { value: null };
51
51
 
52
52
  constructor(renderer: Renderer) {
53
53
  this.renderer = renderer;
@@ -60,7 +60,10 @@ export class RendererLightmap {
60
60
  this.lightmapScaleOffset = lightmapScaleOffset;
61
61
  this.lightmapTexture = lightmapTexture;
62
62
  NEEDLE_progressive.assignTextureLOD(lightmapTexture, 0).then(res => {
63
- if ((res as Texture)?.isTexture) this.lightmapTexture = res as Texture;
63
+ if ((res as Texture)?.isTexture) {
64
+ this.lightmapTexture = res as Texture;
65
+ this.updatePropertyBlockTexture();
66
+ }
64
67
  })
65
68
  if (debug == "show") {
66
69
  console.log("Lightmap:", this.gameObject.name, lightmapIndex, "\nScaleOffset:", lightmapScaleOffset, "\nTexture:", lightmapTexture)
@@ -70,18 +73,18 @@ export class RendererLightmap {
70
73
  this.applyLightmap();
71
74
  }
72
75
 
73
- updateLightmapUniforms(material: Material) {
74
- const uniforms = material["uniforms"];
75
- if (uniforms && uniforms.lightmap) {
76
- this.lightmapScaleOffsetUniform.value = this.lightmapScaleOffset;
77
- uniforms.lightmapScaleOffset = this.lightmapScaleOffsetUniform;
78
- }
76
+ updateLightmapUniforms(_material: any) {
79
77
  }
80
78
 
81
79
  /**
82
- * Apply the lightmap to the object. This will clone the material and set the lightmap texture and scale/offset
80
+ * Apply the lightmap to the object using MaterialPropertyBlock instead of cloning materials.
81
+ * The lightmap texture and its per-object UV transform are set as overrides via PropertyBlock.
82
+ * Three.js reads material.lightMap to determine shader defines and upload uniforms,
83
+ * and uses texture.offset/repeat to compute lightMapTransform in the vertex shader.
83
84
  */
84
85
  applyLightmap() {
86
+ if (this._isApplied) return;
87
+
85
88
  if (this.gameObject.type === "Object3D") {
86
89
  if (debug)
87
90
  console.warn("Can not add lightmap. Is this object missing a renderer?", this.gameObject.name);
@@ -91,23 +94,61 @@ export class RendererLightmap {
91
94
  const mesh = this.gameObject as unknown as (Mesh | Group);
92
95
  this.ensureLightmapUvs(mesh);
93
96
 
94
- for (let i = 0; i < this.renderer.sharedMaterials.length; i++) {
95
-
96
- const mat = this.renderer.sharedMaterials[i];
97
- if (!mat) continue;
98
- const newMat = this.ensureLightmapMaterial(mat, i);
99
- if (mat !== newMat) {
100
- this.renderer.sharedMaterials[i] = newMat;
97
+ if (this.lightmapIndex >= 0 && this.lightmapTexture) {
98
+ this.lightmapTexture.channel = 1;
99
+ const so = this.lightmapScaleOffset;
100
+ for (let i = 0; i < this.renderer.sharedMaterials.length; i++) {
101
+ const mat = this.renderer.sharedMaterials[i];
102
+ if (!mat) continue;
103
+
104
+ // If the material doesn't support lightmaps, skip it
105
+ if (mat["lightMap"] === undefined) continue;
106
+
107
+ if (debug) console.log("Setting lightmap on material", mat.name, "for renderer", this.renderer.name);
108
+
109
+ // Use property block to set lightMap with per-object UV transform.
110
+ // The texture transform differentiates cache keys per object and
111
+ // PropertyBlock handles save/restore of the shared texture's offset/repeat.
112
+ const propertyBlock = MaterialPropertyBlock.get(this.gameObject);
113
+ propertyBlock.setOverride("lightMap", this.lightmapTexture, {
114
+ offset: new Vector2(so.z, 1 - so.y - so.w),
115
+ repeat: new Vector2(so.x, so.y)
116
+ });
117
+
118
+ (mat as any)[$lightmapKey] = true;
101
119
  }
120
+
121
+ this._isApplied = true;
102
122
  }
123
+ }
103
124
 
104
- if (this.lightmapIndex >= 0 && this.lightmapTexture) {
105
- // always on channel 1 for now. We could optimize this by passing the correct lightmap index along
106
- this.lightmapTexture.channel = 1;
107
- for (const mat of this.renderer.sharedMaterials) {
108
- if (mat) this.assignLightmapTexture(mat);
125
+ /** Update the lightMap override on all property blocks (e.g. after LOD swap) */
126
+ private updatePropertyBlockTexture() {
127
+ if (!this._isApplied || !this.lightmapTexture) return;
128
+ this.lightmapTexture.channel = 1;
129
+ const so = this.lightmapScaleOffset;
130
+ const propertyBlock = MaterialPropertyBlock.get(this.gameObject);
131
+ propertyBlock.setOverride("lightMap", this.lightmapTexture, {
132
+ offset: new Vector2(so.z, 1 - so.y - so.w),
133
+ repeat: new Vector2(so.x, so.y)
134
+ });
135
+ }
136
+
137
+ /**
138
+ * Remove the lightmap from the object
139
+ */
140
+ onUnset() {
141
+ for (let i = 0; i < this.renderer.sharedMaterials.length; i++) {
142
+ const mat = this.renderer.sharedMaterials[i];
143
+ if (mat) {
144
+ delete (mat as any)[$lightmapKey];
109
145
  }
110
146
  }
147
+ const block = MaterialPropertyBlock.get(this.gameObject);
148
+ if (block) {
149
+ block.clearOverride("lightMap");
150
+ block.clearOverride("lightMapIntensity");
151
+ }
111
152
  }
112
153
 
113
154
  private ensureLightmapUvs(object: Object3D | Group | Mesh) {
@@ -123,59 +164,8 @@ export class RendererLightmap {
123
164
  }
124
165
  }
125
166
 
126
- private ensureLightmapMaterial(material: Material, index: number) {
127
- if (!material.userData) material.userData = {};
128
- // if (material instanceof MeshPhysicalMaterial) {
129
- // return material;
130
- // }
131
- // check if the material version has changed and only then clone the material
132
- if (this.clonedMaterials[index] !== material) {
133
- if (debug) {
134
- ++cloningCounter;
135
- if (cloningCounter++ < 1000) {
136
- console.warn(`Cloning material for lightmap ${this.renderer.name}: '${material.name}'`);
137
- }
138
- else if (cloningCounter === 1000) {
139
- console.warn(`Further material cloning for lightmaps suppressed to avoid flooding the console.`);
140
- }
141
- }
142
- const mat: Material = material.clone();
143
- if (!mat.name?.includes("(lightmap)")) mat.name = material.name + " (lightmap)";
144
- material = mat;
145
- material.onBeforeCompile = this.onBeforeCompile;
146
- this.clonedMaterials[index] = material;
147
-
148
- }
149
- return material;
150
- }
151
-
152
- private assignLightmapTexture(material: MaterialWithLightmap) {
153
- if (!material) return;
154
- if (material instanceof MeshPhysicalMaterial && material.transmission > 0) {
155
- return;
156
- }
157
- const hasChanged = material.lightMap !== this.lightmapTexture || material[$lightmapVersion] !== material.version;
158
- if (!hasChanged) {
159
- return;
160
- }
161
-
162
- if (debug) console.log(`Assigning lightmap texture ${this.renderer.name}: '${material.name}' (${material.version} ${material[$lightmapVersion]})`);
163
-
164
- // assign the lightmap
165
- material.lightMap = this.lightmapTexture;
166
- material.needsUpdate = true;
167
- // store the version of the material
168
- material[$lightmapVersion] = material.version;
169
- }
170
-
171
- private onBeforeCompile = (shader: WebGLProgramParametersWithUniforms, _) => {
172
- if (debug === "verbose") console.log("Lightmaps, before compile\n", shader)
173
- this.lightmapScaleOffsetUniform.value = this.lightmapScaleOffset;
174
- this.lightmapUniform.value = this.lightmapTexture;
175
- shader.uniforms.lightmapScaleOffset = this.lightmapScaleOffsetUniform;
176
- }
177
-
178
167
  private setLightmapDebugMaterial() {
168
+ const so = this.lightmapScaleOffset;
179
169
 
180
170
  // debug lightmaps
181
171
  this.gameObject["material"] = new ShaderMaterial({
@@ -190,7 +180,6 @@ export class RendererLightmap {
190
180
  fragmentShader: `
191
181
  uniform sampler2D lightMap;
192
182
  uniform float lightMapIntensity;
193
- uniform vec4 lightmapScaleOffset;
194
183
  varying vec2 vUv1;
195
184
 
196
185
  // took from threejs 05fc79cd52b79e8c3e8dec1e7dca72c5c39983a4
@@ -199,8 +188,8 @@ export class RendererLightmap {
199
188
  }
200
189
 
201
190
  void main() {
202
- vec2 lUv = vUv1.xy * lightmapScaleOffset.xy + vec2(lightmapScaleOffset.z, (1. - (lightmapScaleOffset.y + lightmapScaleOffset.w)));
203
-
191
+ vec2 lUv = vUv1.xy * vec2(${so.x.toFixed(6)}, ${so.y.toFixed(6)}) + vec2(${so.z.toFixed(6)}, ${(1 - so.y - so.w).toFixed(6)});
192
+
204
193
  vec4 lightMapTexel = texture2D( lightMap, lUv);
205
194
  gl_FragColor = lightMapTexel;
206
195
  gl_FragColor.a = 1.;
@@ -209,4 +198,4 @@ export class RendererLightmap {
209
198
  defines: { USE_LIGHTMAP: '' }
210
199
  });
211
200
  }
212
- }
201
+ }