KITASENJU DESIGN BLOG

memo, html, javascript, unity

InstancedMesh in Threejs

  • Please make a dummy object for updating matrices of InstancedMesh
  • Please code "mesh.instanceMatrix.needsUpdate = true;"
import { Mesh } from "three";
import * as THREE from 'three';
import { InstancedBall } from './InstancedBall';

export class InstancedBalls extends THREE.Object3D{

    NUM:number = 20;
    mesh:THREE.InstancedMesh;
    dummyObj:THREE.Object3D;
    list:InstancedBall[] = [];

    constructor(ballMesh:Mesh){

        super();

        this.dummyObj = new THREE.Object3D;
        this.add(this.dummyObj);

        for(let i=0;i<this.NUM;i++){
            
            let m = new InstancedBall();

            m.position.x = 400 * (Math.random()-0.5);
            m.position.y = 400 * (Math.random()-0.5);
            m.position.z = 400 * (Math.random()-0.5);

            this.list.push(m);
        }

        this.mesh = new THREE.InstancedMesh(
            ballMesh.geometry,
            ballMesh.material,
            this.NUM
        );
        this.add(this.mesh)

        /*
        for (let i = 0; i < count; i++) {
            dummy.position.set(offset - i, 0, 0)
            dummy.updateMatrix()
            mesh.setMatrixAt(i, dummy.matrix)
        }*/

    }


    update(): void {
        
        for(let i=0;i<this.NUM;i++){

            this.list[i].update();
            this.list[i].setTRS(this.dummyObj)
            this.dummyObj.updateMatrix();
            this.mesh.setMatrixAt(i, this.dummyObj.matrix)
            
        }
        this.mesh.instanceMatrix.needsUpdate = true;

    }



}
import * as THREE from 'three';

export class InstancedBall{

    position:THREE.Vector3;
    rotation:THREE.Vector3;
    scale:THREE.Vector3;
    rotSpd:THREE.Vector3;
    count:number=100*Math.random()
    basePos:THREE.Vector3 = new THREE.Vector3(0,0,0);

    constructor(){
        
        this.position   =new THREE.Vector3();
        this.scale      =new THREE.Vector3(0.3,0.3,0.3);
        this.rotation   =new THREE.Vector3(
            Math.random()*Math.PI*2,
            Math.random()*Math.PI*2,
            Math.random()*Math.PI*2
        );
        this.rotSpd = new THREE.Vector3(
            0.02*(Math.random()-0.5),
            0.02*(Math.random()-0.5),
            0.02*(Math.random()-0.5)
        )        

    }

    setTRS(obj:THREE.Object3D){

        obj.position.x = this.position.x;
        obj.position.y = this.position.y;
        obj.position.z = this.position.z;
        
        obj.scale.x = this.scale.x;
        obj.scale.y = this.scale.y;
        obj.scale.z = this.scale.z;
        
        obj.rotation.x = this.rotation.x;
        obj.rotation.y = this.rotation.y;
        obj.rotation.z = this.rotation.z;

    }

    update(){

        this.count+=0.005;
        //this.position.y = this.basePos.y+20*Math.sin(this.count)

        this.rotation.x+=this.rotSpd.x;
        this.rotation.y+=this.rotSpd.y;
        this.rotation.z+=this.rotSpd.z;

    }

}
"FOOTER"