Efficient rendering of 3d data

Last year I created a program that could render data from a spectrum analyzer in 3d:

It worked well, but was limited to about 112x125 as each cube was its own game object… I say cube, but technically they are cubes that have been scaled vertically according to the intensity of the data point. Anyway, if I expanded the history to 112x225 (another 100 data points in time), then it would slow to about 25 fps, and the stats indicated that the CPU thread was around 38ms or so…

So my question has to do with how to render more data, but also keep the fps decent.

I know it is possible to (in theory) combine game objects under a single mesh, however, I would still like to be able to color each cube according to its intensity. In other words, they are not only scaled, but colored, according to the value of the data point. So, does mesh optimization still work in this case? And, I would also still like (if possible) to be able to perform ray intersection testing of each cube so that I can show the user the amplitude of the data point associated with that cube, as well as highlighting it in yellow (as shown in the video).

Is optimization possible or do I basically still need to keep each data point as its own game object in order to achieve the above requirements? What’s interesting is that Unity indicates that there are not that many draw calls (only about 20) because it managed to save like 5000 due to batching… But, still, the CPU thread is still quite high.

Any thoughts or ideas?

112x225 that is 14k meshes scalling / modifications per frame.
Probably you could reduce that by spreading computation across few frames.
Most likely wont be noticeable by user anyway.

Another approach, if yo uwant to deal with large amount of dynamic data, is to look into Jobs Systems.
And even better into ECS.
Basically look for DOTS.

Edit:
Actually I have noticed on vid, you just modify (scale) one row at the time right?
Just moving other rows (pushing).
So yo just need compute 14k cells, 112x225 grid, checking for collision.
But that seems works fine on your vid.

Either way, jobs and multithreading can be to the rescue.

Maybe look at Unity - Scripting API: Graphics.DrawMeshInstancedIndirect too.

There is an example script.

1 Like

Antypodish,

Actually, when I originally developed it, it was quite slow because I was moving all the rows and setting a row for the new data (sweep).

But then, I changed it where I actually kept all the rows in the same position, except for the last row, which I moved to the front. To make this work such that it seemed stationary, I then moved the camera. So kind of a hack, but it works, as only a single row has to be moved on each update.

Anyway, I’m not sure if ECS is the solution or not… But I was wondering if there was a mesh optimization technique that would still allow for the ray intersection testing on each cube, or at minimum, allow me to keep each cube colored uniquely.

ECS could be good option.
But before then, you can look into Job and Burst.
Also as @richardkettlewell appointed at DrawMeshInstancedIndirect as another option.
But then you will need work a bit more with shaders.