-
-
Notifications
You must be signed in to change notification settings - Fork 35.3k
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
BatchedMesh: Implemented optimize, deleteGeometry and deleteInstance … #28638
base: dev
Are you sure you want to change the base?
Conversation
📦 Bundle sizeFull ESM build, minified and gzipped.
🌳 Bundle size after tree-shakingMinimal build including a renderer, camera, empty scene, and dependencies.
|
@mrdoob, @Mugen87, @gkjohnson |
TBH, I'm not much in favor of this change. So I don't think we should accommodate use cases where |
I agree with this but I think a lot the apparent complexity is coming from so many changes happening in a single PR. I'd expect most of the added complexity to be from the addition of the "optimize" function. I do think we need more concrete use cases for this, though, before adding it. But generally I think it's best to make progressive changes towards something like this so it's easier to understand what's changing. Even so, here couple quick thoughts on this from skimming the code:
But again - I think we should lay out what's this would be used for in practice and what's not possible right now before expanding on this too much more. |
I understand that in this PR there are a lot of changes and that’s why it’s a PR draft, the maintainability of the code can be made better, I can also improve it so that the use of the BatchedMesh class does not change.
I did all this based on the fact that we were talking about the “optimize” function and in the code in the comments it was written that we need to call this function to pack the data. Here I don’t really agree with the idea that you just need to manage "visibility" because I think that after deleting the geometry or instance it should not be stored. |
If there is no drawIndex there will be problems after optimize, here I can make the user work only with instanceId and inside the class BatchedMesh using this instanceId I can get DrawIndex without losing the performance.
I agree with this, I have an idea on how to do this without losing performance. One of these days I'll push the changes.
I just added these things for convenience, they can be easily removed, they are not so critically important.
In my project I use Tile system, I previously had problems with InstancedMesh, since I cannot delete unnecessary instances and add new places to deleted ones. It is very difficult to keep track of which indexes have become free. Now with BatchedMesh I will have the same problems, because I need to add geometry and at some point I need to delete it to free up space. This is necessary because next you will need to add new geometry. |
Guys, thank you for your response, I thought it would be more useful to implement the optimization function because I worked on a similar case on my project and I decided to share. If you want to simple version of optimize function and with fewer changes, you can suggest how it should be. Based on this, I will try to implement it. Again, if necessary. |
Having I don't have much preference beyond that. Immutability can be a useful characteristic in an API, and if we feel that it shouldn't be possible to do removeGeometry, for simplicity and optimization, I have no objection. We could instead add a |
I'm not really sure that it's better that |
I am not insisting that they accept this PR, simply based on the fact that I think it is necessary to implement |
I removed third |
Yes I mean that
These are the kind use cases that I think are good to elaborate on in more detail. The maintainers of this project are not familiar with your use case so it's up to you to make sure we understand why the currently implementation isn't adequate, what's not currently possible, and what issues it's causing.
I think having to shift all colors and matrices when you want to "remove" an instance in the middle of the list is a bit unnecessarily complicated an, in my opinion, an artifact of the underlying InstancedMesh implementation. BatchedMesh is more complicated but generally a significantly more powerful class with support for object sorting and frustum culling. The underlying implementation here would more easily enable removing intermediate elements.
Even if we did this the new BatchedMesh instance would still be expected to respect the previously provided |
Yes, I fixed it, removed all
I agree with you here. I thought the same thing and implemented this |
Yes, I would like for BatchedMesh to allow deleting instances, i.e. returning a previously-used instance from the @gkjohnson I'm happy with whatever you prefer here. 👍🏻 |
Hi guys, Here a use case for I'm currently using BatchedMesh to create new rooms in a dungeon game. In this case I can't really only toggle visibility cause each rooms needs the 2000 instances to use a different set of geometry. Also it didnt seems right to recreate a new BatchedMesh each time as I already have everything loaded and ready in the gpu. For this case I guest the best would be one of those, the first one being my favorite:
I think this case come often when BatchedMesh is use to create large generative environment in game as I face the same problem in a runner game too. |
I agree with you @Makio64. I have already improved |
Related issue: #28462
Description
In this PR implemented deleteGeometry, deleteInstance, deleteAllInstances and optimize functions in the BatchedMesh class. Now you can delete the geometry or instance and then pack the data using the optimization function for further use. This helps eliminate gaps in geometry and instance data and remove unnecessary data. This makes it much easier to use BatchedMesh. The packing data in optimize function without re-creating copy of data.
To achieve this we had to change a lot of things, I will try describe them all below. This is my first PR, this PR is not completely ready, I needed a feedback, so I decided to draw up a PR draft.
Separate Index from ID in the geometries and instances. Because when delete something we have mismatch with index. To solve use geometryId for geometries and instanceId for instances.
Due to the fact that ID is now used, I had to replace _reservedRanges, _drawRanges, _bounds from a bracket array with Map for quick access by ID. Because find() method is slower than Map's get(), since the class does not iterate over these arrays, in this case I think it is better to use Map. If Map is not suitable, I can replace everything with a bracket array, but it will work slowly.
For _drawInfo, I left a bracket array, because there is a lot of iteration over this array. As I know, iteration over Map is slower than iteration over a regular array. So now the instanceId is used for the instance so that there are no problems with matrices, I added another DrawIndex for the instance. This helps to get the instance matrix much faster.
Usage
API Changes
deleteGeometry( geometryId )
Deletes all data of this geometry from attributes and index of the batched mesh geometry. And delete all instances of this geometry. After needs to call optimize to pack the data.
deleteInstance( instanceId )
Deletes the instance data from matrices and colors if colors defined. After it needs to call optimize to update matrices and colors.
optimize()
This function packs and delete gaps the geometry data of the batched mesh. After updates matrices and colors texture and doing re-indexing any instance. This implemented using Array.copyWithin() to get rid of gaps by moving data without creating a copy of data.
Screenshots
Here I delete conus and sphere geometries, keep only box geometry. The screenshots shows how geometry can be optimized after optimize
Position attribute before optimize:
Position attribute after optimize:
Index before optimize:
Index after optimize
I need to get feedback about:
As soon as I get the feedback, I will try to create a new PR and a documentation for this.
I tried to describe as best I could.