question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

geometry._maxInstanceCount is not cleared on dispose

See original GitHub issue
Description of the problem

The BufferGeometry._maxInstanceCount property is set by internal renderer code in WebGLBindingStates.js, but this property is not cleared when calling dispose() on the geometry.

As this property seems to be used internally the renderer to cache this value, I feel as though it should also be cleared on dispose().

The change that added this property broke a buffer resizing technique that I had been using to implement resizeable buffers for ThreeJS without needing to know or allocate a max buffer size beforehand.

The main part of my implementation that broke was something like the following:

const geometry = new THREE.InstancedBufferGeometry();

const data = new Float32Array(1, 2, 3, 4, 5, 6);
const attribute = new THREE.InstancedBufferAttribute(data, 3);
geometry.setAttribute("attributeName", attribute);

// Other attributes, like position and index are added
// Geometry is added to a mesh and to the scene etc.

// Render the geometry somewhere in the rendering loop at least once
renderer.render(scene, camera);

// geometry._maxInstanceCount now has a value.

// To resize the geometry, I dispose of it first to remove it fully from the renderer's memory
// and re-use it as though it's a fresh geometry. This means I don't need to fully re-create
// the object, but the renderer will treat it as though it's a completely new geometry.
geometry.dispose();
// Problem: geometry._maxInstanceCount is still set.

attribute.array = new Float32Array(1, 2, 3, 4, 5, 6, 7); // Array size increased by 1
attribute.count = attribute.array.length / attribute.itemSize;

// Next render loop, the renderer should be treating the geometry as though it's never seen it before
// as I've called dispose on it. The problem is, geometry._maxInstanceCount still has a 
// value that will be used in WebGLRenderer.js, and the incorrect number of instances will be rendered.

I’m not sure if ThreeJS is not designed to support this usage pattern, but I feel as though it’s acceptable given the renderer should not retain any information about the geometry after dispose() is called. As far as the renderer is concerned, it’s being passed an entirely new geometry with entirely new buffers.

Unfortunately, the geometry._maxInstanceCount property isn’t cleared and this use case breaks.

I’m happy to write a more complete fiddle illustrating this problem when I get the chance 😃

Three.js version
  • Dev
  • r117
Browser
  • All of them
  • Chrome
  • Firefox
  • Internet Explorer
OS
  • All of them
  • Windows
  • macOS
  • Linux
  • Android
  • iOS

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:1
  • Comments:13 (6 by maintainers)

github_iconTop GitHub Comments

2reactions
Mugen87commented, Jun 23, 2020

Damn, I forgot this section…Well, even if I don’t like this approach (I personally think reusing geometries is a misusage) it should be possible to delete _maxInstanceCount in onGeometryDispose().

1reaction
WestLangleycommented, Jun 24, 2020

Trails are initially allocated with a small number of points, and the allocation size doubles whenever a new point is added that pushes the line over its current allocation size.

OK, good!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Cannot dispose of unwanted geometry in three.js application
The problem is that even though myGroup has been removed from the scene, console logging shows the geometries are not being removed from...
Read more >
How to dispose of objects – three.js docs
It's important to highlight that these objects are not released automatically. ... These entities are only deleted if you call BufferGeometry.dispose().
Read more >
Implement a Dispose method - Microsoft Learn
The .NET garbage collector does not allocate or release unmanaged memory. The pattern for disposing an object, referred to as the dispose ......
Read more >
About “Chart was not disposed” warning - amCharts
Now, suppose the contents of the chart container <div> are cleared out for some reason. It could happen for a number of reasons,...
Read more >
How to Properly Dispose Of Resources In .Net Core - Medium
Assuming you're not directly using unmanaged code, the resources will still be cleaned up but: a) It won't happen immediately, and your ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found