Skip to content

TSL: onDispose listeners on PMREM textures grow indefinitely #31866

@shotamatsuda

Description

@shotamatsuda

Description

Very similar to #31600, the event listeners on PMREMNode's dispose event grow indefinitely. webgpu_cubemap_dynamic also reproduces this issue.

The code in question would be https://github.com/mrdoob/three.js/blob/r180/src/renderers/common/Textures.js#L349, which unconditionally adds event listener without checking whether it has already been added.

This prevents WebGPURenderer from running for more than an hour, because it has a significant impact on frame performance (presumably due to operations on a very large array in EventDispatcher).

Reproduction steps

  1. Open webgpu_cubemap_dynamic in Chrome (it should also reproduce in other browsers).
  2. Open the developer console, and select the “Memory” tab.
  3. After running it for a few minutes, take a heap snapshot, navigate to Array > Array, sort by "Retained Size", and look the top entries (first and second).

Code

A minimal reproduction follows. You can inspect the leak in the same steps as above.

const cubeRT = new WebGLCubeRenderTarget(64)
const cubeCamera = new CubeCamera(1, 1000, cubeRT)
const cubeScene = new Scene()
const material = new MeshStandardNodeMaterial({
  envMap: cubeRT.texture
})

const mesh = new Mesh(new PlaneGeometry(), material)
const camera = new PerspectiveCamera()
const scene = new Scene().add(mesh)

void renderer.setAnimationLoop(() => {
  cubeCamera.update(renderer, cubeScene)
  void renderer.render(scene, camera)
})

Live example

https://jsfiddle.net/shotamatsuda/0Lfvz3yt/ (this directly counts the number of listeners)

Screenshots

No response

Version

r180

Device

Desktop

Browser

Chrome

OS

MacOS

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions