<script>
const imgData = `data:image/png;base64,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`;
</script>
<div id="info"></div>
<script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
body{
overflow: hidden;
margin: 0;
}
#info {
position: absolute;
color: white;
font-family: Arial;
}
import * as THREE from "https://threejs.org/build/three.module.js";
import { OrbitControls } from "https://threejs.org/examples/jsm/controls/OrbitControls.js";
let fft = [];
let data1;
let data2;
let data3;
const lineMaterial = new THREE.LineBasicMaterial({ color: 0x0000ff });
$.get({
url: 'https://files.wnology.io/5fd77c0d33491f0006da9de8/ThreeJS/docs/temp/1620291600000-144f8cf0ddf47a2d6676017480e6794f.json',
async: false
}, function(data) {
data1 = data
});
$.get({
url: 'https://files.wnology.io/5fd77c0d33491f0006da9de8/ThreeJS/docs/temp/1620291600000-4b685a1eaa1bb5cd30ff2a2f0627d221.json',
async: false
}, function(data) {
data2 = data
});
$.get({
url: 'https://files.wnology.io/5fd77c0d33491f0006da9de8/ThreeJS/docs/temp/1620291600000-96a43a9c906b2c173bda688c0afb6cd2.json',
async: false
}, function(data) {
data3 = data
});
fft.push(data1)
fft.push(data2)
fft.push(data3)
fft.push(data1)
fft.push(data2)
fft.push(data3)
fft.push(data1)
fft.push(data2)
fft.push(data3)
fft.push(data1)
console.log(fft)
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);
let light = new THREE.DirectionalLight(0xffffff, 1);
light.position.setScalar(1);
scene.add(light, new THREE.AmbientLight(0xffffff, 0.75));
createAGrid()
let g = new THREE.BoxGeometry();
g.translate(0, 0.5, 0);
let m = new THREE.MeshLambertMaterial({
onBeforeCompile: shader => {
shader.uniforms.lut = {
value: new THREE.TextureLoader().load(imgData)
}
shader.vertexShader = `
varying float vCurrHeight;
${shader.vertexShader}
`.replace(
`#include <worldpos_vertex>`,
`
#include <worldpos_vertex>
vCurrHeight = (instanceMatrix * vec4( transformed, 1.0 )).y;
`
);
shader.fragmentShader = `
uniform sampler2D lut;
varying float vCurrHeight;
${shader.fragmentShader}
`.replace(
`vec4 diffuseColor = vec4( diffuse, opacity );`,
`
float h = clamp(vCurrHeight / 30., 0., 1.);
vec3 col = texture(lut, vec2(0.3, h)).rgb;
vec4 diffuseColor = vec4( col, opacity );
`
);
//console.log(shader.fragmentShader)
}
});
let rows = fft.length;
let cols = 1008;
let factor = 300
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++) {
for (let x = 0; x < cols; x++) {
dummy.position.set(0, 0, (rows - 1) / 2 - y).multiplyScalar(20);
dummy.position.set(-(cols - 1) / 2 + x, 0, dummy.position.z)
dummy.position.set(dummy.position.x, dummy.position.y, dummy.position.z).multiplyScalar(0.243);
let hData = fft[y][x].a
dummy.scale.set(0.25, hData * factor, 0.25);
dummy.updateMatrix();
o.setMatrixAt(y * cols + x, dummy.matrix);
}
}
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/factor}`;
} 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 createAGrid(opts) {
var gridXZ = new THREE.GridHelper(250, 6)
gridXZ.scale.set(1, 0.5, 0.25);
scene.add(gridXZ);
var gridXY = new THREE.GridHelper(250, 6);
gridXY.position.z = -31, 25
gridXY.position.y = 125
gridXY.rotation.x = Math.PI / 2;
scene.add(gridXY);
var gridYZ = new THREE.GridHelper(250, 3);
gridYZ.position.x = -125
gridYZ.position.y = 125
gridYZ.rotation.z = Math.PI / 2;
gridYZ.scale.set(1, 1, 0.25);
scene.add(gridYZ);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.