You want to avoid creating objects in the render loop as much as possible, as they will be garbage collected at some point which can slow down the rendering.
Also note that creating a new line object for each line is inefficient. You could use a single geometry and material for all of them. The geometry would contain all the points, and you would need to create a vertex color attribute to hold the colors, then set verteColors: true in your material’s parameters.
I would create the whole geometry when you’re starting the application. In the update loop, increment the geometry’s draw range: this will let you progressively reveal new segments.
I researched that options, but still I can’t avoid creating objects in loop, because user can change spiral animation parameters in real-time, which includes coordinates and line width, hence I can’t use single geometry.
But what I do is, after drawing specific numbers of lines (300 for now), I delete all 300 of them and create one single geometry with different colors, and so on. The solution works better than my previous code which I have in the question above.
The problem is, sometimes animation slows down, and sometimes fastens. I tried using requestAnimationFrame, as well as setTimeout within the animate function.
Any ideas how to optimize the code ?
Here’s the website where I develop the app. You can check it out yourself : https://chakrulo-test.pulsarai.ge/
Just click upload to upload the audio file or start microphone recording and the animation will start.
You can modify a buffer geometry after it’s been created, by modifying the relevant attributes array and setting needsUpdate = true on the attribute. So there’s no need to create a new geometry for each line - this is probably where your performance issues are coming from.
There are two different scenarios:
the user uploads a file, in which case you know how long the audio lasts, so you can create all the geometry when the file is uploaded. For any changes to the users settings, update the corresponding geometry attributes.
the user records in real time, so you don’t know how long it will take. In that case, I would have a think about how long I would expect users to record for, then create a geometry that’s large enough to hold all the points for that duration. If the user exceeds that duration, either you reset the whole thing, or you create another large geometry that can be used for a reasonable amount of time, and repeat the process each time the user goes above the limit of data that can be held in your geometry.
For optimisation, you should avoid creating new objects in the render loop as much as possible. Try creating your vectors only once outside the render loop, and in the loop you just set them to the necessary value.
Don’t create a new material for each geometry as that’s a waste of resources. Instead, use a single LineMaterial with vertex colors enabled, and add a color attribute to your line geometry to hold each line’s colors.