<script type="importmap">

  {

        "imports": {

            "three": "https://cdn.jsdelivr.net/npm/three@0.132.0/build/three.module.js",

            "addons/": "https://cdn.jsdelivr.net/npm/three@0.132.0/examples/jsm/"

        }

    }

</script>
body {
  overflow: hidden;
  margin: 0;
}
import * as THREE from "three";

import { OrbitControls } from "addons/controls/OrbitControls.js";
import { GLTFLoader } from "addons/loaders/GLTFLoader.js";
let mesh;

const count = 100;

const dummy = new THREE.Object3D();

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 100);
camera.position.set(0, 5, 10);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);

var controls = new OrbitControls(camera, renderer.domElement);
var loader = new GLTFLoader();

var loader = new GLTFLoader().setPath(
  "https://threejs.org/examples/models/gltf/DamagedHelmet/glTF/"
);
loader.load("DamagedHelmet.gltf", function (geometry) {
  geometry.scene.traverse(function (child) {
    if (child.isMesh) {
      let material = new THREE.MeshBasicMaterial({ color: 0xff0000 });
      child.material = material;
      scene.add(geometry.scene);
      mesh = new THREE.InstancedMesh(child.geometry, child.material, count);
      mesh.instanceMatrix.setUsage(THREE.DynamicDrawUsage);

      for (let i = 0; i < count; i++) {
        dummy.position.set(
          (Math.random() * 2.0 - 1.0) * 80,
          500,
          (Math.random() * 2.0 - 1.0) * 80
        );

        dummy.rotation.y = 0 + Math.random();
        dummy.rotation.z = dummy.rotation.y * 2;

        dummy.updateMatrix();

        mesh.setMatrixAt(i++, dummy.matrix);
      }
    }
  });

  // check overdraw
});

scene.add(new THREE.GridHelper());

var clock = new THREE.Clock();
var camPos = new THREE.Vector3().copy(camera.position);
var camShift = new THREE.Vector3();
var isFree = true;
var t = 0;
document.addEventListener("mousedown", (event) => {
  isFree = false;
});

document.addEventListener("mouseup", (event) => {
  isFree = true;
  t = 0;
  camPos.copy(camera.position);
});

renderer.setAnimationLoop(() => {
  t += clock.getDelta();
  if (isFree) {
    camShift
      .set(Math.cos(t + Math.PI * 2), Math.sin(t), Math.cos(t + Math.PI * 2))
      .multiplyScalar(0.3);
    camera.position.addVectors(camPos, camShift);
    controls.update();
  }
  renderer.render(scene, camera);
});
window.addEventListener("resize", onWindowResize, false);
function onWindowResize() {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
}
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.