@babylonjs/loaders 9.10.1 → 9.11.0

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.
@@ -74,6 +74,9 @@ export declare class TransmissionHelper {
74
74
  private _opaqueMeshesCache;
75
75
  private _transparentMeshesCache;
76
76
  private _materialObservers;
77
+ private _newMeshObserver;
78
+ private _removedMeshObserver;
79
+ private _disposed;
77
80
  private readonly _materialImpls;
78
81
  private readonly _adapterCache;
79
82
  /**
@@ -32,6 +32,9 @@ export class TransmissionHelper {
32
32
  this._opaqueMeshesCache = [];
33
33
  this._transparentMeshesCache = [];
34
34
  this._materialObservers = {};
35
+ this._newMeshObserver = null;
36
+ this._removedMeshObserver = null;
37
+ this._disposed = false;
35
38
  // Material implementations registered by loaders. Each entry maps a material class
36
39
  // to its adapter class so the helper can classify and interact with materials
37
40
  // independently of whichever loader originally created them.
@@ -191,6 +194,13 @@ export class TransmissionHelper {
191
194
  // we need to defer the processing because _addMesh may be called as part as an instance mesh creation, in which case some
192
195
  // internal properties are not setup yet, like _sourceMesh (needed when doing mesh.material below)
193
196
  Tools.SetImmediate(() => {
197
+ // Guard: skip if the helper was disposed before this deferred callback fires.
198
+ // Without this, a disposed helper with a null _opaqueRenderTarget would stamp
199
+ // null onto transmission materials, overriding any texture already assigned by
200
+ // an active frame graph or other external code.
201
+ if (this._disposed) {
202
+ return;
203
+ }
194
204
  if (mesh.material) {
195
205
  const classification = this._classifyMeshMaterials(mesh);
196
206
  if (classification === "transparent") {
@@ -226,9 +236,9 @@ export class TransmissionHelper {
226
236
  _parseScene() {
227
237
  this._scene.meshes.forEach(this._addMesh.bind(this));
228
238
  // Listen for when a mesh is added to the scene and add it to our cache lists.
229
- this._scene.onNewMeshAddedObservable.add(this._addMesh.bind(this));
239
+ this._newMeshObserver = this._scene.onNewMeshAddedObservable.add(this._addMesh.bind(this));
230
240
  // Listen for when a mesh is removed from to the scene and remove it from our cache lists.
231
- this._scene.onMeshRemovedObservable.add(this._removeMesh.bind(this));
241
+ this._removedMeshObserver = this._scene.onMeshRemovedObservable.add(this._removeMesh.bind(this));
232
242
  }
233
243
  // When one of the meshes in the scene has its material changed, make sure that it's in the correct cache list.
234
244
  _onMeshMaterialChanged(mesh) {
@@ -335,6 +345,34 @@ export class TransmissionHelper {
335
345
  * Dispose all the elements created by the Helper.
336
346
  */
337
347
  dispose() {
348
+ // Set the disposed flag first so any pending SetImmediate callbacks (from _addMesh)
349
+ // are no-ops. Without this guard a deferred _classifyMeshMaterials call would stamp
350
+ // a null _opaqueRenderTarget onto transmission materials after disposal.
351
+ this._disposed = true;
352
+ // Unregister scene-level observers so this helper stops reacting to mesh changes.
353
+ this._newMeshObserver?.remove();
354
+ this._removedMeshObserver?.remove();
355
+ this._newMeshObserver = null;
356
+ this._removedMeshObserver = null;
357
+ // Remove per-mesh material-change observers for all tracked meshes.
358
+ const allTracked = [...this._transparentMeshesCache, ...this._opaqueMeshesCache];
359
+ for (const mesh of allTracked) {
360
+ const observer = this._materialObservers[mesh.uniqueId];
361
+ if (observer) {
362
+ observer.remove();
363
+ delete this._materialObservers[mesh.uniqueId];
364
+ }
365
+ }
366
+ // Also remove any remaining observers that were registered before deferred
367
+ // classification added their meshes to the caches.
368
+ for (const mesh of this._scene.meshes) {
369
+ const observer = this._materialObservers[mesh.uniqueId];
370
+ if (observer) {
371
+ observer.remove();
372
+ delete this._materialObservers[mesh.uniqueId];
373
+ }
374
+ }
375
+ this._materialObservers = {};
338
376
  this._scene._transmissionHelper = undefined;
339
377
  if (this._opaqueRenderTarget) {
340
378
  this._opaqueRenderTarget.dispose();
@@ -1 +1 @@
1
- {"version":3,"file":"transmissionHelper.js","sourceRoot":"","sources":["../../../../../../dev/loaders/src/glTF/2.0/Extensions/transmissionHelper.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAK7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,6CAA6C,CAAC;AAClF,OAAO,EAAiB,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAkExC;;;GAGG;AACH,MAAM,OAAO,kBAAkB;IAC3B;;;OAGG;IACK,MAAM,CAAC,kBAAkB;QAC7B,OAAO;YACH,UAAU,EAAE,IAAI;YAChB,OAAO,EAAE,CAAC;YACV,kBAAkB,EAAE,CAAC;YACrB,mBAAmB,EAAE,CAAC,CAAC;YACvB,uBAAuB,EAAE,SAAS,CAAC,sBAAsB;YACzD,eAAe,EAAE,IAAI;SACxB,CAAC;IACN,CAAC;IA+BD;;;;OAIG;IACH,YAAY,OAA4C,EAAE,KAAY;QA9B9D,wBAAmB,GAAkC,IAAI,CAAC;QAC1D,uBAAkB,GAAmB,EAAE,CAAC;QACxC,4BAAuB,GAAmB,EAAE,CAAC;QAC7C,uBAAkB,GAAuD,EAAE,CAAC;QAEpF,mFAAmF;QACnF,8EAA8E;QAC9E,6DAA6D;QAC5C,mBAAc,GAAsC,EAAE,CAAC;QACvD,kBAAa,GAA+C,IAAI,OAAO,EAAE,CAAC;QAQ3F,wEAAwE;QACxE,gEAAgE;QACxD,gCAA2B,GAAmC,IAAI,GAAG,EAAE,CAAC;QAChF,sEAAsE;QACtE,8DAA8D;QACtD,yBAAoB,GAAiC,IAAI,GAAG,EAAE,CAAC;QAC/D,oBAAe,GAAiC,IAAI,GAAG,EAAE,CAAC;QAQ9D,IAAI,CAAC,QAAQ,GAAG;YACZ,GAAG,kBAAkB,CAAC,kBAAkB,EAAE;YAC1C,GAAG,OAAO;SACb,CAAC;QACF,IAAI,CAAC,MAAM,GAAG,KAAY,CAAC;QAC3B,IAAI,CAAC,MAAM,CAAC,mBAAmB,GAAG,IAAI,CAAC;QAEvC,IAAI,CAAC,iBAAiB,GAAG,IAAI,UAAU,EAAE,CAAC;QAC1C,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,OAAO,CAAC,GAAG,EAAE;YACzC,IAAI,CAAC,OAAO,EAAE,CAAC;QACnB,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,IAAI,CAAC,mBAAmB,EAAE,CAAC;IAC/B,CAAC;IAED;;;;;OAKG;IACI,eAAe,CAAC,IAAqC;QACxD,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,KAAK,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC;YAC3E,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,CAAC;IACL,CAAC;IAED;;;OAGG;IACI,aAAa,CAAC,OAA4C;QAC7D,uEAAuE;QACvE,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,GAAW,EAAE,EAAE,CAAE,IAAI,CAAC,QAAgB,CAAC,GAAG,CAAC,KAAM,OAAe,CAAC,GAAG,CAAC,CAAC,CAAC;QACtH,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC;YACpB,OAAO;QACX,CAAC;QAED,MAAM,UAAU,GAAG;YACf,GAAG,IAAI,CAAC,QAAQ;YAChB,GAAG,OAAO;SACb,CAAC;QAEF,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC;QACjC,IAAI,CAAC,QAAQ,GAAG,UAAU,CAAC;QAE3B,uCAAuC;QACvC,IACI,UAAU,CAAC,UAAU,KAAK,UAAU,CAAC,UAAU;YAC/C,UAAU,CAAC,uBAAuB,KAAK,UAAU,CAAC,uBAAuB;YACzE,UAAU,CAAC,eAAe,KAAK,UAAU,CAAC,eAAe;YACzD,CAAC,IAAI,CAAC,mBAAmB,EAC3B,CAAC;YACC,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC/B,CAAC;aAAM,CAAC;YACJ,IAAI,CAAC,mBAAmB,CAAC,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC;YACtD,IAAI,CAAC,mBAAmB,CAAC,kBAAkB,GAAG,UAAU,CAAC,kBAAkB,CAAC;YAC5E,IAAI,CAAC,mBAAmB,CAAC,mBAAmB,GAAG,UAAU,CAAC,mBAAmB,CAAC;QAClF,CAAC;IACL,CAAC;IAED;;OAEG;IACI,eAAe;QAClB,OAAO,IAAI,CAAC,mBAAmB,CAAC;IACpC,CAAC;IAEO,mBAAmB,CAAC,QAAkB;QAC1C,IAAI,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC/C,IAAI,CAAC,OAAO,EAAE,CAAC;YACX,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;gBACrC,IAAI,QAAQ,YAAY,IAAI,CAAC,aAAa,EAAE,CAAC;oBACzC,OAAO,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;oBAC1C,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;oBAC1C,MAAM;gBACV,CAAC;YACL,CAAC;QACL,CAAC;QACD,OAAO,OAAO,CAAC;IACnB,CAAC;IAED;;;;;;;OAOG;IACK,sBAAsB,CAAC,IAAkB;QAC7C,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC/B,IAAI,CAAC,QAAQ,EAAE,CAAC;YACZ,OAAO,QAAQ,CAAC;QACpB,CAAC;QAED,uBAAuB;QACvB,IAAI,CAAC,CAAC,QAAQ,YAAY,aAAa,CAAC,EAAE,CAAC;YACvC,MAAM,OAAO,GAAG,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;YACnD,IAAI,CAAC,OAAO,EAAE,CAAC;gBACX,OAAO,QAAQ,CAAC;YACpB,CAAC;YACD,IAAI,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC;gBAC1B,OAAO,CAAC,2BAA2B,GAAG,IAAI,CAAC,mBAAmB,CAAC;gBAC/D,OAAO,aAAa,CAAC;YACzB,CAAC;YACD,OAAO,QAAQ,CAAC;QACpB,CAAC;QAED,2DAA2D;QAC3D,IAAI,cAAc,GAAG,KAAK,CAAC;QAC3B,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAU,CAAC;QAE7C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACpD,MAAM,MAAM,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACxC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACV,SAAS,GAAG,IAAI,CAAC;gBACjB,SAAS;YACb,CAAC;YACD,MAAM,OAAO,GAAG,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC;YACjD,IAAI,OAAO,EAAE,CAAC;gBACV,IAAI,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC;oBAC1B,OAAO,CAAC,2BAA2B,GAAG,IAAI,CAAC,mBAAmB,CAAC;oBAC/D,cAAc,GAAG,IAAI,CAAC;oBACtB,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gBAC9B,CAAC;qBAAM,CAAC;oBACJ,SAAS,GAAG,IAAI,CAAC;gBACrB,CAAC;YACL,CAAC;iBAAM,CAAC;gBACJ,SAAS,GAAG,IAAI,CAAC;YACrB,CAAC;QACL,CAAC;QAED,IAAI,cAAc,IAAI,SAAS,EAAE,CAAC;YAC9B,IAAI,CAAC,2BAA2B,CAAC,GAAG,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC;YAC/D,IAAI,CAAC,2BAA2B,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC;YAC3D,OAAO,OAAO,CAAC;QACnB,CAAC;QACD,IAAI,CAAC,2BAA2B,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC9C,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACvC,OAAO,cAAc,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC;IACrD,CAAC;IAED;;;;;OAKG;IACK,2BAA2B,CAAC,IAAkB,EAAE,kBAA+B;QACnF,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACjB,IAAI,CAAC,oBAAoB,CAAC,GAAG,CACzB,IAAI,EACJ,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EAAW,EAAE,EAAE,CAAC,CAAC,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CACpF,CAAC;QACN,CAAC;IACL,CAAC;IAEO,QAAQ,CAAC,IAAkB;QAC/B,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,2BAA2B,CAAC,GAAG,CAAC,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAEtH,0HAA0H;QAC1H,kGAAkG;QAClG,KAAK,CAAC,YAAY,CAAC,GAAG,EAAE;YACpB,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAChB,MAAM,cAAc,GAAG,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAC;gBACzD,IAAI,cAAc,KAAK,aAAa,EAAE,CAAC;oBACnC,IAAI,IAAI,CAAC,uBAAuB,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;wBACpD,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBAC5C,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACJ,oDAAoD;oBACpD,yDAAyD;oBACzD,mDAAmD;oBACnD,IAAI,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;wBAC/C,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBACvC,CAAC;gBACL,CAAC;YACL,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAEO,WAAW,CAAC,IAAkB;QAClC,IAAI,CAAC,2BAA2B,CAAC,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;QAChF,OAAO,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC9C,IAAI,GAAG,GAAG,IAAI,CAAC,uBAAuB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACrD,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;YACb,IAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAChD,CAAC;QACD,GAAG,GAAG,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC5C,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;YACb,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAC3C,CAAC;QACD,IAAI,CAAC,2BAA2B,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC9C,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC3C,CAAC;IAEO,WAAW;QACf,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACrD,8EAA8E;QAC9E,IAAI,CAAC,MAAM,CAAC,wBAAwB,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACnE,0FAA0F;QAC1F,IAAI,CAAC,MAAM,CAAC,uBAAuB,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACzE,CAAC;IAED,+GAA+G;IACvG,sBAAsB,CAAC,IAAkB;QAC7C,MAAM,cAAc,GAAG,IAAI,CAAC,uBAAuB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAClE,MAAM,SAAS,GAAG,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAExD,MAAM,cAAc,GAAG,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAC;QAEzD,IAAI,cAAc,KAAK,aAAa,EAAE,CAAC;YACnC,+CAA+C;YAC/C,IAAI,SAAS,KAAK,CAAC,CAAC,EAAE,CAAC;gBACnB,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;gBAC7C,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC5C,CAAC;iBAAM,IAAI,cAAc,KAAK,CAAC,CAAC,EAAE,CAAC;gBAC/B,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC5C,CAAC;QACL,CAAC;aAAM,CAAC;YACJ,iEAAiE;YACjE,0DAA0D;YAC1D,IAAI,cAAc,KAAK,CAAC,CAAC,EAAE,CAAC;gBACxB,IAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC;gBACvD,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACvC,CAAC;iBAAM,IAAI,SAAS,KAAK,CAAC,CAAC,EAAE,CAAC;gBAC1B,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACvC,CAAC;QACL,CAAC;IACL,CAAC;IAED;;;;OAIG;IACI,oBAAoB;QACvB,OAAO,IAAI,CAAC,mBAAmB,EAAE,kBAAkB,EAAE,KAAK,IAAI,CAAC;IACnE,CAAC;IAED;;;OAGG;IACI,mBAAmB;QACtB,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC3B,IAAI,CAAC,mBAAmB,CAAC,OAAO,EAAE,CAAC;QACvC,CAAC;QACD,IAAI,CAAC,mBAAmB,GAAG,IAAI,mBAAmB,CAC9C,oBAAoB,EACpB,IAAI,CAAC,QAAQ,CAAC,UAAU,EACxB,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,QAAQ,CAAC,eAAe,EAC7B,SAAS,EACT,IAAI,CAAC,QAAQ,CAAC,uBAAuB,CACxC,CAAC;QACF,IAAI,CAAC,mBAAmB,CAAC,oBAAoB,GAAG,IAAI,CAAC;QACrD,IAAI,CAAC,mBAAmB,CAAC,UAAU,GAAG,IAAI,CAAC,kBAAkB,CAAC;QAC9D,IAAI,CAAC,mBAAmB,CAAC,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,KAAK,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QAC1G,IAAI,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC,GAAG,GAAG,CAAC;QAC5C,IAAI,CAAC,mBAAmB,CAAC,UAAU,GAAG,KAAK,CAAC;QAC5C,IAAI,CAAC,mBAAmB,CAAC,kBAAkB,GAAG,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC;QAC/E,IAAI,CAAC,mBAAmB,CAAC,mBAAmB,GAAG,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC;QACjF,IAAI,CAAC,mBAAmB,CAAC,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;QACzD,IAAI,CAAC,mBAAmB,CAAC,aAAa,GAAG,IAAI,CAAC;QAC9C,IAAI,CAAC,mBAAmB,CAAC,eAAe,GAAG,IAAI,CAAC;QAChD,IAAI,CAAC,mBAAmB,CAAC,sBAAsB,GAAG,IAAI,CAAC;QAEvD,IAAI,qBAA6B,CAAC;QAClC,IAAI,CAAC,mBAAmB,CAAC,sBAAsB,CAAC,GAAG,CAAC,CAAC,kBAAkB,EAAE,EAAE;YACvE,qBAAqB,GAAG,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC;YACzD,IAAI,CAAC,MAAM,CAAC,oBAAoB,GAAG,GAAG,CAAC;YACvC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;gBAC5B,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,kBAAkB,CAAC,kBAAkB,CAAC,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,uBAAuB,CAAC,CAAC;YAC9H,CAAC;iBAAM,CAAC;gBACJ,kBAAkB,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;YACrE,CAAC;YACD,kBAAkB,CAAC,UAAU,CAAC,CAAC,GAAG,GAAG,CAAC;YAEtC,sEAAsE;YACtE,+EAA+E;YAC/E,MAAM,SAAS,GAAG,IAAI,CAAC,oBAAoB,CAAC,OAAO,EAAE,CAAC;YACtD,KAAK,IAAI,OAAO,GAAG,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC;gBAC7E,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBAC9B,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBACpC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;oBACjB,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;oBAC/C,IAAI,CAAC,SAAS,GAAG,UAAU,CAAC;gBAChC,CAAC;YACL,CAAC;QACL,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,mBAAmB,CAAC,uBAAuB,CAAC,GAAG,CAAC,GAAG,EAAE;YACtD,IAAI,CAAC,MAAM,CAAC,oBAAoB,GAAG,qBAAqB,CAAC;YAEzD,2DAA2D;YAC3D,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,CAAC;YACpD,KAAK,IAAI,UAAU,GAAG,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC;gBAC5F,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACxD,CAAC;YACD,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,6DAA6D;QAC7D,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,uBAAuB,EAAE,CAAC;YAC9C,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAChB,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAC;YACtC,CAAC;QACL,CAAC;QACD,MAAM,YAAY,GAAG,IAAI,CAAC,2BAA2B,CAAC,OAAO,EAAE,CAAC;QAChE,KAAK,IAAI,UAAU,GAAG,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC;YAC5F,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACjC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAChB,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAC;YACtC,CAAC;QACL,CAAC;IACL,CAAC;IAED;;OAEG;IACI,OAAO;QACV,IAAI,CAAC,MAAM,CAAC,mBAAmB,GAAG,SAAS,CAAC;QAC5C,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC3B,IAAI,CAAC,mBAAmB,CAAC,OAAO,EAAE,CAAC;YACnC,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;QACpC,CAAC;QACD,IAAI,CAAC,uBAAuB,GAAG,EAAE,CAAC;QAClC,IAAI,CAAC,kBAAkB,GAAG,EAAE,CAAC;QAC7B,IAAI,CAAC,2BAA2B,CAAC,KAAK,EAAE,CAAC;QACzC,IAAI,CAAC,oBAAoB,CAAC,KAAK,EAAE,CAAC;QAClC,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;IACjC,CAAC;CACJ;AAED;;;;;;;GAOG;AACH,gEAAgE;AAChE,MAAM,UAAU,wBAAwB,CAAC,MAAkB,EAAE,eAAyB;IAClF,IAAI,MAAM,CAAC,MAAM,CAAC,yBAAyB,EAAE,CAAC;QAC1C,OAAO;IACX,CAAC;IACD,MAAM,KAAK,GAAG,eAAe,CAAC,QAAQ,EAA0C,CAAC;IACjF,MAAM,cAAc,GAAG,KAAK,CAAC,mBAAmB,CAAC;IACjD,MAAM,MAAM,GAAG,cAAc,IAAI,IAAI,kBAAkB,CAAC,EAAE,EAAE,eAAe,CAAC,QAAQ,EAAE,CAAC,CAAC;IACxF,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC;QAC/D,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IACD,IAAI,cAAc,IAAI,CAAC,cAAc,CAAC,oBAAoB,EAAE,EAAE,CAAC;QAC3D,cAAc,CAAC,mBAAmB,EAAE,CAAC;IACzC,CAAC;AACL,CAAC","sourcesContent":["import { type Nullable } from \"core/types\";\nimport { type Material } from \"core/Materials/material\";\nimport { MultiMaterial } from \"core/Materials/multiMaterial\";\nimport { type Scene } from \"core/scene\";\nimport { type AbstractMesh } from \"core/Meshes/abstractMesh\";\nimport { type SubMesh } from \"core/Meshes/subMesh\";\nimport { type Texture } from \"core/Materials/Textures/texture\";\nimport { RenderTargetTexture } from \"core/Materials/Textures/renderTargetTexture\";\nimport { type Observer, Observable } from \"core/Misc/observable\";\nimport { Constants } from \"core/Engines/constants\";\nimport { Tools } from \"core/Misc/tools\";\nimport { type Color4 } from \"core/Maths/math.color\";\nimport { type IMaterialLoadingAdapter } from \"../materialLoadingAdapter\";\nimport { type GLTFLoader } from \"../glTFLoader\";\n\n/**\n * Describes a material class and its corresponding loading adapter.\n * Passed to TransmissionHelper so it can classify and interact with materials\n * independently of any specific loader instance.\n */\nexport interface ITransmissionHelperMaterialImpl {\n /** The material class constructor */\n materialClass: typeof Material;\n /** The adapter class constructor */\n adapterClass: new (material: Material) => IMaterialLoadingAdapter;\n}\n\n/**\n * @internal\n */\nexport interface ITransmissionHelperHolder {\n /** The transmission helper instance, if created on the scene */\n _transmissionHelper: TransmissionHelper | undefined;\n}\n\n/**\n * Options for the TransmissionHelper.\n */\nexport interface ITransmissionHelperOptions {\n /**\n * The size of the render buffers (default: 1024)\n */\n renderSize: number;\n\n /**\n * The number of samples to use when generating the render target texture for opaque meshes (default: 4)\n */\n samples: number;\n\n /**\n * Scale to apply when selecting the LOD level to sample the refraction texture (default: 1)\n */\n lodGenerationScale: number;\n\n /**\n * Offset to apply when selecting the LOD level to sample the refraction texture (default: -4)\n */\n lodGenerationOffset: number;\n\n /**\n * Type of the refraction render target texture (default: TEXTURETYPE_HALF_FLOAT)\n */\n renderTargetTextureType: number;\n\n /**\n * Defines if the mipmaps for the refraction render target texture must be generated (default: true)\n */\n generateMipmaps: boolean;\n\n /**\n * Clear color of the opaque texture. If not provided, use the scene clear color (which will be converted to linear space).\n * If provided, should be in linear space\n */\n clearColor?: Color4;\n}\n\n/**\n * A class to handle setting up the rendering of opaque objects to be shown through transmissive objects.\n * @internal\n */\nexport class TransmissionHelper {\n /**\n * Creates the default options for the helper.\n * @returns the default options\n */\n private static _GetDefaultOptions(): ITransmissionHelperOptions {\n return {\n renderSize: 1024,\n samples: 4,\n lodGenerationScale: 1,\n lodGenerationOffset: -4,\n renderTargetTextureType: Constants.TEXTURETYPE_HALF_FLOAT,\n generateMipmaps: true,\n };\n }\n\n private readonly _scene: Scene & ITransmissionHelperHolder;\n\n private _options: ITransmissionHelperOptions;\n\n private _opaqueRenderTarget: Nullable<RenderTargetTexture> = null;\n private _opaqueMeshesCache: AbstractMesh[] = [];\n private _transparentMeshesCache: AbstractMesh[] = [];\n private _materialObservers: { [id: string]: Nullable<Observer<AbstractMesh>> } = {};\n\n // Material implementations registered by loaders. Each entry maps a material class\n // to its adapter class so the helper can classify and interact with materials\n // independently of whichever loader originally created them.\n private readonly _materialImpls: ITransmissionHelperMaterialImpl[] = [];\n private readonly _adapterCache: WeakMap<Material, IMaterialLoadingAdapter> = new WeakMap();\n\n /**\n * This observable will be notified with any error during the creation of the environment,\n * mainly texture creation errors.\n */\n public onErrorObservable: Observable<{ message?: string; exception?: any }>;\n\n // For MultiMaterial meshes with mixed opaque/translucent sub-materials:\n // maps mesh → set of materialIndex values that are translucent.\n private _translucentMaterialIndices: Map<AbstractMesh, Set<number>> = new Map();\n // Precomputed opaque-only submesh arrays for mixed meshes, swapped in\n // during the opaque RT render to avoid per-frame allocations.\n private _opaqueOnlySubMeshes: Map<AbstractMesh, SubMesh[]> = new Map();\n private _savedSubMeshes: Map<AbstractMesh, SubMesh[]> = new Map();\n\n /**\n * constructor\n * @param options Defines the options we want to customize the helper\n * @param scene The scene to add the material to\n */\n constructor(options: Partial<ITransmissionHelperOptions>, scene: Scene) {\n this._options = {\n ...TransmissionHelper._GetDefaultOptions(),\n ...options,\n };\n this._scene = scene as any;\n this._scene._transmissionHelper = this;\n\n this.onErrorObservable = new Observable();\n this._scene.onDisposeObservable.addOnce(() => {\n this.dispose();\n });\n\n this._parseScene();\n this._setupRenderTargets();\n }\n\n /**\n * Registers a material implementation with the helper so it can classify and create\n * adapters for materials of that type. Safe to call multiple times with the same\n * implementation — duplicates are ignored.\n * @param impl The material implementation to register\n */\n public addMaterialImpl(impl: ITransmissionHelperMaterialImpl): void {\n if (!this._materialImpls.some((i) => i.materialClass === impl.materialClass)) {\n this._materialImpls.push(impl);\n }\n }\n\n /**\n * Updates the helper options.\n * @param options the options to update\n */\n public updateOptions(options: Partial<ITransmissionHelperOptions>) {\n // First check if any options are actually being changed. If not, exit.\n const newValues = Object.keys(options).filter((key: string) => (this._options as any)[key] !== (options as any)[key]);\n if (!newValues.length) {\n return;\n }\n\n const newOptions = {\n ...this._options,\n ...options,\n };\n\n const oldOptions = this._options;\n this._options = newOptions;\n\n // If size changes, recreate everything\n if (\n newOptions.renderSize !== oldOptions.renderSize ||\n newOptions.renderTargetTextureType !== oldOptions.renderTargetTextureType ||\n newOptions.generateMipmaps !== oldOptions.generateMipmaps ||\n !this._opaqueRenderTarget\n ) {\n this._setupRenderTargets();\n } else {\n this._opaqueRenderTarget.samples = newOptions.samples;\n this._opaqueRenderTarget.lodGenerationScale = newOptions.lodGenerationScale;\n this._opaqueRenderTarget.lodGenerationOffset = newOptions.lodGenerationOffset;\n }\n }\n\n /**\n * @returns the opaque render target texture or null if not available.\n */\n public getOpaqueTarget(): Nullable<Texture> {\n return this._opaqueRenderTarget;\n }\n\n private _getOrCreateAdapter(material: Material): IMaterialLoadingAdapter | undefined {\n let adapter = this._adapterCache.get(material);\n if (!adapter) {\n for (const impl of this._materialImpls) {\n if (material instanceof impl.materialClass) {\n adapter = new impl.adapterClass(material);\n this._adapterCache.set(material, adapter);\n break;\n }\n }\n }\n return adapter;\n }\n\n /**\n * Classify a mesh's materials as transparent, opaque, or mixed.\n * Sets the refraction background texture on any translucent materials found.\n * For mixed MultiMaterial meshes, populates _translucentMaterialIndices so\n * their translucent submeshes can be excluded from the opaque render target.\n * @param mesh - The mesh to classify\n * @returns 'transparent' if all materials are translucent, 'opaque' if none are, 'mixed' if both\n */\n private _classifyMeshMaterials(mesh: AbstractMesh): \"transparent\" | \"opaque\" | \"mixed\" {\n const material = mesh.material;\n if (!material) {\n return \"opaque\";\n }\n\n // Single material case\n if (!(material instanceof MultiMaterial)) {\n const adapter = this._getOrCreateAdapter(material);\n if (!adapter) {\n return \"opaque\";\n }\n if (adapter.isTranslucent()) {\n adapter.refractionBackgroundTexture = this._opaqueRenderTarget;\n return \"transparent\";\n }\n return \"opaque\";\n }\n\n // MultiMaterial case: check each sub-material individually\n let hasTranslucent = false;\n let hasOpaque = false;\n const translucentIndices = new Set<number>();\n\n for (let i = 0; i < material.subMaterials.length; i++) {\n const subMat = material.subMaterials[i];\n if (!subMat) {\n hasOpaque = true;\n continue;\n }\n const adapter = this._getOrCreateAdapter(subMat);\n if (adapter) {\n if (adapter.isTranslucent()) {\n adapter.refractionBackgroundTexture = this._opaqueRenderTarget;\n hasTranslucent = true;\n translucentIndices.add(i);\n } else {\n hasOpaque = true;\n }\n } else {\n hasOpaque = true;\n }\n }\n\n if (hasTranslucent && hasOpaque) {\n this._translucentMaterialIndices.set(mesh, translucentIndices);\n this._rebuildOpaqueOnlySubMeshes(mesh, translucentIndices);\n return \"mixed\";\n }\n this._translucentMaterialIndices.delete(mesh);\n this._opaqueOnlySubMeshes.delete(mesh);\n return hasTranslucent ? \"transparent\" : \"opaque\";\n }\n\n /**\n * Rebuild the cached opaque-only submesh array for a mixed mesh.\n * Called when classification changes so the per-frame swap is allocation-free.\n * @param mesh - The mesh to rebuild for\n * @param translucentIndices - Set of materialIndex values that are translucent\n */\n private _rebuildOpaqueOnlySubMeshes(mesh: AbstractMesh, translucentIndices: Set<number>): void {\n if (mesh.subMeshes) {\n this._opaqueOnlySubMeshes.set(\n mesh,\n mesh.subMeshes.filter((sm: SubMesh) => !translucentIndices.has(sm.materialIndex))\n );\n }\n }\n\n private _addMesh(mesh: AbstractMesh): void {\n this._materialObservers[mesh.uniqueId] = mesh.onMaterialChangedObservable.add(this._onMeshMaterialChanged.bind(this));\n\n // we need to defer the processing because _addMesh may be called as part as an instance mesh creation, in which case some\n // internal properties are not setup yet, like _sourceMesh (needed when doing mesh.material below)\n Tools.SetImmediate(() => {\n if (mesh.material) {\n const classification = this._classifyMeshMaterials(mesh);\n if (classification === \"transparent\") {\n if (this._transparentMeshesCache.indexOf(mesh) === -1) {\n this._transparentMeshesCache.push(mesh);\n }\n } else {\n // Both 'opaque' and 'mixed' go in the opaque cache.\n // For 'mixed', the translucent submeshes are temporarily\n // excluded during the opaque render target render.\n if (this._opaqueMeshesCache.indexOf(mesh) === -1) {\n this._opaqueMeshesCache.push(mesh);\n }\n }\n }\n });\n }\n\n private _removeMesh(mesh: AbstractMesh): void {\n mesh.onMaterialChangedObservable.remove(this._materialObservers[mesh.uniqueId]);\n delete this._materialObservers[mesh.uniqueId];\n let idx = this._transparentMeshesCache.indexOf(mesh);\n if (idx !== -1) {\n this._transparentMeshesCache.splice(idx, 1);\n }\n idx = this._opaqueMeshesCache.indexOf(mesh);\n if (idx !== -1) {\n this._opaqueMeshesCache.splice(idx, 1);\n }\n this._translucentMaterialIndices.delete(mesh);\n this._opaqueOnlySubMeshes.delete(mesh);\n }\n\n private _parseScene(): void {\n this._scene.meshes.forEach(this._addMesh.bind(this));\n // Listen for when a mesh is added to the scene and add it to our cache lists.\n this._scene.onNewMeshAddedObservable.add(this._addMesh.bind(this));\n // Listen for when a mesh is removed from to the scene and remove it from our cache lists.\n this._scene.onMeshRemovedObservable.add(this._removeMesh.bind(this));\n }\n\n // When one of the meshes in the scene has its material changed, make sure that it's in the correct cache list.\n private _onMeshMaterialChanged(mesh: AbstractMesh) {\n const transparentIdx = this._transparentMeshesCache.indexOf(mesh);\n const opaqueIdx = this._opaqueMeshesCache.indexOf(mesh);\n\n const classification = this._classifyMeshMaterials(mesh);\n\n if (classification === \"transparent\") {\n // Fully translucent: move to transparent cache\n if (opaqueIdx !== -1) {\n this._opaqueMeshesCache.splice(opaqueIdx, 1);\n this._transparentMeshesCache.push(mesh);\n } else if (transparentIdx === -1) {\n this._transparentMeshesCache.push(mesh);\n }\n } else {\n // Opaque or mixed: move to opaque cache (mixed meshes have their\n // translucent submeshes excluded during opaque RT render)\n if (transparentIdx !== -1) {\n this._transparentMeshesCache.splice(transparentIdx, 1);\n this._opaqueMeshesCache.push(mesh);\n } else if (opaqueIdx === -1) {\n this._opaqueMeshesCache.push(mesh);\n }\n }\n }\n\n /**\n * @internal\n * Check if the opaque render target has not been disposed and can still be used.\n * @returns\n */\n public _isRenderTargetValid() {\n return this._opaqueRenderTarget?.getInternalTexture() !== null;\n }\n\n /**\n * @internal\n * Setup the render targets according to the specified options.\n */\n public _setupRenderTargets(): void {\n if (this._opaqueRenderTarget) {\n this._opaqueRenderTarget.dispose();\n }\n this._opaqueRenderTarget = new RenderTargetTexture(\n \"opaqueSceneTexture\",\n this._options.renderSize,\n this._scene,\n this._options.generateMipmaps,\n undefined,\n this._options.renderTargetTextureType\n );\n this._opaqueRenderTarget.ignoreCameraViewport = true;\n this._opaqueRenderTarget.renderList = this._opaqueMeshesCache;\n this._opaqueRenderTarget.clearColor = this._options.clearColor?.clone() ?? this._scene.clearColor.clone();\n this._opaqueRenderTarget.clearColor.a = 0.0;\n this._opaqueRenderTarget.gammaSpace = false;\n this._opaqueRenderTarget.lodGenerationScale = this._options.lodGenerationScale;\n this._opaqueRenderTarget.lodGenerationOffset = this._options.lodGenerationOffset;\n this._opaqueRenderTarget.samples = this._options.samples;\n this._opaqueRenderTarget.renderSprites = true;\n this._opaqueRenderTarget.renderParticles = true;\n this._opaqueRenderTarget.disableImageProcessing = true;\n\n let saveSceneEnvIntensity: number;\n this._opaqueRenderTarget.onBeforeBindObservable.add((opaqueRenderTarget) => {\n saveSceneEnvIntensity = this._scene.environmentIntensity;\n this._scene.environmentIntensity = 1.0;\n if (!this._options.clearColor) {\n this._scene.clearColor.toLinearSpaceToRef(opaqueRenderTarget.clearColor, this._scene.getEngine().useExactSrgbConversions);\n } else {\n opaqueRenderTarget.clearColor.copyFrom(this._options.clearColor);\n }\n opaqueRenderTarget.clearColor.a = 0.0;\n\n // For mixed MultiMaterial meshes, swap in the precomputed opaque-only\n // submesh array so translucent submeshes don't render into the opaque texture.\n const tlEntries = this._opaqueOnlySubMeshes.entries();\n for (let tlEntry = tlEntries.next(); !tlEntry.done; tlEntry = tlEntries.next()) {\n const mesh = tlEntry.value[0];\n const opaqueOnly = tlEntry.value[1];\n if (mesh.subMeshes) {\n this._savedSubMeshes.set(mesh, mesh.subMeshes);\n mesh.subMeshes = opaqueOnly;\n }\n }\n });\n this._opaqueRenderTarget.onAfterUnbindObservable.add(() => {\n this._scene.environmentIntensity = saveSceneEnvIntensity;\n\n // Restore the full submesh list after the opaque RT render\n const savedEntries = this._savedSubMeshes.entries();\n for (let savedEntry = savedEntries.next(); !savedEntry.done; savedEntry = savedEntries.next()) {\n savedEntry.value[0].subMeshes = savedEntry.value[1];\n }\n this._savedSubMeshes.clear();\n });\n\n // Update refraction textures on transparent and mixed meshes\n for (const mesh of this._transparentMeshesCache) {\n if (mesh.material) {\n this._classifyMeshMaterials(mesh);\n }\n }\n const mixedEntries = this._translucentMaterialIndices.entries();\n for (let mixedEntry = mixedEntries.next(); !mixedEntry.done; mixedEntry = mixedEntries.next()) {\n const mesh = mixedEntry.value[0];\n if (mesh.material) {\n this._classifyMeshMaterials(mesh);\n }\n }\n }\n\n /**\n * Dispose all the elements created by the Helper.\n */\n public dispose(): void {\n this._scene._transmissionHelper = undefined;\n if (this._opaqueRenderTarget) {\n this._opaqueRenderTarget.dispose();\n this._opaqueRenderTarget = null;\n }\n this._transparentMeshesCache = [];\n this._opaqueMeshesCache = [];\n this._translucentMaterialIndices.clear();\n this._opaqueOnlySubMeshes.clear();\n this._savedSubMeshes.clear();\n }\n}\n\n/**\n * Ensures a TransmissionHelper exists on the scene and has all of the loader's material\n * implementations registered with it. Creates the helper if one does not yet exist on the\n * scene, and recreates its render target if it has been disposed. Does nothing when the\n * loader's parent has `dontUseTransmissionHelper` set.\n * @param loader The glTF loader whose material implementations should be registered\n * @param babylonMaterial A material belonging to the scene where the helper should live\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function ensureTransmissionHelper(loader: GLTFLoader, babylonMaterial: Material): void {\n if (loader.parent.dontUseTransmissionHelper) {\n return;\n }\n const scene = babylonMaterial.getScene() as unknown as ITransmissionHelperHolder;\n const existingHelper = scene._transmissionHelper;\n const helper = existingHelper ?? new TransmissionHelper({}, babylonMaterial.getScene());\n for (const impl of Array.from(loader._pbrMaterialImpls.values())) {\n helper.addMaterialImpl(impl);\n }\n if (existingHelper && !existingHelper._isRenderTargetValid()) {\n existingHelper._setupRenderTargets();\n }\n}\n"]}
1
+ {"version":3,"file":"transmissionHelper.js","sourceRoot":"","sources":["../../../../../../dev/loaders/src/glTF/2.0/Extensions/transmissionHelper.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Nullable } from \"core/types\";\nimport { type Material } from \"core/Materials/material\";\nimport { MultiMaterial } from \"core/Materials/multiMaterial\";\nimport { type Scene } from \"core/scene\";\nimport { type AbstractMesh } from \"core/Meshes/abstractMesh\";\nimport { type SubMesh } from \"core/Meshes/subMesh\";\nimport { type Texture } from \"core/Materials/Textures/texture\";\nimport { RenderTargetTexture } from \"core/Materials/Textures/renderTargetTexture\";\nimport { type Observer, Observable } from \"core/Misc/observable\";\nimport { Constants } from \"core/Engines/constants\";\nimport { Tools } from \"core/Misc/tools\";\nimport { type Color4 } from \"core/Maths/math.color\";\nimport { type IMaterialLoadingAdapter } from \"../materialLoadingAdapter\";\nimport { type GLTFLoader } from \"../glTFLoader\";\n\n/**\n * Describes a material class and its corresponding loading adapter.\n * Passed to TransmissionHelper so it can classify and interact with materials\n * independently of any specific loader instance.\n */\nexport interface ITransmissionHelperMaterialImpl {\n /** The material class constructor */\n materialClass: typeof Material;\n /** The adapter class constructor */\n adapterClass: new (material: Material) => IMaterialLoadingAdapter;\n}\n\n/**\n * @internal\n */\nexport interface ITransmissionHelperHolder {\n /** The transmission helper instance, if created on the scene */\n _transmissionHelper: TransmissionHelper | undefined;\n}\n\n/**\n * Options for the TransmissionHelper.\n */\nexport interface ITransmissionHelperOptions {\n /**\n * The size of the render buffers (default: 1024)\n */\n renderSize: number;\n\n /**\n * The number of samples to use when generating the render target texture for opaque meshes (default: 4)\n */\n samples: number;\n\n /**\n * Scale to apply when selecting the LOD level to sample the refraction texture (default: 1)\n */\n lodGenerationScale: number;\n\n /**\n * Offset to apply when selecting the LOD level to sample the refraction texture (default: -4)\n */\n lodGenerationOffset: number;\n\n /**\n * Type of the refraction render target texture (default: TEXTURETYPE_HALF_FLOAT)\n */\n renderTargetTextureType: number;\n\n /**\n * Defines if the mipmaps for the refraction render target texture must be generated (default: true)\n */\n generateMipmaps: boolean;\n\n /**\n * Clear color of the opaque texture. If not provided, use the scene clear color (which will be converted to linear space).\n * If provided, should be in linear space\n */\n clearColor?: Color4;\n}\n\n/**\n * A class to handle setting up the rendering of opaque objects to be shown through transmissive objects.\n * @internal\n */\nexport class TransmissionHelper {\n /**\n * Creates the default options for the helper.\n * @returns the default options\n */\n private static _GetDefaultOptions(): ITransmissionHelperOptions {\n return {\n renderSize: 1024,\n samples: 4,\n lodGenerationScale: 1,\n lodGenerationOffset: -4,\n renderTargetTextureType: Constants.TEXTURETYPE_HALF_FLOAT,\n generateMipmaps: true,\n };\n }\n\n private readonly _scene: Scene & ITransmissionHelperHolder;\n\n private _options: ITransmissionHelperOptions;\n\n private _opaqueRenderTarget: Nullable<RenderTargetTexture> = null;\n private _opaqueMeshesCache: AbstractMesh[] = [];\n private _transparentMeshesCache: AbstractMesh[] = [];\n private _materialObservers: { [id: string]: Nullable<Observer<AbstractMesh>> } = {};\n private _newMeshObserver: Nullable<Observer<AbstractMesh>> = null;\n private _removedMeshObserver: Nullable<Observer<AbstractMesh>> = null;\n private _disposed = false;\n\n // Material implementations registered by loaders. Each entry maps a material class\n // to its adapter class so the helper can classify and interact with materials\n // independently of whichever loader originally created them.\n private readonly _materialImpls: ITransmissionHelperMaterialImpl[] = [];\n private readonly _adapterCache: WeakMap<Material, IMaterialLoadingAdapter> = new WeakMap();\n\n /**\n * This observable will be notified with any error during the creation of the environment,\n * mainly texture creation errors.\n */\n public onErrorObservable: Observable<{ message?: string; exception?: any }>;\n\n // For MultiMaterial meshes with mixed opaque/translucent sub-materials:\n // maps mesh → set of materialIndex values that are translucent.\n private _translucentMaterialIndices: Map<AbstractMesh, Set<number>> = new Map();\n // Precomputed opaque-only submesh arrays for mixed meshes, swapped in\n // during the opaque RT render to avoid per-frame allocations.\n private _opaqueOnlySubMeshes: Map<AbstractMesh, SubMesh[]> = new Map();\n private _savedSubMeshes: Map<AbstractMesh, SubMesh[]> = new Map();\n\n /**\n * constructor\n * @param options Defines the options we want to customize the helper\n * @param scene The scene to add the material to\n */\n constructor(options: Partial<ITransmissionHelperOptions>, scene: Scene) {\n this._options = {\n ...TransmissionHelper._GetDefaultOptions(),\n ...options,\n };\n this._scene = scene as any;\n this._scene._transmissionHelper = this;\n\n this.onErrorObservable = new Observable();\n this._scene.onDisposeObservable.addOnce(() => {\n this.dispose();\n });\n\n this._parseScene();\n this._setupRenderTargets();\n }\n\n /**\n * Registers a material implementation with the helper so it can classify and create\n * adapters for materials of that type. Safe to call multiple times with the same\n * implementation — duplicates are ignored.\n * @param impl The material implementation to register\n */\n public addMaterialImpl(impl: ITransmissionHelperMaterialImpl): void {\n if (!this._materialImpls.some((i) => i.materialClass === impl.materialClass)) {\n this._materialImpls.push(impl);\n }\n }\n\n /**\n * Updates the helper options.\n * @param options the options to update\n */\n public updateOptions(options: Partial<ITransmissionHelperOptions>) {\n // First check if any options are actually being changed. If not, exit.\n const newValues = Object.keys(options).filter((key: string) => (this._options as any)[key] !== (options as any)[key]);\n if (!newValues.length) {\n return;\n }\n\n const newOptions = {\n ...this._options,\n ...options,\n };\n\n const oldOptions = this._options;\n this._options = newOptions;\n\n // If size changes, recreate everything\n if (\n newOptions.renderSize !== oldOptions.renderSize ||\n newOptions.renderTargetTextureType !== oldOptions.renderTargetTextureType ||\n newOptions.generateMipmaps !== oldOptions.generateMipmaps ||\n !this._opaqueRenderTarget\n ) {\n this._setupRenderTargets();\n } else {\n this._opaqueRenderTarget.samples = newOptions.samples;\n this._opaqueRenderTarget.lodGenerationScale = newOptions.lodGenerationScale;\n this._opaqueRenderTarget.lodGenerationOffset = newOptions.lodGenerationOffset;\n }\n }\n\n /**\n * @returns the opaque render target texture or null if not available.\n */\n public getOpaqueTarget(): Nullable<Texture> {\n return this._opaqueRenderTarget;\n }\n\n private _getOrCreateAdapter(material: Material): IMaterialLoadingAdapter | undefined {\n let adapter = this._adapterCache.get(material);\n if (!adapter) {\n for (const impl of this._materialImpls) {\n if (material instanceof impl.materialClass) {\n adapter = new impl.adapterClass(material);\n this._adapterCache.set(material, adapter);\n break;\n }\n }\n }\n return adapter;\n }\n\n /**\n * Classify a mesh's materials as transparent, opaque, or mixed.\n * Sets the refraction background texture on any translucent materials found.\n * For mixed MultiMaterial meshes, populates _translucentMaterialIndices so\n * their translucent submeshes can be excluded from the opaque render target.\n * @param mesh - The mesh to classify\n * @returns 'transparent' if all materials are translucent, 'opaque' if none are, 'mixed' if both\n */\n private _classifyMeshMaterials(mesh: AbstractMesh): \"transparent\" | \"opaque\" | \"mixed\" {\n const material = mesh.material;\n if (!material) {\n return \"opaque\";\n }\n\n // Single material case\n if (!(material instanceof MultiMaterial)) {\n const adapter = this._getOrCreateAdapter(material);\n if (!adapter) {\n return \"opaque\";\n }\n if (adapter.isTranslucent()) {\n adapter.refractionBackgroundTexture = this._opaqueRenderTarget;\n return \"transparent\";\n }\n return \"opaque\";\n }\n\n // MultiMaterial case: check each sub-material individually\n let hasTranslucent = false;\n let hasOpaque = false;\n const translucentIndices = new Set<number>();\n\n for (let i = 0; i < material.subMaterials.length; i++) {\n const subMat = material.subMaterials[i];\n if (!subMat) {\n hasOpaque = true;\n continue;\n }\n const adapter = this._getOrCreateAdapter(subMat);\n if (adapter) {\n if (adapter.isTranslucent()) {\n adapter.refractionBackgroundTexture = this._opaqueRenderTarget;\n hasTranslucent = true;\n translucentIndices.add(i);\n } else {\n hasOpaque = true;\n }\n } else {\n hasOpaque = true;\n }\n }\n\n if (hasTranslucent && hasOpaque) {\n this._translucentMaterialIndices.set(mesh, translucentIndices);\n this._rebuildOpaqueOnlySubMeshes(mesh, translucentIndices);\n return \"mixed\";\n }\n this._translucentMaterialIndices.delete(mesh);\n this._opaqueOnlySubMeshes.delete(mesh);\n return hasTranslucent ? \"transparent\" : \"opaque\";\n }\n\n /**\n * Rebuild the cached opaque-only submesh array for a mixed mesh.\n * Called when classification changes so the per-frame swap is allocation-free.\n * @param mesh - The mesh to rebuild for\n * @param translucentIndices - Set of materialIndex values that are translucent\n */\n private _rebuildOpaqueOnlySubMeshes(mesh: AbstractMesh, translucentIndices: Set<number>): void {\n if (mesh.subMeshes) {\n this._opaqueOnlySubMeshes.set(\n mesh,\n mesh.subMeshes.filter((sm: SubMesh) => !translucentIndices.has(sm.materialIndex))\n );\n }\n }\n\n private _addMesh(mesh: AbstractMesh): void {\n this._materialObservers[mesh.uniqueId] = mesh.onMaterialChangedObservable.add(this._onMeshMaterialChanged.bind(this));\n\n // we need to defer the processing because _addMesh may be called as part as an instance mesh creation, in which case some\n // internal properties are not setup yet, like _sourceMesh (needed when doing mesh.material below)\n Tools.SetImmediate(() => {\n // Guard: skip if the helper was disposed before this deferred callback fires.\n // Without this, a disposed helper with a null _opaqueRenderTarget would stamp\n // null onto transmission materials, overriding any texture already assigned by\n // an active frame graph or other external code.\n if (this._disposed) {\n return;\n }\n if (mesh.material) {\n const classification = this._classifyMeshMaterials(mesh);\n if (classification === \"transparent\") {\n if (this._transparentMeshesCache.indexOf(mesh) === -1) {\n this._transparentMeshesCache.push(mesh);\n }\n } else {\n // Both 'opaque' and 'mixed' go in the opaque cache.\n // For 'mixed', the translucent submeshes are temporarily\n // excluded during the opaque render target render.\n if (this._opaqueMeshesCache.indexOf(mesh) === -1) {\n this._opaqueMeshesCache.push(mesh);\n }\n }\n }\n });\n }\n\n private _removeMesh(mesh: AbstractMesh): void {\n mesh.onMaterialChangedObservable.remove(this._materialObservers[mesh.uniqueId]);\n delete this._materialObservers[mesh.uniqueId];\n let idx = this._transparentMeshesCache.indexOf(mesh);\n if (idx !== -1) {\n this._transparentMeshesCache.splice(idx, 1);\n }\n idx = this._opaqueMeshesCache.indexOf(mesh);\n if (idx !== -1) {\n this._opaqueMeshesCache.splice(idx, 1);\n }\n this._translucentMaterialIndices.delete(mesh);\n this._opaqueOnlySubMeshes.delete(mesh);\n }\n\n private _parseScene(): void {\n this._scene.meshes.forEach(this._addMesh.bind(this));\n // Listen for when a mesh is added to the scene and add it to our cache lists.\n this._newMeshObserver = this._scene.onNewMeshAddedObservable.add(this._addMesh.bind(this));\n // Listen for when a mesh is removed from to the scene and remove it from our cache lists.\n this._removedMeshObserver = this._scene.onMeshRemovedObservable.add(this._removeMesh.bind(this));\n }\n\n // When one of the meshes in the scene has its material changed, make sure that it's in the correct cache list.\n private _onMeshMaterialChanged(mesh: AbstractMesh) {\n const transparentIdx = this._transparentMeshesCache.indexOf(mesh);\n const opaqueIdx = this._opaqueMeshesCache.indexOf(mesh);\n\n const classification = this._classifyMeshMaterials(mesh);\n\n if (classification === \"transparent\") {\n // Fully translucent: move to transparent cache\n if (opaqueIdx !== -1) {\n this._opaqueMeshesCache.splice(opaqueIdx, 1);\n this._transparentMeshesCache.push(mesh);\n } else if (transparentIdx === -1) {\n this._transparentMeshesCache.push(mesh);\n }\n } else {\n // Opaque or mixed: move to opaque cache (mixed meshes have their\n // translucent submeshes excluded during opaque RT render)\n if (transparentIdx !== -1) {\n this._transparentMeshesCache.splice(transparentIdx, 1);\n this._opaqueMeshesCache.push(mesh);\n } else if (opaqueIdx === -1) {\n this._opaqueMeshesCache.push(mesh);\n }\n }\n }\n\n /**\n * @internal\n * Check if the opaque render target has not been disposed and can still be used.\n * @returns\n */\n public _isRenderTargetValid() {\n return this._opaqueRenderTarget?.getInternalTexture() !== null;\n }\n\n /**\n * @internal\n * Setup the render targets according to the specified options.\n */\n public _setupRenderTargets(): void {\n if (this._opaqueRenderTarget) {\n this._opaqueRenderTarget.dispose();\n }\n this._opaqueRenderTarget = new RenderTargetTexture(\n \"opaqueSceneTexture\",\n this._options.renderSize,\n this._scene,\n this._options.generateMipmaps,\n undefined,\n this._options.renderTargetTextureType\n );\n this._opaqueRenderTarget.ignoreCameraViewport = true;\n this._opaqueRenderTarget.renderList = this._opaqueMeshesCache;\n this._opaqueRenderTarget.clearColor = this._options.clearColor?.clone() ?? this._scene.clearColor.clone();\n this._opaqueRenderTarget.clearColor.a = 0.0;\n this._opaqueRenderTarget.gammaSpace = false;\n this._opaqueRenderTarget.lodGenerationScale = this._options.lodGenerationScale;\n this._opaqueRenderTarget.lodGenerationOffset = this._options.lodGenerationOffset;\n this._opaqueRenderTarget.samples = this._options.samples;\n this._opaqueRenderTarget.renderSprites = true;\n this._opaqueRenderTarget.renderParticles = true;\n this._opaqueRenderTarget.disableImageProcessing = true;\n\n let saveSceneEnvIntensity: number;\n this._opaqueRenderTarget.onBeforeBindObservable.add((opaqueRenderTarget) => {\n saveSceneEnvIntensity = this._scene.environmentIntensity;\n this._scene.environmentIntensity = 1.0;\n if (!this._options.clearColor) {\n this._scene.clearColor.toLinearSpaceToRef(opaqueRenderTarget.clearColor, this._scene.getEngine().useExactSrgbConversions);\n } else {\n opaqueRenderTarget.clearColor.copyFrom(this._options.clearColor);\n }\n opaqueRenderTarget.clearColor.a = 0.0;\n\n // For mixed MultiMaterial meshes, swap in the precomputed opaque-only\n // submesh array so translucent submeshes don't render into the opaque texture.\n const tlEntries = this._opaqueOnlySubMeshes.entries();\n for (let tlEntry = tlEntries.next(); !tlEntry.done; tlEntry = tlEntries.next()) {\n const mesh = tlEntry.value[0];\n const opaqueOnly = tlEntry.value[1];\n if (mesh.subMeshes) {\n this._savedSubMeshes.set(mesh, mesh.subMeshes);\n mesh.subMeshes = opaqueOnly;\n }\n }\n });\n this._opaqueRenderTarget.onAfterUnbindObservable.add(() => {\n this._scene.environmentIntensity = saveSceneEnvIntensity;\n\n // Restore the full submesh list after the opaque RT render\n const savedEntries = this._savedSubMeshes.entries();\n for (let savedEntry = savedEntries.next(); !savedEntry.done; savedEntry = savedEntries.next()) {\n savedEntry.value[0].subMeshes = savedEntry.value[1];\n }\n this._savedSubMeshes.clear();\n });\n\n // Update refraction textures on transparent and mixed meshes\n for (const mesh of this._transparentMeshesCache) {\n if (mesh.material) {\n this._classifyMeshMaterials(mesh);\n }\n }\n const mixedEntries = this._translucentMaterialIndices.entries();\n for (let mixedEntry = mixedEntries.next(); !mixedEntry.done; mixedEntry = mixedEntries.next()) {\n const mesh = mixedEntry.value[0];\n if (mesh.material) {\n this._classifyMeshMaterials(mesh);\n }\n }\n }\n\n /**\n * Dispose all the elements created by the Helper.\n */\n public dispose(): void {\n // Set the disposed flag first so any pending SetImmediate callbacks (from _addMesh)\n // are no-ops. Without this guard a deferred _classifyMeshMaterials call would stamp\n // a null _opaqueRenderTarget onto transmission materials after disposal.\n this._disposed = true;\n\n // Unregister scene-level observers so this helper stops reacting to mesh changes.\n this._newMeshObserver?.remove();\n this._removedMeshObserver?.remove();\n this._newMeshObserver = null;\n this._removedMeshObserver = null;\n\n // Remove per-mesh material-change observers for all tracked meshes.\n const allTracked = [...this._transparentMeshesCache, ...this._opaqueMeshesCache];\n for (const mesh of allTracked) {\n const observer = this._materialObservers[mesh.uniqueId];\n if (observer) {\n observer.remove();\n delete this._materialObservers[mesh.uniqueId];\n }\n }\n\n // Also remove any remaining observers that were registered before deferred\n // classification added their meshes to the caches.\n for (const mesh of this._scene.meshes) {\n const observer = this._materialObservers[mesh.uniqueId];\n if (observer) {\n observer.remove();\n delete this._materialObservers[mesh.uniqueId];\n }\n }\n\n this._materialObservers = {};\n\n this._scene._transmissionHelper = undefined;\n if (this._opaqueRenderTarget) {\n this._opaqueRenderTarget.dispose();\n this._opaqueRenderTarget = null;\n }\n this._transparentMeshesCache = [];\n this._opaqueMeshesCache = [];\n this._translucentMaterialIndices.clear();\n this._opaqueOnlySubMeshes.clear();\n this._savedSubMeshes.clear();\n }\n}\n\n/**\n * Ensures a TransmissionHelper exists on the scene and has all of the loader's material\n * implementations registered with it. Creates the helper if one does not yet exist on the\n * scene, and recreates its render target if it has been disposed. Does nothing when the\n * loader's parent has `dontUseTransmissionHelper` set.\n * @param loader The glTF loader whose material implementations should be registered\n * @param babylonMaterial A material belonging to the scene where the helper should live\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function ensureTransmissionHelper(loader: GLTFLoader, babylonMaterial: Material): void {\n if (loader.parent.dontUseTransmissionHelper) {\n return;\n }\n const scene = babylonMaterial.getScene() as unknown as ITransmissionHelperHolder;\n const existingHelper = scene._transmissionHelper;\n const helper = existingHelper ?? new TransmissionHelper({}, babylonMaterial.getScene());\n for (const impl of Array.from(loader._pbrMaterialImpls.values())) {\n helper.addMaterialImpl(impl);\n }\n if (existingHelper && !existingHelper._isRenderTargetValid()) {\n existingHelper._setupRenderTargets();\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@babylonjs/loaders",
3
- "version": "9.10.1",
3
+ "version": "9.11.0",
4
4
  "main": "index.js",
5
5
  "module": "index.js",
6
6
  "types": "index.d.ts",
@@ -18,10 +18,10 @@
18
18
  "postcompile": "build-tools -c add-js-to-es6"
19
19
  },
20
20
  "devDependencies": {
21
- "@babylonjs/core": "9.10.1",
21
+ "@babylonjs/core": "9.11.0",
22
22
  "@dev/build-tools": "^1.0.0",
23
23
  "@dev/loaders": "^1.0.0",
24
- "babylonjs-gltf2interface": "9.10.1"
24
+ "babylonjs-gltf2interface": "9.11.0"
25
25
  },
26
26
  "peerDependencies": {
27
27
  "@babylonjs/core": "^9.0.0",