Modified THREE.InstancedMesh dynamically instancecount

Hello everyone!
I need to be in THREE.InstancedMesh When I have created tens of thousands of instances, I need to dynamically crop and display the number of visible instances according to the camera cone. At present, the camera cone judgment has worked well, but there is a problem in dynamically modifying the number of instances Previously, using InstancedBufferGeometry to set the instanceCount property can dynamically control the number of current renderings. On InstancedMesh, I have tried to modify the updateRange of BufferAttribute. It seems that it doesn’t work properly. Is there any other API or how I can improve it?
Please help me!
Thank you very much!!!

Hi!
Are you looking for .count ?

1 Like

Sorry, maybe I didn’t describe it clearly! . count is the total number of all instances. I need to control the number of instances rendered to the screen again within this range, similar to the instancecount and _maxinstancecount properties of instancedbuffergeometry.

So, maybe makes sense to take a look at the source code of examples. For example, this one https://threejs.org/examples/?q=inst#webgl_instancing_dynamic (see that “count” slider at the top-right corner).

And what parameter changes in GUI:

I need to expand the rendering quantity like InstancedBufferGeometry!
The following code fragment is found in three:

var instanceCount = Math.min ( geometry.instanceCount , geometry._ maxInstanceCount );

        if ( object.isInstancedMesh ) {

			renderer.renderInstances( geometry, drawStart, drawCount, object.count );

		} else if ( geometry.isInstancedBufferGeometry ) {

			var instanceCount = Math.min( geometry.instanceCount, geometry._maxInstanceCount );

			renderer.renderInstances( geometry, drawStart, drawCount, instanceCount );

		} else {

			renderer.render( drawStart, drawCount );

		}

So, changing instancedMesh.count does exactly what you need.

Have a look at this example:

In the console, I logged its instanced mesh’s geometry, where you can see, that _maxInstanceCount is 10000 (and that’s correct, as I fill the attribute of matrices for instances in double loop 100 x 100), whereas you can instantiate the mesh like that: let o = new THREE.InstancedMesh(g, m, 345); and get _maxInstanceCount still 10000.

2 Likes

For example, I use Float32Array to open 10 instance memory. After that, I only need to sort the instances to be rendered to the front through setMatrixAt method and control the number of renderable instances (for example, there are 5 visible instances in the camera range). In this way, it is unnecessary to re create Float32Array every time. I think this will cause unnecessary memory consumption.

Yes, you don’t need to re-create it, as you set it once.
Do you re-create it?

When I set the . count property of InstancedMesh to fill the buffer, I notice that it draws all instances. However, I want to dynamically control the number of drawing instances. It is similar to the instanceCount property of InstancedBufferGeometry. When I extend InstancedMesh and add such attributes as instanceOpacity, modifying the updateRange of BufferAttribute seems to have no effect! I hope instancedmesh can add the same API as InstancedBufferGeometry.
like this:

    if ( object.isInstancedMesh ) {

            const instanceCount = Math.min( object.instanceCount, object.count );
       		renderer.renderInstances( drawStart, drawCount, instanceCount  );


   	} else if ( geometry.isInstancedBufferGeometry ) {

   		const instanceCount = Math.min( geometry.instanceCount, geometry._maxInstanceCount );

   		renderer.renderInstances( drawStart, drawCount, instanceCount );

   	} else {

   		renderer.render( drawStart, drawCount );

   	}

Keep in mind that InstancedMesh.count represents the maximum count of instances. You need to init the mesh with this number but can then alter the property to a lower value.

Buffers can not be resized! This is also true for InstancedBufferGeometry. Hence, you always have to create buffers sufficiently sized and then select the range you actually want to render.

2 Likes

Thank you. I understand it wrong! :smile:

1 Like

Got it, can’t increase the count, only lower it! otherwise, should create a new InstancedMesh

Thanks @Mugen87 :white_check_mark:

1 Like