Keqiang Li Keqiang Li - 8 days ago 6
Javascript Question

Three.js to visualize 3 slices of heatmaps in 3D space

I'm trying to use Three.js to visualize a 3D matrix. For each 2D plane, I want the visualization to be a 2D heatmap, it will look like:

Each plane can slide to show different slice of the matrix

Users can drag each plane to show different slice of the matrix. The problem I'm having now is I can't find the best way in Three.js to visualize it. I drew each cell in the heatmap individually as a squre and color it. However, when the size of the matrix gets really huge, say 100000 * 500 * 200, it's very sluggish to draw.

I'm very new to 3D and Three.js. I looked into some examples and it seems to me that Three.js can actually visualize a huge amount of data by using particle system but I'm not sure how exactly I should utilize it. Some examples I found online didn't work for the latest version of Three.js.

Other requirements are to enable users to zoom, rotate and pan over the visualization.

A good example I found is http://www.georgeandjonathan.com/#1. At the end of the song, it has visualized a long sequence of data and you can rotate to see even the very beginning.

In short, my question is what techniques are available in three.js that I can use to visualize such plot, considering the size.

Thanks.

Answer

After I went over couple of examples, it looks like using THREE.Points constructed by a BufferGeometry and a PointsMaterial is sufficient to visualize the heatmaps.

var PARTICLE_SIZE = 15;
var geometry = new THREE.BufferGeometry();
var material = new THREE.PointsMaterial({
    size:PARTICLE_SIZE;
    , vertexColors: THREE.VertexColors
});

var rowNumber = 200, columnNumber = 10000;
var particleNumber = rowNumber * columnNumber;
var positions = new Float32Array(particleNumber * 3);
var colors = new Float32Array(particleNumber * 3);
for (i = 0; i < rowNumber; ++i) {
    for (j = 0; j < columnNumber; ++j) {
        var index = (i * columnNumber + j) * 3;

        // put vertices on the XY plane
        positions[index] = rowIndex * PARTICLE_SIZE;
        positions[index + 1] = columnIndex * PARTICLE_SIZE;
        positions[index + 2] = 0;

        // just use random color for now
        colors[index] = Math.random();
        colors[index + 1] = Math.random();
        colors[index + 2] = Math.random();
    }
}
// these attributes will be used to render the particles
geometry.addAttribute('position', new THREE.BufferAttribute(positions, 3));
geometry.addAttribute('color', new THREE.BufferAttribute(colors, 3));
var particles = new THREE.Points(geometry, material);
scene.add(particles);

There is one problem I haven't figured out yet, that is all the particles are facing towards the camera all the time. When the heatmap is rotated, these particles will always face you thus the whole plane is direction is changed. I will post my update when I find a solution.