lume / three-meshline

Mesh-based replacement for `THREE.Line` to allow lines thicker than 1 pixel and other features.
https://docs.lume.io/three-meshline/
MIT License
42 stars 4 forks source link

come up with a more efficient way to update points #2

Open trusktr opened 1 year ago

trusktr commented 1 year ago

line.setPoints re-creates a bunch of stuff each time, lots of garbage collection. GPU upload during renderer.render is also slow.

trusktr commented 1 year ago

These two commits were obvious performance improvements:

38d768dc24702a2c132e504b7a2bcd730d3552bc c49246e803cd37a764824beaacdd93b9a22c0b2d

setPoints performance was greatly improved in commit bb5bf8ef8aed6e675839ec72ab53b63f58bc7108, making it as fast as possible, copying data from the passed-in array directly to the internal GPU attribute arrays without allocating any new buffers if the number of points hasn't changed (avoids allocation and garbage collection cost of repeatedly updating points).

Although the setPoints speeds is a lot faster, the GPU upload in three's WebGLRenderer.render calls is still quite slow, especially for lines with lots of points.

The mem use for a line with n points (3n floats) is currently 28n floats and 6n short ints, meaning a line with 1000 points allocates roughly 28,000 floats plus 6000 shorts. Essentially ~O(34n), which is considerably high compared to drawing a regular WebGL line (THREE.Line) of O(3n) floats, where 1000 points means 3000 floats. Mesh lines are currently 11 times bigger (give or take)!

Can we improve the shader so that we don't need to pass in so much data?

trusktr commented 1 year ago

This commit, 70bbcd12253be187c8957adaf94e00f548b6743a, provides a huge gain by avoiding GPU uploads for certain buffers when point count hasn't changed, and by making expensive bounds updates optional so they can be skipped when not needed