-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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] - Shader Imports. Decouple Mesh logic from PBR #3137
Conversation
Closely related to #2241. |
How do all this interact with shader hot-reloading? Is there a technical reason why the PBR shaders are using |
@Davier i'm pretty sure that the reason is that the AssetServer is meant for loading things from the application's assets dir. Shaders that come included with bevy (or community plugins) aren't distributed in that way, so they gotta get loaded differently. |
Yup its a matter of bundling shaders inside crates. We might ultimately sort out some way to not bundle these types of assets inside the binary to cut down on deployment sizes, but there are a ton of UX issues to solve there:
An editor might make it easier to implement these features, but I'm not even convinced that its worth it generally. At the very least, its not something I want to solve now. |
(resolved conflicts) |
Fixes #3132 Confirmed the fix with a local patch: diff --git a/pipelined/bevy_render2/src/render_phase/draw.rs b/pipelined/bevy_render2/src/render_phase/draw.rs
index 2f26c540..6a5e9759 100644
--- a/pipelined/bevy_render2/src/render_phase/draw.rs
+++ b/pipelined/bevy_render2/src/render_phase/draw.rs
@@ -249,7 +249,9 @@ where
item: &P,
) {
let param = self.state.get(world);
- C::render(view, item, param, pass);
+ if let RenderCommandResult::Failure = C::render(view, item, param, pass) {
+ bevy_utils::tracing::warn!("RenderCommandResult::Failure");
+ }
}
}
And seeing some log lines infrequently on startup, but no panics:
|
bors r+ |
## Shader Imports This adds "whole file" shader imports. These come in two flavors: ### Asset Path Imports ```rust // /assets/shaders/custom.wgsl #import "shaders/custom_material.wgsl" [[stage(fragment)]] fn fragment() -> [[location(0)]] vec4<f32> { return get_color(); } ``` ```rust // /assets/shaders/custom_material.wgsl [[block]] struct CustomMaterial { color: vec4<f32>; }; [[group(1), binding(0)]] var<uniform> material: CustomMaterial; ``` ### Custom Path Imports Enables defining custom import paths. These are intended to be used by crates to export shader functionality: ```rust // bevy_pbr2/src/render/pbr.wgsl #import bevy_pbr::mesh_view_bind_group #import bevy_pbr::mesh_bind_group [[block]] struct StandardMaterial { base_color: vec4<f32>; emissive: vec4<f32>; perceptual_roughness: f32; metallic: f32; reflectance: f32; flags: u32; }; /* rest of PBR fragment shader here */ ``` ```rust impl Plugin for MeshRenderPlugin { fn build(&self, app: &mut bevy_app::App) { let mut shaders = app.world.get_resource_mut::<Assets<Shader>>().unwrap(); shaders.set_untracked( MESH_BIND_GROUP_HANDLE, Shader::from_wgsl(include_str!("mesh_bind_group.wgsl")) .with_import_path("bevy_pbr::mesh_bind_group"), ); shaders.set_untracked( MESH_VIEW_BIND_GROUP_HANDLE, Shader::from_wgsl(include_str!("mesh_view_bind_group.wgsl")) .with_import_path("bevy_pbr::mesh_view_bind_group"), ); ``` By convention these should use rust-style module paths that start with the crate name. Ultimately we might enforce this convention. Note that this feature implements _run time_ import resolution. Ultimately we should move the import logic into an asset preprocessor once Bevy gets support for that. ## Decouple Mesh Logic from PBR Logic via MeshRenderPlugin This breaks out mesh rendering code from PBR material code, which improves the legibility of the code, decouples mesh logic from PBR logic, and opens the door for a future `MaterialPlugin<T: Material>` that handles all of the pipeline setup for arbitrary shader materials. ## Removed `RenderAsset<Shader>` in favor of extracting shaders into RenderPipelineCache This simplifies the shader import implementation and removes the need to pass around `RenderAssets<Shader>`. ## RenderCommands are now fallible This allows us to cleanly handle pipelines+shaders not being ready yet. We can abort a render command early in these cases, preventing bevy from trying to bind group / do draw calls for pipelines that couldn't be bound. This could also be used in the future for things like "components not existing on entities yet". # Next Steps * Investigate using Naga for "partial typed imports" (ex: `#import bevy_pbr::material::StandardMaterial`, which would import only the StandardMaterial struct) * Implement `MaterialPlugin<T: Material>` for low-boilerplate custom material shaders * Move shader import logic into the asset preprocessor once bevy gets support for that. Fixes #3132
Pull request successfully merged into pipelined-rendering. Build succeeded: |
Shader Imports
This adds "whole file" shader imports. These come in two flavors:
Asset Path Imports
Custom Path Imports
Enables defining custom import paths. These are intended to be used by crates to export shader functionality:
By convention these should use rust-style module paths that start with the crate name. Ultimately we might enforce this convention.
Note that this feature implements run time import resolution. Ultimately we should move the import logic into an asset preprocessor once Bevy gets support for that.
Decouple Mesh Logic from PBR Logic via MeshRenderPlugin
This breaks out mesh rendering code from PBR material code, which improves the legibility of the code, decouples mesh logic from PBR logic, and opens the door for a future
MaterialPlugin<T: Material>
that handles all of the pipeline setup for arbitrary shader materials.Removed
RenderAsset<Shader>
in favor of extracting shaders into RenderPipelineCacheThis simplifies the shader import implementation and removes the need to pass around
RenderAssets<Shader>
.RenderCommands are now fallible
This allows us to cleanly handle pipelines+shaders not being ready yet. We can abort a render command early in these cases, preventing bevy from trying to bind group / do draw calls for pipelines that couldn't be bound. This could also be used in the future for things like "components not existing on entities yet".
Next Steps
#import bevy_pbr::material::StandardMaterial
, which would import only the StandardMaterial struct)MaterialPlugin<T: Material>
for low-boilerplate custom material shadersFixes #3132