THREE.js Mutating vertices of Plane according to Data from mp3

222 Views Asked by At

So i've been stuck for a while because i've been having trouble dynamically changing the shape of the vertices in a place geometry according to the frequency data of an mp3, I've been having 2 main problems:

1)The array generated by the mp3 has too many values and it is impossible to render out the vertices that fast and accordingly, i am getting the frequency data with this code.

var frequencyData = new Uint8Array(analyser.frequencyBinCount);

2) Re-Rendering the plane everytime frequencyData changes causes extreme performance issues to the point it does not render out anymore

I've been using simplex noise to cause the vertices to morph, and it does work until obviously i pass in frequency data and everything breaks, this is the code i'm trying to use to morph the vertices of the plane according to the music.

function adjustVertices() {

      for (var i = 0; i < 100; i++) {
          for (var j = 0; j < 100; j++) {
              var ex = 0.5;
              pgeom.vertices[i + j * 100].z =
                  (noise.simplex2(i / 100, j / 100) +
                      noise.simplex2((i + 500) / 50, j / 50) * Math.pow(ex, frequencyData[2]) +
                      noise.simplex2((i + 400) / 25, j / 25) * Math.pow(ex, frequencyData[2]) +
                      noise.simplex2((i + 600) / 12.5, j / 12.5) * Math.pow(ex, frequencyData[2]) +
                      +(noise.simplex2((i + 800) / 6.25, j / 6.25) * Math.pow(ex, frequencyData[2]))) /
                  2;
              pgeom.verticesNeedUpdate = true;
              pgeom.computeVertexNormals();
          }
      }

  }

This is my plane object:

var pgeom = new THREE.PlaneGeometry(5, 5, 99, 99);
 var plane = THREE.SceneUtils.createMultiMaterialObject(pgeom, [
 new THREE.MeshPhongMaterial({
  color: 0x33ff33,
  specular: 0x773300,
  side: THREE.DoubleSide,
  shading: THREE.FlatShading,
  shininess: 3,
}),
]);



 scene.add(plane);

I am very grateful for the help, I am just doing my best in mastering three.js :)

2

There are 2 best solutions below

0
On

I would check if the computeVertexNormals is what is taking the most time in that render loop, and then look into optimizing it, if you still require it.

You can optimize the normal calculation by building the mesh topology once at startup, since it doesn't change at runtime, making the recalc run in constant time.

Then reduce the vertex count until things become manageable. :)

2
On

The first answer is correct. Most likely computing vertex normals is causing the hit, and it's most likely happening because the Geometry method which you seem to be using creates a lot of new THREE.Vector3. If you profile this i imagine you'd see a lot of GC activity and not so much of computation time.

One more thing to consider since you only map one variable, is to move this computation in the shader. You could write your values to a texture and only update that. You would not have to refresh the vertex and normal buffers which are much larger than the texture you'd need to store just the input variable. You would also be able to do this computation in parallel.