<div id="info"></div>
body{
  overflow: hidden;
  margin: 0;
}

#info {
  position: absolute;
  color: white;
  font-family: Arial;
}
console.clear();

import * as THREE from "https://threejs.org/build/three.module.js";
import {OrbitControls} from "https://threejs.org/examples/jsm/controls/OrbitControls.js";
import {BufferGeometryUtils} from "https://threejs.org/examples/jsm/utils/BufferGeometryUtils.js";

let scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 1000);
camera.position.set(-100, 100, 150);
let renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);

const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2( 1, 1 );

let controls = new OrbitControls(camera, renderer.domElement);

scene.add(new THREE.GridHelper(250, 10));

let light = new THREE.DirectionalLight(0xffffff, 1);
light.position.setScalar(1);
scene.add(light, new THREE.AmbientLight(0xffffff, 0.75));

let g = new THREE.BoxGeometry();
g.translate(0, 0.5, 0);
let m = new THREE.MeshLambertMaterial();

let rows = 50;
let cols = 125;
let c1 = new THREE.Color(0, 0.5, 1);
let c2 = new THREE.Color(0.5, 0, 1);
let c = new THREE.Color();

let o = new THREE.InstancedMesh(g, m, rows * cols);

let dummy = new THREE.Object3D();
let mat4 = new THREE.Matrix4();
for(let y = 0; y < rows; y++){
  let factor0 = y * 0.1;
  let factor1 = Math.random();
  for(let x = 0; x < cols; x++){
    
    dummy.position.set(-(cols - 1) / 2 + x,0, (rows - 1) / 2 - y).multiplyScalar(2);
    
    let hData = Math.random() * 0.05 + 0.005 + Math.max(Math.abs(Math.sin(x * 0.012 * 2)*factor0)-factor1,0);
    
    dummy.scale.set(1.5, Math.pow(hData, 3) ,1.5);
    dummy.updateMatrix();
    o.setMatrixAt(y * cols + x, dummy.matrix);
    
    o.setColorAt(y * cols + x, c.lerpColors(c1, c2, hData))
  }
}

scene.add(o);

window.addEventListener( 'resize', onWindowResize );
document.addEventListener( 'mousemove', onMouseMove );

renderer.setAnimationLoop( _ => {
  
  raycaster.setFromCamera( mouse, camera );

  const intersection = raycaster.intersectObject( o );

  if ( intersection.length > 0 ) {

    info.style.display = "block";
    const instanceId = intersection[ 0 ].instanceId;

    o.getMatrixAt(instanceId, mat4);
    mat4.decompose(dummy.position, dummy.quaternion, dummy.scale);
    
    info.innerText = `data: ${dummy.scale.y}`;

  }
  else {
    info.style.display = "none";
  }
  
  renderer.render(scene, camera);
})

function onMouseMove( event ) {

  event.preventDefault();
  
  info.style.transform = `translate(${event.clientX + 15}px, ${event.clientY + 5}px)`;
  
  mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
  mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;

}

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.