Few questions how to improve performance in the current scenario

Hello everyone, I’m quite new to three.js, but I have some questions I couldn’t find answers to. So I decided to ask them.
I’m looking for a way how to improve performance here

I have an application where the user can add and drag a box, and there are also relationships between boxes are indicated by lines. It uses three.js but in reality, it’s a mostly 2D scene. I’m using OrthographicCamera here.

It works fine with a small amount of boxes, but displaying hundreds or even thousands of them is killing my laptop.

I read few articles on how to improve performance in three.js app and so far what I already did:

  1. all boxes share the same geometry
  2. everything reuses the predefined set of meshBasicMaterial
  3. all line arrows are rendered with the same geometry

So now the current render cycle is next:

  1. render all boxes.
  2. calculate the position for start and end and if required middle points for lines
  3. based on points create geometry for every line
  4. render lines with line arrows

questions I’m looking for answers to:

  1. I’m using the Line class to render lines, is it somehow possible to merge line’s Geometry and line arrow’s Geometry together? (I tried to make it, but failed, I was using mergeBufferGeometries function from BufferGeometryUtils class)

  2. In the app some lines are straight, some are not. Does it make sense to create a single Geometry for a line, share between straight lines, and scale when it is required? (as I can understand, it will require additional calculating for the position where to put the line in the scene)

  3. does the use of Vector2 will give any benefit over using Vector3 in my case?

  4. I was thinking about putting all lines in a single geometry, let’s call it AllLinesGeometry for reference (I read somewhere it will provide a single render call then), but during the drag’n’drop of the box, together with the box I also move the connected lines for this box. So during drag and drop it will require me to delete few lines from AllLinesGeometry, create the new one and render it again - AllLinesGeometry + few lines which user is dragging in this moment - does this one makes sense?
    I can imagine this will work the same way with boxes.

  5. And the last one but still important - Is there anything else I can do to improve performance there? Above is just something I found in the internet, but maybe here are also some unknown tips?

  1. Not rendering 1000s’ of boxes. :eyes: Are all boxes visible at any given time? If not, creating a simple 2D / 3D spatial index may help reducing the amount of things you render / update quite significantly. :thinking:
  1. That would likely prevent the line from being rendered using GL_LINES.
  1. If there’s no depth at all, otherwise it’d just complicate your code even more. :sweat_smile:
  1. While that does sound nice - it’d prevent point (1) from happening - and splitting your billions of lines into subsets / tiles will likely improve the performance more than putting them all in a single geometry for the entire scene. Same for boxes.

hey @mjurczyk thanks for answering, but I still have some questions :slight_smile:

  1. Oh nice, I was not familiar with this terminology, sounds like a good idea, thanks for sharing;
    the bad thing is that I want to show all things together for a user, but based on this it sounds like I can display simple or not all elements at a certain zoom level, and when the user zooms in → display all necessary details that fit a screen, sounds like a plan. :thinking:
  1. yeah, I mostly use z-index just to render some elements under the others, so they don’t overlap each other and not making some glitches
    but for example:
    would the creation of a curve line with SplineCurve from Vector2 and pass it to the BufferGeometry work faster than the creation of a curve line with CatmullRomCurve3 from Vector3 and pass it to the BufferGeometry? as I can assume at the end it will be the same Vector3 in the BufferGeometry
  1. read a few times to get into it. Sounds good.

The question, because I never did it before(just to make it clear here is a specific scenario - user drags a single line causing to change its geometry) - Do I understand correctly, that if I create a single geometry(name it subsetLinesGeometry) out of N lines, and when on drag start event I need to change the geometry of a single line from this N lines - that’s means I have to re-create a subsetLinesGeometry from N-1 lines and a separate line geometry for this single line which user drags? and on drag end event I have to re-create again the full subsetLinesGeometry of N lines with fresh new geometry of the dragged line?
Is there a way to delete a piece of geometry from the big geometry? I got a feeling that computation the new geometry from N-1 elements might take more time than just delete something from the already existing one. But I have absolutely no idea if it is even possible. - let me know if it is another topic for discussion.

Hello @ifozest,

Have you succeed in what you were trying to do ?
I have quite a similar need and I’d be glad to know how you managed your case (link to my problem:

a million … interactive lines, if you figure this out pls let me know :smiley:

1 Like

@teoav maybe something related to the part of your question on SO:

  • line: We could create only 1 geometry with all the turns inside. However, currently all my lines are linked (like if i was drawing them with a pen in one shot). More over, I do not think it is easily possible to manipulate a specific turn with this solution.

Have a look: Using NaN in attributes - #7 by prisoner849 (LineSegments + indexed geometry, non-interactive)

1 Like

Hey @teoav , unfortunately I didn’t succeed and after some investigations decided just limit the amount of information displayed to the user, I mean millions of line makes more questions rather than solve anything. Your case seems different, the only thing I can tell that Three.js Lines don’t work with InstancedMesh

1 Like

Thanks for the link, I missed this one ! It still remains the fact that I have to know how to make each part interactive when it’s only 1 Line but this is cool to see that we can draw the lines properly !

Btw, the fiddle you gave is broken. I will however try to implement this using r3f. Thanks!

Cheers for your return of experience !
Could you share with me how you are limiting the number of objects please ? Like, are you not showing the lines when you are zoomed out ?

Currently I think the best way is to create my own ‘line’ with a Box InstanceMesh !