mirror of
https://github.com/bevyengine/bevy.git
synced 2026-07-01 08:12:51 -04:00
create-pull-request/patch
12 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
535cf401cc |
Reframe old "scene" terminology as "world serialization" (#23630)
Part 2 of #23619 In **Bevy 0.19** we are landing a subset of Bevy's Next Generation Scene system (often known as BSN), which now lives in the `bevy_scene` / `bevy::scene` crate. However the old `bevy_scene` system still needs to stick around for a bit longer, as it provides some features that Bevy's Next Generation Scene system doesn't (yet!): 1. It is not _yet_ possible to write a World _to_ BSN, so the old system is still necessary for "round trip World serialization". 2. The GLTF scene loader has not yet been ported to BSN, so the old system is still necessary to spawn GLTF scenes in Bevy. For this reason, we have renamed the old `bevy_scene` crate to `bevy_world_serialization`. If you were referencing `bevy_scene::*` or `bevy::scene::*` types, rename those paths to `bevy_world_serialization::*` and `bevy::world_serialization::*` respectively. Additionally, to avoid confusion / conflicts with the new scene system, all "scene" terminology / types have been reframed as "world serialization": - `Scene` -> `WorldAsset` (as this was always just a World wrapper) - `SceneRoot` -> `WorldAssetRoot` - `DynamicScene` -> `DynamicWorld` - `DynamicScene::from_scene` -> `DynamicWorld::from_world_asset` - `DynamicSceneBuilder` -> `DynamicWorldBuilder` - `DynamicSceneRoot` -> `DynamicWorldRoot` - `SceneInstanceReady` -> `WorldInstanceReady` - `SceneLoader` -> `WorldAssetLoader` - `ScenePlugin` -> `WorldSerializationPlugin` - `SceneRootTemplate` -> `WorldAssetRootTemplate` - `SceneSpawner` -> `WorldInstanceSpawner` - `SceneFilter` -> `WorldFilter` - `SceneLoaderError` -> `WorldAssetLoaderError` - `SceneSpawnError` -> `WorldInstanceSpawnError` Note that I went with `bevy_world_serialization` over `bevy_ecs_serialization`, as that is what all of the internal features described themselves as. I think it is both more specific and does a better job of making itself decoupled from `bevy_ecs` proper. |
||
|
|
9d2db8838f |
Improve frustum culling of skinned meshes through per-joint bounds (#21837)
## Objective Mostly fix #4971 by adding a new option for updating skinned mesh `Aabb` components from joint transforms. https://github.com/user-attachments/assets/c25b31fa-142d-462b-9a1d-012ea928f839 This fixes cases where vertex positions are only modified through skinning. It doesn't fix other cases like morph targets and vertex shaders. The PR kind of upstreams [`bevy_mod_skinned_aabb`](https://github.com/greeble-dev/bevy_mod_skinned_aabb), but with some changes to make it simpler and more reliable. ### Dependencies - (MERGED) #21732 (or something similar) is desirable to make the new option work with `RenderAssetUsages::RENDER_WORLD`-only meshes. - This PR is authored as if 21732 has landed. But if that doesn't happen then I can adjust this PR to note the limitation. - (Optional) #21845 adds an option related to skinned mesh bounds. - Either PR can land first - the second will need to be updated. ## Background If a main world entity has a `Mesh3d` component then it's automatically assigned an `Aabb` component. This is done by `bevy_camera` or `bevy_gltf`. The `Aabb` is used by `bevy_camera` for frustum culling. It can also be used by `bevy_picking` as an optimization, and by third party crates. But there's a problem - the `Aabb` can be wrong if something changes the mesh's vertex positions after the `Aabb` is calculated. This can be done by vertex shaders - notably skinning and morph targets - or by mutating the `Mesh` asset (#4294). For the skinning case, the most common solution has been to disable frustum culling via the `NoFrustumCulling` component. This is simple, and might even be the most efficient approach for apps where meshes tend to stay on-screen. But it's annoying to implement, bad for apps where meshes are often off-screen, and it only fixes frustum culling - it doesn't help other systems that use the `Aabb`. ## Solution This PR adds a reliable and reasonably efficient method of updating the `Aabb` of a skinned mesh from its animated joint transforms. See the "How does it work" section for more detail. The glTF loader can add skinned bounds automatically if a new `GltfSkinnedMeshBoundsPolicy` option is enabled in `GltfPlugin` or `GltfLoaderSettings`: ```rust app.add_plugins(DefaultPlugins.set(GltfPlugin { skinned_mesh_bounds_policy: GltfSkinnedMeshBoundsPolicy::Dynamic, ..default() })) ``` _The new glTF loader option is enabled by default_. I think this is the right choice for several reasons: - Bugs caused by skinned mesh culling have been a regular pain for both new and experienced users. Now the most common case Just Works(tm). - The CPU cost is modest (see later section), and sophisticated users can opt-out. - GPU limited apps might see a performance increase if the user was previously disabling culling. Non-glTF cases require some manual steps. The user must ask `Mesh` to generate the skinned bounds, and then add the `DynamicSkinnedMeshBounds` marker component to their mesh entity. ```rust mesh.generate_skinned_mesh_bounds()?; let mesh_asset = mesh_assets.add(mesh); entity.insert((Mesh3d(mesh_asset), DynamicSkinnedMeshBounds)); ``` See the `custom_skinned_mesh` example for real code. ## Bonus Features ### `GltfSkinnedMeshBoundsPolicy::NoFrustumCulling` This is a convenience for users who prefer the `NoFrustumCulling` workaround, but want to avoid the hassle of adding it after a glTF scene has been spawned. ```rust app.add_plugins(DefaultPlugins.set(GltfPlugin { skinned_mesh_bounds_policy: GltfSkinnedMeshBoundsPolicy::NoFrustumCulling, ..default() })) ``` PR #21845 is also adding an option related to skinned mesh bounds. I'm fine if that PR lands first - I'll update this PR to include the option. ### Gizmos `bevy_gizmos::SkinnedMeshBoundsGizmoPlugin` can draw the per-joint AABBs. ```rust fn toggle_skinned_mesh_bounds(mut config: ResMut<GizmoConfigStore>) { config.config_mut::<SkinnedMeshBoundsGizmoConfigGroup>().1.draw_all ^= true; } ``` The name is debatable. It's not technically drawing the bounds of the skinned mesh - it's drawing the per-joint bounds that contribute to the bounds of the skinned mesh. ## Testing ```sh cargo run --example test_skinned_mesh_bounds # Press `B` to show mesh bounds, 'J' to show joint bounds. cargo run --example scene_viewer --features "free_camera" -- "assets/models/animated/Fox.glb" cargo run --example scene_viewer --features "free_camera" -- "assets/models/SimpleSkin/SimpleSkin.gltf" # More complicated mesh downloaded from https://github.com/KhronosGroup/glTF-Sample-Assets/tree/main/Models/RecursiveSkeletons cargo run --example scene_viewer --features "free_camera" -- "RecursiveSkeletons.glb" cargo run --example custom_skinned_mesh ``` I also hacked `custom_skinned_mesh` to simulate awkward cases like rotated and off-screen entities. ## How Does It Work? <details><summary>Click to expand</summary> ### Summary `Mesh::generated_skinned_mesh_bounds` calculates an AABB for each joint in the mesh - the AABB encloses all the vertices skinned to that joint. Then every frame, `bevy_camera::update_skinned_mesh_bounds` uses the current joint transforms to calculate an `Aabb` that encloses all the joint AABBs. This approach is reliable, in that the final `Aabb` will always enclose the skinned vertices. But it can be larger than necessary. In practice it's tight enough to be useful, and rarely more than 50% bigger. This approach works even with non-rigid transforms and soft skinning. If there's any doubt then I can add more detail. ### Awkward Bits The solution is not as simple and efficient as it could be. #### Problem 1: Joint transforms are world-space, `Aabb` is entity-space. - Ideally we'd use the world-space joint transforms to calculate a world-space `Aabb`, but that's not possible. - The obvious solution is to transform the joints to entity-space, so the `Aabb` is directly calculated in entity-space. - But that means an extra matrix multiply per joint. - This PR calculates the `Aabb` in world-space and then transforms it to entity-space. - That avoids a matrix multiply per-joint, but can increase the size of the `Aabb`. #### Problem 2: Joint AABBs are in a surprising(?) space. - When creating joint AABBs from a mesh, the intuitive solution would be to calculate them in joint-space. - Then the update just has to transform them by the world-space joint transform. - But to calculate them in joint-space we need both the bind pose vertex positions and the bind pose joint transforms. - These two parts are in separate assets - `Mesh` and `SkinnedMeshInverseBindposes` - and those assets can be mixed and matched. - So we'd need to calculate a `SkinnedMeshBoundsAsset` for each combination of `Mesh` and `SkinnedMeshInverseBindposes`. - (`bevy_mod_skinned_aabb` uses this approach - it's slow and fragile.) - This PR calculates joint AABBs in *mesh-space* (or more strictly speaking: bind pose space). - That can be done with just the `Mesh` asset. - One downside is that the update needs an extra matrix multiply so we can go from mesh-space to world-space. - However, this might become a performance advantage if frustum culling changes - see the "Future Options" section. - Another minor downside is that mesh-space AABBs (red in the screenshot below) tend to be bigger than joint-space AABBs (green), since joints with one long axis might be at an awkward angle in mesh-space. <img width="1085" height="759" alt="image" src="https://github.com/user-attachments/assets/a02a28c3-8882-412c-9be1-64109b767da7" /> ### Future Options For frustum culling there's a cheeky way to optimize and simplify skinned bounds - put frustum culling in the renderer and calculate a world-space AABB during `extract_skins`. The joint transform will be already loaded and in the right space, so we can avoid an entity lookup and matrix multiply. I estimate this would make skinned bounds 3x faster. Another option is to change main world frustum culling to use a world-space AABB. So there would be a new `GlobalAabb` component that gets updated each frame from `Aabb` and the entity transform (which is basically the same as transform propagation and the relationship between `Transform` and `GlobalTransform`). This has some advantages and disadvantages but I won't get into them here - I think putting frustum culling into the renderer is a better option. (Note that putting frustum culling into the renderer doesn't mean removing the current main world visibility system - it just means the main world system would be separate opt-in system) </details> ## Performance <details><summary>Click to expand</summary> ### Initialization Creating the skinned bounds asset for `Fox.glb` (576 verts, 22 skinned joints) takes **0.03ms**. Loading the whole glTF takes 8.7ms, so this is a **<1% increase**. ### Per-Frame The `many_foxes` example has 1000 skinned meshes, each with 22 skinned joints. Updating the skinned bounds takes **0.086ms**. This is a throughput of roughly 250,000 joints per millisecond, using two threads. <img width="2404" height="861" alt="image" src="https://github.com/user-attachments/assets/c27165ae-dc6c-4f6b-bbfb-4e211ab0263c" /> The whole animation update takes 3.67ms (where "animation update" = advancing players + graph evaluation + transform propagation). So we can kinda sorta claim that this PR increases the cost of skinned animation by roughly **3%**. But that's very hand-wavey and situation dependent. This was tested on an AMD Ryzen 7900 but with `TaskPoolOptions::with_num_threads(6)` to simulate a lower spec CPU. Comparing against a few other threading options: - Non-parallel: **0.141ms**. - 6 threads (2 compute threads): **0.086ms**. - 24 threads (15 compute threads): **0.051ms**. So the parallel iterator is better but quickly hits diminishing returns as the number of threads increases. ### Future Options The "How Does It Work" section mentions moving skinned mesh bounds into the renderer's skin extraction. Based on some microbenchmarks, I estimate this would reduce non-parallel `many_foxes` from 0.141ms to 0.049ms, so roughly 3x faster. Requiring AVX2 (to enable broadcast loads) or pre-splatting (to fake broadcast loads for SSE) would knock off another 25%. And fancier SIMD approaches could do better again. There's also approaches that trade reliability for performance. For character rigs, an effective optimization is to fold face and finger joints into a single bound on the head and hand joints. This can reduce the number of joints required by 50-80%. </details> ## FAQ <details><summary>Click to expand</summary> #### Why can't it be automatically added to any mesh? Then the glTF importer and custom mesh generators wouldn't need special logic. `bevy_mod_skinned_aabb` took the automatic approach, and I don't think the outcome was good. It needs some surprisingly fiddly and fragile logic to decide when an entity has the right combination of assets in the right loaded state. And it can never work with `RenderAssetUsages::RENDER_WORLD`. So this PR takes a more modest and manual approach. I think there's plenty of scope to generalise and automate as the asset pipeline matures. If the glTF importer becomes a purer glTF -> BSN transform, then adding skinned bounds could be a general scene/asset transform that's shared with other importers and custom mesh generators. #### Why is the data in `Mesh`? Shouldn't it go in `SkinnedMesh` or `SkinnedMeshInverseBindposes`? That might seem intuitive, but it wouldn't work in practice - the data is derived from `Mesh` alone. `SkinnedMesh` doesn't work because it's per mesh instance, so the data would be duplicated. `SkinnedMeshInverseBindposes` doesn't work because it can be shared between multiple meshes. The names are a bit misleading - `Mesh` does contain some skinning data, while `SkinnedMesh` and `SkinnedMeshInverseBindposes` are more like joint bindings one step removed from the vertex data. #### Why not put the bounds on the joint entities? This is surprisingly tricky in practice because multiple meshes can be bound to the same joint entity. So there would need to be logic that tracks the bindings and updates the bounds as meshes are added and removed. #### Why is the `DynamicSkinnedMeshBounds` component required? It's an optimisation for users who want to opt out. It might also be useful for future expansion, like adding options to approximate the bounds with an AABB attached to a single joint. #### Why are the update system and `DynamicSkinnedMeshBounds` component in `bevy_camera`? Shouldn't they be in `bevy_mesh`? `bevy_camera` is the owner and main user of `Aabb`, and already has some mesh related logic (`calculate_bounds` automatically adds an `Aabb` to mesh entities). So putting it in `bevy_camera` is consistent with the current structure. I'd agree that it's a little awkward though and could change in future. </details> ## What Do Other Engines Do? <details><summary>Click to expand</summary> - **Unreal**: Automatically uses [collision shapes](https://dev.epicgames.com/documentation/en-us/unreal-engine/physics-asset-editor-in-unreal-engine) attached to joints, which is similar to this PR in practice but fragile and inefficient. Also supports various fixed bounds options. - **Unity**: Fixed bounds attached to the root bone. Automatically calculated from animation poses or specified manually ([documentation](https://docs.unity3d.com/6000.4/Documentation/Manual/troubleshooting-skinned-mesh-renderer-visibility.html)). - **Godot**: Appears to use roughly the same method as this PR, although I didn't 100% confirm. See [`MeshStorage::mesh_get_aabb`](https://github.com/godotengine/godot/blob/fafc07335bdecacd96b548c4119fbe1f47ee5866/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp#L650) and [`RendererSceneCull::_update_instance_aabb`](https://github.com/godotengine/godot/blob/235a32ad11f40ecba26d6d9ceea8ab245c13adb0/servers/rendering/renderer_scene_cull.cpp#L1991). - **O3DE**: Fixed bounds attached to root bone, plus option to approximate the AABB from joint origins and a fudge factor. - **Northlight** (Remedy, Alan Wake 2): Specifically for vegetation, calculates bounds from joint extents on GPU ([source](https://gdcvault.com/play/1034310/Large-Scale-GPU-Based-Skinning), slide 48) An approach that's been proposed several times for Bevy is copying Unity's "fixed AABB from animation poses". I think this is more complicated and less reliable than many people expect. More complicated because linking animations to meshes can often be difficult. Less reliable because it doesn't account for ragdolls and procedural animation. But it could still be viable for for simple cases like a single self-contained glTF with basic animation. </details> --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com> |
||
|
|
a88af65738 |
Contact Shadows (#22382)
# Objective - Implement contact shadows to add fine shadow detail where shadow cascades cannot. ## Solution - Extend our existing pbr implementation using our existing raymarching functions. --- ## Showcase <img width="1824" height="1180" alt="image" src="https://github.com/user-attachments/assets/e93b79c5-c596-4a9e-b94d-20bdde1d863b" /> <img width="1824" height="1180" alt="image" src="https://github.com/user-attachments/assets/0fd7dffa-60b8-4b92-8fad-7f993d4d89dd" /> https://github.com/user-attachments/assets/e74b190d-9ae3-4aaf-97f0-b520930a0667 https://github.com/user-attachments/assets/e80ccb26-bbaa-4d25-a823-8ea12354c5b9 https://github.com/user-attachments/assets/b04f4b00-92bd-4a2f-b7dd-5157d8fbe0ab <img width="1073" height="685" alt="image" src="https://github.com/user-attachments/assets/b7629908-dd32-48db-8ee7-a4d2dd8f66c2" /> <img width="1073" height="685" alt="image" src="https://github.com/user-attachments/assets/3de0258e-9191-4180-ac57-41b32e1205bd" /> <img width="1073" height="685" alt="image" src="https://github.com/user-attachments/assets/951477f9-e9a9-426f-ae8d-18ae50cc7b85" /> <img width="1073" height="685" alt="image" src="https://github.com/user-attachments/assets/2291453c-da57-4fcc-a6b0-f60f6eac6cbb" /> <img width="1073" height="685" alt="image" src="https://github.com/user-attachments/assets/5820cdff-ea54-4294-b520-2a8d8dc24996" /> <img width="1073" height="685" alt="image" src="https://github.com/user-attachments/assets/3ea16481-7689-4e99-87e2-1589f1532e4c" /> --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com> Co-authored-by: charlotte 🌸 <charlotte.c.mcelwain@gmail.com> |
||
|
|
d431f7e139 |
Split AmbientLight into two (#21595)
# Objective For resources-as-components (#19731), structs mustn't doubly derive both `Component` and `Resource`. ## Solution Split `AmbientLight` in two: `AmbientLight` (the resource) and `AmbientLightOverride` (the component). ## Testing I initially made two structs `AmbientLightComponent` and `AmbientLightResource`, and replaced every mention with the relevant one to ensure that I didn't confuse the two. ## Notes - I don't know if the names are correct. I kept the easiest name for the resource, as that's the one most often used. - I haven't provided any conversion methods as there are already plans to replace the component variant with something else. --------- Co-authored-by: atlv <email@atlasdostal.com> |
||
|
|
f6b77e4e49 |
bevy_post_process (#20778)
# Objective Split out post process effects from bevy_core_pipeline because they are not core pipelines. ## Solution @IceSentry proposed something like this, not sure if the split is exactly as he envisioned but this seems reasonable to me. The goal is to move absolutely everything possible out of bevy_core_pipelines to unblock bevy_pbr/bevy_sprite_render compilation. Future PRs may attempt to move more little bits out. ## Testing |
||
|
|
13877fa84d |
Add a new trait to accept more types in the Val-helper functions (#20551)
# Objective - Allow the `Val`-helper functions to accept more types besides just `f32` Fixes #20549 ## Solution - Adds a new trait that can be implemented for numbers - That trait has a method that converts `self` to `f32` ## Testing - I tested it using Rust's testing framework (although I didn't leave the tests in, as I don't deem them important enough) <details> <summary>Rust test</summary> ```rust #[cfg(test)] mod tests { use super::*; #[test] fn test_val_helpers_work() { let p = px(10_u8); assert_eq!(p, Val::Px(10.0)); let p = px(10_u16); assert_eq!(p, Val::Px(10.0)); let p = px(10_u32); assert_eq!(p, Val::Px(10.0)); let p = px(10_u64); assert_eq!(p, Val::Px(10.0)); let p = px(10_u128); assert_eq!(p, Val::Px(10.0)); let p = px(10_i8); assert_eq!(p, Val::Px(10.0)); let p = px(10_i16); assert_eq!(p, Val::Px(10.0)); let p = px(10_i32); assert_eq!(p, Val::Px(10.0)); let p = px(10_i64); assert_eq!(p, Val::Px(10.0)); let p = px(10_i128); assert_eq!(p, Val::Px(10.0)); let p = px(10.3_f32); assert_eq!(p, Val::Px(10.3)); let p = px(10.6_f64); assert_eq!(p, Val::Px(10.6)); } } ``` </details> --- ## Showcase ```rust // Same as Val::Px(10.) px(10); px(10_u8); px(10.0); ``` |
||
|
|
68b848217f |
Yeet RenderAssetUsages re-export (#20498)
# Objective - Forgor to yeet this ## Solution - rember and yeet ## Testing cargo check --examples --all-features |
||
|
|
03dd839b82 |
Use bevy::camera in examples instead of bevy::render::camera re-export (#20477)
# Objective - Prepare for removing re-exports ## Solution - title ## Testing - cargo check --examples |
||
|
|
acc8f6d455 |
Stop using mesh re-exports in-repo and add bevy_mesh prelude (#20473)
# Objective - prepare to remove bevy_mesh re-export from bevy_render. This will be done in 0.18, but we might as well prepare for it now. ## Solution - Add a prelude and use bevy_mesh directly. After this pr and #20471, we will be ready. ## Testing - cargo check --examples |
||
|
|
0f75142560 |
Add test for invalid skinned meshes (#18763)
## Objective Add a test that would have caught #16929 and #18712. ## Solution The PR adds a `test_invalid_skinned_mesh` example that creates various valid and invalid skinned meshes. This is designed to catch panics via CI, and can be inspected visually. It also tests skinned meshes + motion blur.  The screenshot shows all the tests, but two are currently disabled as they cause panics. #18074 will re-enable them. ### Concerns - The test is not currently suitable for screenshot comparison. - I didn't add the test to CI. I'm a bit unsure if this should be part of the PR or a follow up discussion. - Visual inspection requires understanding why some meshes are deliberately broken and what that looks like. - I wasn't sure about naming conventions. I put `test` in the name so it's not confused with a real example. ## Testing ``` cargo run --example test_invalid_skinned_mesh ``` Tested on Win10/Nvidia, across Vulkan, WebGL/Chrome, WebGPU/Chrome. |
||
|
|
a15d152635 |
Deferred Renderer (#9258)
# Objective - Add a [Deferred Renderer](https://en.wikipedia.org/wiki/Deferred_shading) to Bevy. - This allows subsequent passes to access per pixel material information before/during shading. - Accessing this per pixel material information is needed for some features, like GI. It also makes other features (ex. Decals) simpler to implement and/or improves their capability. There are multiple approaches to accomplishing this. The deferred shading approach works well given the limitations of WebGPU and WebGL2. Motivation: [I'm working on a GI solution for Bevy](https://youtu.be/eH1AkL-mwhI) # Solution - The deferred renderer is implemented with a prepass and a deferred lighting pass. - The prepass renders opaque objects into the Gbuffer attachment (`Rgba32Uint`). The PBR shader generates a `PbrInput` in mostly the same way as the forward implementation and then [packs it into the Gbuffer](https://github.com/DGriffin91/bevy/blob/ec1465559f2c82001830e908fc02ff1d7c2efe51/crates/bevy_pbr/src/render/pbr.wgsl#L168). - The deferred lighting pass unpacks the `PbrInput` and [feeds it into the pbr() function](https://github.com/DGriffin91/bevy/blob/ec1465559f2c82001830e908fc02ff1d7c2efe51/crates/bevy_pbr/src/deferred/deferred_lighting.wgsl#L65), then outputs the shaded color data. - There is now a resource [DefaultOpaqueRendererMethod](https://github.com/DGriffin91/bevy/blob/ec1465559f2c82001830e908fc02ff1d7c2efe51/crates/bevy_pbr/src/material.rs#L599) that can be used to set the default render method for opaque materials. If materials return `None` from [opaque_render_method()](https://github.com/DGriffin91/bevy/blob/ec1465559f2c82001830e908fc02ff1d7c2efe51/crates/bevy_pbr/src/material.rs#L131) the `DefaultOpaqueRendererMethod` will be used. Otherwise, custom materials can also explicitly choose to only support Deferred or Forward by returning the respective [OpaqueRendererMethod](https://github.com/DGriffin91/bevy/blob/ec1465559f2c82001830e908fc02ff1d7c2efe51/crates/bevy_pbr/src/material.rs#L603) - Deferred materials can be used seamlessly along with both opaque and transparent forward rendered materials in the same scene. The [deferred rendering example](https://github.com/DGriffin91/bevy/blob/deferred/examples/3d/deferred_rendering.rs) does this. - The deferred renderer does not support MSAA. If any deferred materials are used, MSAA must be disabled. Both TAA and FXAA are supported. - Deferred rendering supports WebGL2/WebGPU. ## Custom deferred materials - Custom materials can support both deferred and forward at the same time. The [StandardMaterial](https://github.com/DGriffin91/bevy/blob/ec1465559f2c82001830e908fc02ff1d7c2efe51/crates/bevy_pbr/src/render/pbr.wgsl#L166) does this. So does [this example](https://github.com/DGriffin91/bevy_glowy_orb_tutorial/blob/deferred/assets/shaders/glowy.wgsl#L56). - Custom deferred materials that require PBR lighting can create a `PbrInput`, write it to the deferred GBuffer and let it be rendered by the `PBRDeferredLightingPlugin`. - Custom deferred materials that require custom lighting have two options: 1. Use the base_color channel of the `PbrInput` combined with the `STANDARD_MATERIAL_FLAGS_UNLIT_BIT` flag. [Example.](https://github.com/DGriffin91/bevy_glowy_orb_tutorial/blob/deferred/assets/shaders/glowy.wgsl#L56) (If the unlit bit is set, the base_color is stored as RGB9E5 for extra precision) 2. A Custom Deferred Lighting pass can be created, either overriding the default, or running in addition. The a depth buffer is used to limit rendering to only the required fragments for each deferred lighting pass. Materials can set their respective depth id via the [deferred_lighting_pass_id](https://github.com/DGriffin91/bevy/blob/b79182d2a32cac28c4213c2457a53ac2cc885332/crates/bevy_pbr/src/prepass/prepass_io.wgsl#L95) attachment. The custom deferred lighting pass plugin can then set [its corresponding depth](https://github.com/DGriffin91/bevy/blob/ec1465559f2c82001830e908fc02ff1d7c2efe51/crates/bevy_pbr/src/deferred/deferred_lighting.wgsl#L37). Then with the lighting pass using [CompareFunction::Equal](https://github.com/DGriffin91/bevy/blob/ec1465559f2c82001830e908fc02ff1d7c2efe51/crates/bevy_pbr/src/deferred/mod.rs#L335), only the fragments with a depth that equal the corresponding depth written in the material will be rendered. Custom deferred lighting plugins can also be created to render the StandardMaterial. The default deferred lighting plugin can be bypassed with `DefaultPlugins.set(PBRDeferredLightingPlugin { bypass: true })` --------- Co-authored-by: nickrart <nickolas.g.russell@gmail.com> |
||
|
|
cb0db07c5b |
Fix dependency of shadow mapping on the optional PrepassPlugin (#7878)
# Objective Unfortunately, there are three issues with my changes introduced by #7784. 1. The changes left some dead code. This is already taken care of here: #7875. 2. Disabling prepass causes failures because the shadow mapping relies on the `PrepassPlugin` now. 3. Custom materials use the `prepass.wgsl` shader, but this does not always define a fragment entry point. This PR fixes 2. and 3. and resolves #7879. ## Solution - Add a regression test with disabled prepass. - Split `PrepassPlugin` into two plugins: - `PrepassPipelinePlugin` contains the part that is required for the shadow mapping to work and is unconditionally added. - `PrepassPlugin` now only adds the systems and resources required for the "real" prepasses. - Add a noop fragment entry point to `prepass.wgsl`, used if `NORMAL_PASS` is not defined. Co-authored-by: Edgar Geier <geieredgar@gmail.com> |