I have implemented the suggestion by Roland Melkert with VBO's as he wrote above (draw this VBO here, there and there) in order to see if there would be any benefits when doing this with three.js.
The initial results were some really hairy models:
Joke aside (although that was actually the result after the first code rewrite). To use VBO's with three.js boils down to reusing 'Mesh' objects. I have decided to build one mesh for each part in color '16. A model using a certain part with different colors will thus only use (and reuse) a single VBO. The color handling is performed in custom shaders.
If you remember some of my first posts in this thread, you might think "This sounds familiar... isn't this what you did before bringing down the space usage and improving the render time?" and you would be right.
So what has changed?
Well. Pretty much the whole code base. By using the tricks from all the other posts (such as reusing points and using custom shaders), the memory usage is being kept under control. Performance is similarly improved by the following two improvements:
Bottom-up Constructions of Parts
I am now building the parts "bottom-up" in order to improve reusability of points. Previously a part, such as 3001 would be built like this:
Build 3001.dat by first building all line types 2, 3, 4 and 5. Then built each primitive (line type 1), such as stud.dat the same way.
Finally sort all the points collected for 3001.dat in order to reuse those that overlap.
Now parts are built like this:
First built all primitives without any inner primitives (such as 4-4edge.dat, which only consists of 16 normal lines). Sort the points of the primitives immediately.
Then built all primitives that only depend on the primitives that have been built. The effort used by sorting is now reduced since the other primitives already have their points sorted.
Continue until all parts are built.
The improvements with this method of building comes from having to sort less. There are also fewer points to sort each time anything needs to be sorted, which leads to better detection of overlapping points.
Client Storage
The second big improvement does absolutely nothing for performance... unless you have IndexedDB enabled in the browser. Parts are being stored in the IndexedDB of the client, which allows for much quicker rebuilding of parts. Retrieving parts from IndexedDB takes less than 2ms for all models I have tested with. This technology didn't work for me right away:
Performance Improvements
The following two models are added to the test suite for variety:
UCS MF (10179) with 5163 parts
and this MAN TGS Cement Truck with 1523 parts
The results for performance are split up in two times. The first is for building parts and storing them in IndexedDB. This number is less than 2ms for repeated visits, but is encountered at the first visit and for everyone who does not use IndexedDB (such as Safari in Incognito mode):
Psych
- Memory usage: 8.8MB -> 9.7MB
- Rendering time: 3.325ms -> 1.270ms + 1.730ms = 3.000ms
MAN Cement Truck
- Memory usage: 20.2MB -> 18.5MB
- Rendering time: 12.090ms -> 4.619ms + 4.432ms = 9.051ms
Executor
- Memory usage: 16.4MB -> 27.5MB
- Rendering time: 44.922ms -> 4.008ms + 4.024ms = 8.032ms
UCS MF (10179)
- Memory usage: 20.5MB -> 37.8MB
- Rendering time: 134.709ms -> 4.561ms + 5.214ms = 9.775ms
This is a great success for rendering times and only a moderate decrement to space usage. Remember that these performance measures are from my now 10 year old mid range Sony Vaio laptop. A modern phone is quicker than this!
The initial results were some really hairy models:
Joke aside (although that was actually the result after the first code rewrite). To use VBO's with three.js boils down to reusing 'Mesh' objects. I have decided to build one mesh for each part in color '16. A model using a certain part with different colors will thus only use (and reuse) a single VBO. The color handling is performed in custom shaders.
If you remember some of my first posts in this thread, you might think "This sounds familiar... isn't this what you did before bringing down the space usage and improving the render time?" and you would be right.
So what has changed?
Well. Pretty much the whole code base. By using the tricks from all the other posts (such as reusing points and using custom shaders), the memory usage is being kept under control. Performance is similarly improved by the following two improvements:
Bottom-up Constructions of Parts
I am now building the parts "bottom-up" in order to improve reusability of points. Previously a part, such as 3001 would be built like this:
Build 3001.dat by first building all line types 2, 3, 4 and 5. Then built each primitive (line type 1), such as stud.dat the same way.
Finally sort all the points collected for 3001.dat in order to reuse those that overlap.
Now parts are built like this:
First built all primitives without any inner primitives (such as 4-4edge.dat, which only consists of 16 normal lines). Sort the points of the primitives immediately.
Then built all primitives that only depend on the primitives that have been built. The effort used by sorting is now reduced since the other primitives already have their points sorted.
Continue until all parts are built.
The improvements with this method of building comes from having to sort less. There are also fewer points to sort each time anything needs to be sorted, which leads to better detection of overlapping points.
Client Storage
The second big improvement does absolutely nothing for performance... unless you have IndexedDB enabled in the browser. Parts are being stored in the IndexedDB of the client, which allows for much quicker rebuilding of parts. Retrieving parts from IndexedDB takes less than 2ms for all models I have tested with. This technology didn't work for me right away:
Performance Improvements
The following two models are added to the test suite for variety:
UCS MF (10179) with 5163 parts
and this MAN TGS Cement Truck with 1523 parts
The results for performance are split up in two times. The first is for building parts and storing them in IndexedDB. This number is less than 2ms for repeated visits, but is encountered at the first visit and for everyone who does not use IndexedDB (such as Safari in Incognito mode):
Psych
- Memory usage: 8.8MB -> 9.7MB
- Rendering time: 3.325ms -> 1.270ms + 1.730ms = 3.000ms
MAN Cement Truck
- Memory usage: 20.2MB -> 18.5MB
- Rendering time: 12.090ms -> 4.619ms + 4.432ms = 9.051ms
Executor
- Memory usage: 16.4MB -> 27.5MB
- Rendering time: 44.922ms -> 4.008ms + 4.024ms = 8.032ms
UCS MF (10179)
- Memory usage: 20.5MB -> 37.8MB
- Rendering time: 134.709ms -> 4.561ms + 5.214ms = 9.775ms
This is a great success for rendering times and only a moderate decrement to space usage. Remember that these performance measures are from my now 10 year old mid range Sony Vaio laptop. A modern phone is quicker than this!