bevy/crates/bevy_pbr/src
Sou1gh0st 3a478ad5c1
Fix lightmaps break when deferred rendering is enabled (#14599)
# Objective
- Fixes https://github.com/bevyengine/bevy/issues/13552

## Solution
- Thanks for the guidance from @DGriffin91, the current solution is to
transmit the light_map through the emissive channel to avoid increasing
the bandwidth of deferred shading.
- <del>Store lightmap sample result into G-Buffer and pass them into the
`Deferred Lighting Pipeline`, therefore we can get the correct indirect
lighting via the `apply_pbr_lighting` function.</del>
- <del>The original G-Buffer lacks storage for lightmap data, therefore
a new buffer is added. We can only use Rgba16Uint here due to the
32-byte limit on the render targets.</del>

## Testing
- Need to test all the examples that contains a prepass, with both the
forward and deferred rendering mode.
- I have tested the ones below.
- `lightmaps` (adjust the code based on the issue and check the
rendering result)
    - `transmission` (it contains a prepass)
    - `ssr` (it also uses the G-Bufffer)
    - `meshlet` (forward and deferred)
    - `pbr`

## Showcase
By updating the `lightmaps` example to use deferred rendering, this pull
request enables correct rendering result of the Cornell Box.

```
diff --git a/examples/3d/lightmaps.rs b/examples/3d/lightmaps.rs
index 564a3162b..11a748fba 100644
--- a/examples/3d/lightmaps.rs
+++ b/examples/3d/lightmaps.rs
@@ -1,12 +1,14 @@
 //! Rendering a scene with baked lightmaps.
 
-use bevy::pbr::Lightmap;
+use bevy::core_pipeline::prepass::DeferredPrepass;
+use bevy::pbr::{DefaultOpaqueRendererMethod, Lightmap};
 use bevy::prelude::*;
 
 fn main() {
     App::new()
         .add_plugins(DefaultPlugins)
         .insert_resource(AmbientLight::NONE)
+        .insert_resource(DefaultOpaqueRendererMethod::deferred())
         .add_systems(Startup, setup)
         .add_systems(Update, add_lightmaps_to_meshes)
         .run();
@@ -19,10 +21,12 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
         ..default()
     });
 
-    commands.spawn(Camera3dBundle {
-        transform: Transform::from_xyz(-278.0, 273.0, 800.0),
-        ..default()
-    });
+    commands
+        .spawn(Camera3dBundle {
+            transform: Transform::from_xyz(-278.0, 273.0, 800.0),
+            ..default()
+        })
+        .insert(DeferredPrepass);
 }
 
 fn add_lightmaps_to_meshes(
```

<img width="1280" alt="image"
src="https://github.com/user-attachments/assets/17fd3367-61cc-4c23-b956-e7cfc751af3c">

## Emissive Issue
**The emissive light object appears incorrectly rendered because the
alpha channel of emission is set to 1 in deferred rendering and 0 in
forward rendering, leading to different emissive light result. Could
this be a bug?**

```wgsl
// pbr_deferred_functions.wgsl - pbr_input_from_deferred_gbuffer
let emissive = rgb9e5::rgb9e5_to_vec3_(gbuffer.g);
if ((pbr.material.flags & STANDARD_MATERIAL_FLAGS_UNLIT_BIT) != 0u) {
    pbr.material.base_color = vec4(emissive, 1.0);
    pbr.material.emissive = vec4(vec3(0.0), 1.0);
} else {
    pbr.material.base_color = vec4(pow(base_rough.rgb, vec3(2.2)), 1.0);
    pbr.material.emissive = vec4(emissive, 1.0);
}

// pbr_functions.wgsl - apply_pbr_lighting
emissive_light = emissive_light * mix(1.0, view_bindings::view.exposure, emissive.a);
```

---------

Co-authored-by: JMS55 <47158642+JMS55@users.noreply.github.com>
2024-10-18 23:18:11 +00:00
..
cluster Implement WorldQuery for MainWorld and RenderWorld components (#15745) 2024-10-13 20:58:46 +00:00
deferred Fix lightmaps break when deferred rendering is enabled (#14599) 2024-10-18 23:18:11 +00:00
light Synchronize removed components with the render world (#15582) 2024-10-08 22:23:17 +00:00
light_probe Implement WorldQuery for MainWorld and RenderWorld components (#15745) 2024-10-13 20:58:46 +00:00
lightmap Type safe retained render world (#15756) 2024-10-10 18:47:04 +00:00
meshlet Type safe retained render world (#15756) 2024-10-10 18:47:04 +00:00
prepass Fix lightmaps break when deferred rendering is enabled (#14599) 2024-10-18 23:18:11 +00:00
render Despawn unused light-view entity (#15902) 2024-10-15 13:54:09 +00:00
ssao Fix *most* clippy lints (#15906) 2024-10-14 20:52:35 +00:00
ssr Migrate reflection probes to required components (#15737) 2024-10-08 23:59:27 +00:00
volumetric_fog Implement WorldQuery for MainWorld and RenderWorld components (#15745) 2024-10-13 20:58:46 +00:00
bundle.rs Type safe retained render world (#15756) 2024-10-10 18:47:04 +00:00
extended_material.rs Simpler lint fixes: makes ci lints work but disables a lint for now (#15376) 2024-09-24 11:42:59 +00:00
fog.rs Migrate cameras to required components (#15641) 2024-10-05 01:59:52 +00:00
lib.rs Revert default mesh materials (#15930) 2024-10-15 19:47:40 +00:00
material.rs Revert default mesh materials (#15930) 2024-10-15 19:47:40 +00:00
mesh_material.rs Revert default mesh materials (#15930) 2024-10-15 19:47:40 +00:00
parallax.rs bevy_reflect: FromReflect Ergonomics Implementation (#6056) 2023-06-29 01:31:34 +00:00
pbr_material.rs Fix typos from greyscale -> grayscale (#15947) 2024-10-16 12:30:23 +00:00
wireframe.rs Revert "Have EntityCommands methods consume self for easier chaining" (#15523) 2024-10-02 12:47:26 +00:00