-
Notifications
You must be signed in to change notification settings - Fork 470
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Question] Suggested Rendering Optimizations? #459
Comments
Hi @gkjohnson - we love the work that you've done with 3DTilesRendererJS 😄 All good ideas - anything to reduce draw calls should help, including batching based on material and using texture atlases. KHR_texture_transform may be worth looking at. Also check out EXT_mesh_features which could in theory be used to batch primitives with different PBR parameters (the PBR parameter would be stored in property tables and accessed in the shader). Runtime batching of different tiles is something we've considered in CesiumJS but haven't implemented yet. Out of curiosity have you had success with any of these techniques since you opened this issue? We'd love to hear if you've seen any good results. |
Hey @lilleyse! Thanks for the kinds words -- always happy to hear it. We appreciate you guys making the spec publicly available, as well! These all sound like good additional GLTF extensions but they do all require that the data be preprocessed. To add a bit more context -- the tileset that the user provided and was seeing slow performance on was some kind of BIM model that had been generated from a piece of software I'm unfamiliar with (possibly some custom solution). Part of me wondered if they were generating less-than-optimal b3dm files because the typical viewer for 3d tiles (Cesium) was automatically optimizing the contents on load. It sounds like Cesium isn't doing anything like that, though.
My answer when users send these kinds of files is that the tiles should be optimized ahead of time which I think is the right answer whether run time optimizations are present or not. The 3DTilesRenderer class affords a callback whenever a model is loaded which would allow the use to perform any run time optimizations they'd like including mesh merging, material sharing, texture atlasing, etc, but ultimately I see that as a user-land concern. Run time batching between different tiles would be a nice optional function / plugin for the renderer but I haven't taken a deep dive into it myself -- generally we haven't had a need for our work. It's also unclear to me what exactly the right path would be considering how frequently the batched geometry and textures would have to be updated as the camera moves and tiles are loaded / unloaded. The |
Yeah nothing too fancy in CesiumJS on this front, we render the glTF as-is and hope that tiles coming in are optimized. Though long term we're interested in runtime batch techniques intra-tile and inter-tile. Lots of variables to consider for the latter and I wonder if additional metadata in the tileset could provide tile size guarantees to help minimize the defragging problem. Or maybe you only batch sibling tiles and load/unload them together? (related: #9) Most of our performance tuning in CesiumJS has focused on tile prioritization and preloading (e.g. for camera flights) https://cesium.com/blog/2019/05/07/faster-3d-tiles/ |
One thing that comes to mind in a simple case, at least, is if there were a known and consistent or maximum number of triangles / vertices per tile then it would make updating the batched geometry easier. You could preallocate buffer space for x number of tiles knowing that no tile would be above a certain memory requirement and no defragmentation of the buffer would have to be done. You'd just have to keep track of unused sections of the buffer to fill them in when new data is loaded. Something similar could be done with a sampler array if you know ahead of time that the textures are a consistent size. Of course this all assumes that the tiles are designed to be share a common material in the first place. |
Thanks for the discussion @gkjohnson! I'm going to close this issue to keep things tidy. |
Hello! I recently got a performance-related issue from a user when they were rendering a data set with our three.js 3d tiles implementation here. Looking at the data set once it's fully loaded there are over 3500 meshes in the scene which was taking 30+ ms to render while there are only around 93 visible tiles. Beyond modifying the source data to produce pre merged geometry per tile are there any recommendations for run time optimizations that can be performed for a situation like this?
Some of the basic options that come to mind include sharing any common materials between all tile geometry, atlasing textures within a single set of tile geometry, merging geometry with common materials within a single tile, and / or dynamic batching of non instanced visible tile geometry to cut down on state changes and draw calls. Do you guys use any of these in Cesium or have other recommendations?
Thanks!
The text was updated successfully, but these errors were encountered: