# glTF KHR\_materials\_transmission: TransmissionHelper outlives the asset that created it

**URL:** <https://forum.babylonjs.com/t/gltf-khr-materials-transmission-transmissionhelper-outlives-the-asset-that-created-it/64499>\
**Category:** Bugs\
**Created:** [November 2, 2026, 1:15pm UTC](https://forum.babylonjs.com/t/gltf-khr-materials-transmission-transmissionhelper-outlives-the-asset-that-created-it/64499 "2026-11-02T13:15:03Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![picitujeromanov](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/picitujeromanov/32/52378_2.png) [@picitujeromanov](https://forum.babylonjs.com/u/picitujeromanov)\
**Post date:** [November 2, 2026, 1:15pm UTC](https://forum.babylonjs.com/t/gltf-khr-materials-transmission-transmissionhelper-outlives-the-asset-that-created-it/64499/1 "2026-11-02T13:15:03Z")

</div>

Babylon.js 9.29.0 (`@babylonjs/core` + `@babylonjs/loaders`).

Loading a glTF with a `KHR_materials_transmission` material creates a scene-wide `TransmissionHelper` (`ensureTransmissionHelper`, stored on `scene._transmissionHelper`). It is only disposed with the scene (`scene.onDisposeObservable`).

Our app swaps glTF sets in one scene. After disposing every mesh and material the asset created, the helper is still there:

- its opaque render target (1024 px, 4× MSAA by default) stays allocated;
- its `onNewMeshAddedObservable` / `onMeshRemovedObservable` observers keep classifying every mesh added later, so the next set’s meshes go into its opaque cache.

There’s no public way to release it short of disposing the scene. The only handle is the internal `scene._transmissionHelper`, which we dispose ourselves on unload.

Could the helper be disposed when its last transmissive material is disposed, or be exposed (or given a dispose call) publicly?

**Repro:** load a glTF with `KHR_materials_transmission`; dispose every mesh and material it created; `scene._transmissionHelper` is still set with its render target allocated; load another glTF without glass, and its meshes are added to the helper’s opaque mesh cache.

---

<div class="post-metadata">

**Author:** ![Evgeni\_Popov](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/evgeni_popov/32/4432_2.png) [@Evgeni\_Popov](https://forum.babylonjs.com/u/Evgeni_Popov)\
**Post date:** [November 2, 2026, 2:35pm UTC](https://forum.babylonjs.com/t/gltf-khr-materials-transmission-transmissionhelper-outlives-the-asset-that-created-it/64499/2 "2026-11-02T14:35:26Z")

</div>

Thanks for reporting this. You’re right: the helper is shared at the scene level, and its automatic cleanup currently happens only when the scene is disposed. Disposing the imported meshes and materials removes those meshes from its caches, but does not dispose the helper or unregister its scene observers.

Disposing it when the last material using it is disposed sounds like a sensible improvement. We would need to track its consumers across imports, since unloading one asset must not break transmission on another asset in the same scene. The same applies to `KHR_materials_diffuse_transmission`, which uses this helper too.

For now, calling `scene._transmissionHelper?.dispose()` after disposing **all** materials that depend on it is a reasonable workaround, although it relies on an internal API. A subsequent glTF load requiring transmission will recreate the helper.

One nuance: the retained helper does not necessarily mean an additional render pass continues every frame once all transmissive materials are gone. However, the retained resources and mesh-observer activity you describe are real lifecycle issues.
