-
Notifications
You must be signed in to change notification settings - Fork 1
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
StandardMaterial flat values #3
StandardMaterial flat values #3
Conversation
I made this call for performance reasons. I tried swapping over to per-entity spawn commands for sprites and got a pretty major performance dip. However ultimately I think spawning as entities is probably the way to go, as it allows people to attach custom data to extracted entities and easily correlate it to the data we extract for entities (like mesh data). I also think we have a number of options to cut down on overhead:
I want to experiment with doing "asset extraction" in the extract step to protect against this kind of thing. I think we can make it perform just as well, and it would be much more clean / consistent that way. |
Sounds good. I’m fine with it being a resource for now and making an iterative change later when ECS performance is good enough for this. It also feels a bit strange to have multiple copies of data - in the app world, extracted in the render world, converted from that to std140, written into a staging buffer, and copied to VRAM. That’s possibly 4 copies in system RAM and one in VRAM. I appreciate that we need to have at least one in the app world, one in the render world, and one in VRAM but is there a way to avoid the 2 additional copies? I was thinking about extracting directly into std140 buffers. And then I wonder if the staging buffer actually makes a copy or just holds a reference. The copying is inefficient, and takes space.
What do you mean here? I was thinking that the BufferId is only used to insert into the bind group so I could move the bind group creation into the extract step and remove the BufferId member from ExtractedMesh, only storing the BindGroupId. But it sounds like you maybe mean handling the staging and buffer copy or texture creation and upload, similar to how uniforms are handled, rather than running app world systems to do it. |
This would require direct access to a centralized UniformVec resource (which is doable if we insert the render world as a resource, but would require running such systems serially). The main reason not to do it is if there is expensive work required to make it happen (ex: computing the inverse of a matrix). We want to keep the extract step as short as possible to allow the next frame update to start running as quickly as possible. I honestly doubt that the extra step costs us much. But its worth benchmarking.
Afaik this is a direct memory-mapped gpu pointer.
Basically:
|
To be clear: we can definitely remove the intermediate buffer, it just puts a restriction on when/how we map the staging buffer. Without the intermediate vec it would be hard to queue things up across systems. But thats not really a major loss in this context. |
Perhaps it's possible to support both ways of doing things. A sort of deferred staging buffer that holds a copy of the data, and an immediate zero copy version? |
Let me know if there's anything else you'd like me to change before this is possible to merge. :) |
Looks good to me! |
# Objective Load skeletal weights and indices from GLTF files. Animate meshes. ## Solution - Load skeletal weights and indices from GLTF files. - Added `SkinnedMesh` component and ` SkinnedMeshInverseBindPose` asset - Added `extract_skinned_meshes` to extract joint matrices. - Added queue phase systems for enqueuing the buffer writes. Some notes: - This ports part of # bevyengine#2359 to the current main. - This generates new `BufferVec`s and bind groups every frame. The expectation here is that the number of `Query::get` calls during extract is probably going to be the stronger bottleneck, with up to 256 calls per skinned mesh. Until that is optimized, caching buffers and bind groups is probably a non-concern. - Unfortunately, due to the uniform size requirements, this means a 16KB buffer is allocated for every skinned mesh every frame. There's probably a few ways to get around this, but most of them require either compute shaders or storage buffers, which are both incompatible with WebGL2. Co-authored-by: james7132 <contact@jamessliu.com> Co-authored-by: François <mockersf@gmail.com> Co-authored-by: James Liu <contact@jamessliu.com>
Added support for 'flat' values (i.e. that do not vary across the surface, so no textures) in StandardMaterial. I just got this working with the
3d_scene_pipelined
example. I haven't implemented sorting by material and I'm just naively rebinding on for every mesh. I don't really like the way I had to munge theStandardMaterial
'sBufferId
andOption<BindGroupId>
intoExtractedMesh
and I'd love to hear suggestions for better ways of managing that. I don't really understand why theExtractedMesh
are added to aVec<>
member inExtractedMeshes
which is inserted as a render world resource, instead of them being inserted as individual entities, as then I would have added a component to those entities. I'm guessing it has something to do with queries not guaranteeing order or something.