-
-
Notifications
You must be signed in to change notification settings - Fork 3.8k
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
[Merged by Bors] - Mesh Skinning. Attempt #3 #4238
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just finished my first pass. Generally things are looking good. I think the SkinnedMeshJoints
allocation patterns are the biggest thing that needs revisiting.
crates/bevy_pbr/src/render/mesh.rs
Outdated
}, | ||
count: None, | ||
}], | ||
label: Some("mesh_layout"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
label: Some("mesh_layout"), | |
label: Some("joint_buffer_layout"), |
Nit: distinct name for debugging.
I consolidated the joint binding into the Mesh bind group, which I think is the right path forward, given how limited bind group slots are in practice (4 is what we can rely on). I think this is good to go. I'll wait for feedback on the merged bind group from at least one other person involved in this before merging though. |
How does WGSL/wgpu handle bindings that go unused? I was originally under the impression that the two had to be 1:1 Any skinned mesh on screen would add an extra binding to all drawn meshes. |
Bindings must be used / bound. Note that in my change there are two "flavors" of the bind group: one with skinning and one without. The proper bind group is selected based on whether or not skinning is enabled. It is always a "perfect fit". |
While I think this will work for this particular case, I'm not sure how well this will go when we need expanded support (i.e. morph targets), as we'd have combinatorially many bind groups. I guess we'll cross that bridge when we get there. |
Depends on the approach used. If we use dynamic uniforms for morph targets, we can still have a single bind group. Happy to revisit when we implement morph targets though. |
bors r+ |
# 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 # #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 <[email protected]> Co-authored-by: François <[email protected]> Co-authored-by: James Liu <[email protected]>
there is some Z-fighting in 'custom_skinned_mesh' example, not like a major issue but it's better not to see things like that) |
# 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 <[email protected]> Co-authored-by: François <[email protected]> Co-authored-by: James Liu <[email protected]>
# 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 <[email protected]> Co-authored-by: François <[email protected]> Co-authored-by: James Liu <[email protected]>
Objective
Load skeletal weights and indices from GLTF files. Animate meshes.
Solution
SkinnedMesh
component andSkinnedMeshInverseBindPose
assetextract_skinned_meshes
to extract joint matrices.Some notes:
BufferVec
s and bind groups every frame. The expectation here is that the number ofQuery::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.Crediting
This isn't something that I did alone and has been worked on by @lassade and @Looooong and multiple others before this PR was made.