Ok so I added instanced geometry to my scene in 4 x 4 tiles. Each tiles 30 trees and the tree is composed of two meshes. That means that I would get 32 draw calls if all the trees are in the cameras view. I didn’t want to render 480 trees if they were behind me so that’s why I split them up into 16 tiles on the map. This would reduce the draw calls from 15,360, to 32.
The problem is that the renderer always says that I have 32 draw calls even when I face none of the trees. For some reason the instanced mesh from this module doesn’t seem to be tested if it’s in the camera’s view. Am I doing something wrong or is the module handling the meshes incorrectly.
function loadSnubTrees() {
//add trees
loader.load( "/models/tree_snub_trunk.glb",
// called when the resource is loaded
function ( gltf ) {
let nodeTree = gltf.scene.children[2].children;
let materials = [];
let geometries = [];
nodeTree.forEach(node => {
if(node instanceof THREE.Mesh) {
node.castShadow = true;
materials.push(node.material);
geometries.push(node.geometry);
}
});
for(let row = 0; row < 4; row++) {
for(let col = 0; col < 4; col++) {
const position = getPositions(-100 + (col * 50), -100 + (row * 50));
for(let index = 0; index < geometries.length; index++) {
addCluster(geometries[index], materials[index], 50, position);
}
}
}
});
}
function addCluster(geometry, material, count, positions) {
geometry.rotateX(Math.PI / 2);
//the instance group
var cluster = new THREE.InstancedMesh(
geometry, //this is the same
material,
count, //instance count
false, //is it dynamic
false, //does it have color
true, //uniform scale, axis' are scaled proportionally --> +Performance
);
cluster.castShadow = true;
var _v3 = new THREE.Vector3();
var _q = new THREE.Quaternion();
for ( var i = 0 ; i < count ; i ++ ) {
cluster.setQuaternionAt( i , _q );
cluster.setPositionAt( i , _v3.set( positions[i] , -1.3, positions[i + 1]) );
cluster.setScaleAt( i , _v3.set(1,1,1) );
}
//remove our alterations
geometry.rotateX(-Math.PI / 2);
scene.add( cluster );
}
function getPositions(startX, startZ, tileSize = 50, count = 30) {
let positions = [];
//count is how many x, z, coordinate pairs we want returned
for(let coord = 0; coord < count; coord++) {
positions.push(Math.random() * tileSize + startX);
positions.push(Math.random() * tileSize + startZ);
}
return positions;
}
Any help is appreciated!