-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Add MeshPass #21880
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
base: main
Are you sure you want to change the base?
Add MeshPass #21880
Conversation
|
Welcome, new contributor! Please make sure you've read our contributing guide and we look forward to reviewing your pull request shortly ✨ |
ded7642 to
46eebe5
Compare
46eebe5 to
70276b2
Compare
|
Okay, I haven't had a chance to look deeply at the code but a few thoughts:
I'm particularly encouraged by more experimentation here as this is an area of the renderer that really needs to be more modular. |
|
I totally understand you. While adding the example, I discovered a problem: Adding MeshPasses that share a PhaseItem across different entities’ materials is fine, but this use case is very limited. If a user wants to add multiple MeshPasses to the same material, they must use completely different PhaseItems. Whether they implement them from scratch or use a newtype, they ultimately need to provide a corresponding render graph node. Update: |
|
The generated |
Hello everyone,
This is my first pull request. I've been experimenting with this for a while, and now it's time to share it.
Objective
To simplify the effort required to create and add a custom mesh pipeline.
This pull request currently only simplifies the work needed for the specialization and queue stages. I haven't yet found a suitable way to abstract the other stages. I think that's enough to close #21127.
As a reward, this enables a form of "multi-material" support by allowing custom MeshPasses to be added to a material.
Solution
I've abstracted
MaterialPluginsinto the more generalMeshPassPlugin<P>, which customizes the behavior of a pass via theMeshPassgeneric parameter.Now, a
MeshPasscan be defined like this:Where
SpecializerandPhaseItemare expected to implement the following traits:And a material can utilize it as follows:
Beyond this, some additional work is still required for usage. Please refer to
main_pass.rsandprepass/mod.rsfor details.Implementation Challenges
To achieve this, I explored multiple approaches:
Abstracting the specialize and queue systems to be per-phase item: This meant using systems like
specialize<Pass, PhaseItem>andqueue<Pass, PhaseItem>. Each system would only handle one phase item, and we would add multiple system based onMeshPass::PhaseItems.visible_entities, and I couldn't find a simple or efficient way to filter them down.Switching to a per-pass system approach: To convert the MeshPass::PhaseItems tuple into parameters for the specialize and queue systems and to directly call the trait methods through the tuple within the systems, I ended up writing a lot of complicated and verbose macros. This eventually led to an issue with HRTB (Higher-Rank Trait Bounds), which propagated from the internal systems to the user's implementation, making the whole approach completely unusable.
Current Approach:
The current solution uses a fixed number of
Option<Res<RenderPhasesN<P>>>for the specialize and queue system parameters, usingDummyPhaseNto fill any unused slots in thePMeshPass::PhaseItemstuple. This approach is much simpler to implement, and the resulting boilerplate code is considered acceptable.Pending Issues
Previously, when iterating over
visible_entityinspecialize_prepass_material_meshes, we had this:Now that we support adding custom
MeshPasses, and users can even disable theMainPass, this filtering needs to be extended into a general implementation. Also, since users can add two materials with completely different passes, when iterating overvisible_entity, it would be best to filter for the relevant passes.Both issues fundamentally boil down to the same problem: We need a way within the systems to determine if an entity is valid for the current pass.
Potential Solutions:
MaterialProperties: For example,passes_enabled: SmallVec[PassId]. We would also need to add a corresponding method in theMaterialtrait.Materialpurely for defining the material: Then, use an additionalPassMarkercomponent to indicate whether the corresponding pass is enabled. This could potentially be combined withVisibilityClass.Additionally, if you have any good suggestions regarding the API naming or parameter design, please let me know!
Testing
In this commit,
MainPass,Prepass, andDeferredPasshave been switched to the newMeshPassimplementation and have been tested in theshader_prepass,motion_blur, anddeferred_renderingexamples.