Hi,
I’m trying to generate some ducks in a row using an InstancedMesh of the duck glTF (I started this example using the damaged helmet example but I’m hoping to create an arcade style game). I’m getting the necessary draw calls (3) and the increase in the triangle count of 1,000 = 4,210,000 triangles, but I’m unfortunately not able to see the ducks. All of this works just fine outside of the loop, but once the instanceMesh is added inside of the loop, the duck model(s) disappear. Any suggestions?
Your help would be greatly appreciated!
import "./style.css";
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader.js";
let container, controls;
let camera, scene, renderer;
init();
render();
function init() {
container = document.createElement('div');
document.body.appendChild(container);
scene = new THREE.Scene();
const axesHelper = new THREE.AxesHelper(20);
scene.add(axesHelper);
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.01, 1000);
camera.position.set(48, 30, -48);
new RGBELoader()
.setDataType(THREE.UnsignedByteType)
.load('/textures/environmentMaps/royal_esplanade_1k.hdr', (texture) => {
var envMap = pmremGenerator.fromEquirectangular(texture).texture;
scene.environment = envMap;
// After cube textures are generated, then this can be disposed of.
texture.dispose();
pmremGenerator.dispose();
render();
const dummyObject = new THREE.Object3D();
let count = 1000;
let xDistance = 5;
let zDistance = 5;
let xOffset = 1;
var loader = new GLTFLoader();
loader.load('/models/glTF/Duck.glb', (gltf) => {
gltf.scene.traverse(function (child) {
if (child.isMesh) {
const instancedMesh = new THREE.InstancedMesh(child.geometry, child.material, count);
instancedMesh.setMatrixAt(0, dummyObject.matrix);
// Iterate from here:
for (let i = 0; i < count; i++) {
for (let j = 0; j < count; j++) {
instancedMesh.position.x = i;
instancedMesh.position.z = j;
instancedMesh.position.x = xDistance * i + xOffset;
instancedMesh.position.z = zDistance * j;
instancedMesh.setMatrixAt(i + j * count, dummyObject.matrix);
instancedMesh.scale.x = 10;
instancedMesh.scale.y = 10;
instancedMesh.scale.z = 10;
instancedMesh.rotation.y = THREE.Math.degToRad(0);
instancedMesh.rotation.x = THREE.Math.degToRad(90);
instancedMesh.rotation.z = THREE.Math.degToRad(-90);
scene.add(instancedMesh);
instancedMesh.matrix.needsUpdate = true;
}
}
}
});
render();
});
});
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.physicallyCorrectLights = true;
renderer.outputEncoding = THREE.sRGBEncoding;
renderer.toneMapping = THREE.ReinhardToneMapping;
renderer.toneMappingExposure = 1;
container.appendChild(renderer.domElement);
var pmremGenerator = new THREE.PMREMGenerator(renderer);
pmremGenerator.compileEquirectangularShader();
controls = new OrbitControls(camera, renderer.domElement);
controls.addEventListener('change', render);
controls.minDistance = 5;
controls.maxDistance = 10000;
controls.update();
window.addEventListener('resize', onWindowResize, false);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
render();
}
function render() {
renderer.render(scene, camera);
}