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 ?
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.
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.
Thank you. I understand it wrong!
Got it, can’t increase the count, only lower it! otherwise, should create a new InstancedMesh
Thanks @Mugen87