Skip to content
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

Deferred Renderer #9258

Merged
merged 159 commits into from
Oct 12, 2023
Merged
Show file tree
Hide file tree
Changes from 98 commits
Commits
Show all changes
159 commits
Select commit Hold shift + click to select a range
dcf8017
Move texture sample out of branch
DGriffin91 Jun 28, 2022
9e406c7
use tonemapping in array_texture example
DGriffin91 Jun 29, 2022
c2209a6
Revert "use tonemapping in array_texture example"
DGriffin91 Jun 29, 2022
f2dbfdc
init deferred
DGriffin91 May 31, 2023
52a38eb
remove temp file
DGriffin91 May 31, 2023
ea6ce6b
add dither and tonemap in shader
DGriffin91 May 31, 2023
b6f06b0
get forward and prepass without deferred working again
DGriffin91 Jun 1, 2023
5f1d8fc
get shadows working
DGriffin91 Jun 1, 2023
30c8ed8
use rgb9e5 for emissive
DGriffin91 Jun 1, 2023
764205f
make deferred and forward work together
DGriffin91 Jun 1, 2023
90d97aa
reuse mesh_view_layout_entries
DGriffin91 Jun 1, 2023
5390866
add stencil reference for selecting deferred lighting pass
DGriffin91 Jun 2, 2023
1ce6ad2
don't fill pixel data for depth/stencil fallback
DGriffin91 Jun 2, 2023
0d37110
make deferred lighting stencil reference configurable
DGriffin91 Jun 2, 2023
b497801
consolidate depth format and fallback
DGriffin91 Jun 2, 2023
1a8f03b
more deferred feature parity
DGriffin91 Jun 3, 2023
0acbfe8
add specific deferred flags
DGriffin91 Jun 3, 2023
6449316
move render method extract plugin and normalize normals
DGriffin91 Jun 3, 2023
5cd1ec8
relocate deferred files
DGriffin91 Jun 3, 2023
08303b7
include normals in deferred gbuffer
DGriffin91 Jun 3, 2023
ec28a8b
encode base color as srgb, setup test in forward pbr
DGriffin91 Jun 4, 2023
79807e2
make webgl work
DGriffin91 Jun 4, 2023
76a4a7e
pack gbuffer differently for webgl
DGriffin91 Jun 4, 2023
84c2913
tweak normals rounding
DGriffin91 Jun 4, 2023
3623945
use DEFAULT_PBR_DEFERRED_LIGHTING_STENCIL_REFERENCE for material default
DGriffin91 Jun 4, 2023
a6ad3b3
move prepass vertex and fragment io into separate file
DGriffin91 Jun 4, 2023
0822760
handle unlit
DGriffin91 Jun 5, 2023
5793290
always use full material input
DGriffin91 Jun 5, 2023
dfa166c
simplify pbr_input_from_deferred_gbuffer, add parallax to example
DGriffin91 Jun 5, 2023
f16d48f
Merge remote-tracking branch 'upstream/main' into deferred
DGriffin91 Jun 5, 2023
37d7fad
merge deferred with forward pbr frag shader
DGriffin91 Jun 5, 2023
31963b5
Merge remote-tracking branch 'origin/main' into deferred
DGriffin91 Jun 5, 2023
5994fdd
add ui to example
DGriffin91 Jun 7, 2023
d18d316
don't use bevy_internal path
DGriffin91 Jun 7, 2023
7dcc731
fix taa depth texture
DGriffin91 Jun 12, 2023
42c6f1e
Merge remote-tracking branch 'origin/main' into deferred
DGriffin91 Jun 13, 2023
5d5cd67
fix deferred/motion vector prepass order
DGriffin91 Jun 13, 2023
476f483
put deferred lighting pass after main pass start but before opaque pass
DGriffin91 Jun 15, 2023
67a3967
use vec4 for out.normal
DGriffin91 Jun 15, 2023
b616599
make a way to BypassPBRDeferredLightingPlugin
DGriffin91 Jun 15, 2023
e3d5e59
make deferred light pass use the layout it defines instead of from me…
DGriffin91 Jun 15, 2023
dc67cde
use DeferredLightingBindGroup instead of MeshViewBindGroup
DGriffin91 Jun 15, 2023
91e00d2
use pub const for deferred lighting node name
DGriffin91 Jun 15, 2023
790af5c
add motion vector output from deferred pbr
DGriffin91 Jun 16, 2023
0c4088c
prefix wgsl transformation names to avoid collision
DGriffin91 Jun 16, 2023
b7f5f0d
missed one
DGriffin91 Jun 16, 2023
87a14d3
move pbr input to pbr types for better accessibility
DGriffin91 Jun 16, 2023
cd3e0de
fix alpha discard
DGriffin91 Jun 24, 2023
0c18601
use standard rgb9e5 bit order, update octa encode/decode
DGriffin91 Jun 26, 2023
2c6de16
Merge commit 'bb59509d44d2979e4b91bd0f998c047f16b89dd0' into deferred
DGriffin91 Jun 27, 2023
f42607d
merge up to bb59509
DGriffin91 Jun 27, 2023
901a3c9
Merge commit '0f4d16aa3ce9a7937d253313b6f821c6eeb09c10' into deferred
DGriffin91 Jun 27, 2023
87a6a30
merge up to 0f4d16a
DGriffin91 Jun 27, 2023
4d2f7eb
fix ssao
DGriffin91 Jun 27, 2023
cd3e2bb
Merge commit '10f5c9206847ae01b8dc833c2680562e7bd46664' into deferred
DGriffin91 Jul 16, 2023
41761ff
merge in new naga oil stuff
DGriffin91 Jul 16, 2023
ef0e49f
Merge commit '8ba9571eedada4f3ff43cdf1402670b7fe7c280d' into deferred
DGriffin91 Jul 16, 2023
05c09d5
update to bevy 0.11
DGriffin91 Jul 16, 2023
aa31d9e
Merge remote-tracking branch 'origin/main' into deferred
DGriffin91 Jul 16, 2023
052ab30
mesh_view_bindings todos
DGriffin91 Jul 16, 2023
937c733
fix sign issue
DGriffin91 Jul 19, 2023
3be1ff9
Merge remote-tracking branch 'origin' into deferred
DGriffin91 Jul 19, 2023
2ab66f2
misc docs/wording tweaks
DGriffin91 Jul 21, 2023
bedd5ab
rename PBRDeferredLightingPlugin
DGriffin91 Jul 21, 2023
b73cefa
get ssao working with deferred
DGriffin91 Jul 21, 2023
6afb442
include prepass in ssao node edges
DGriffin91 Jul 21, 2023
2e37811
don't use depth format with stencil for shadows
DGriffin91 Jul 22, 2023
689f44b
fix webgl
DGriffin91 Jul 22, 2023
eb580ee
Merge remote-tracking branch 'origin' into deferred
DGriffin91 Jul 22, 2023
9c4496f
use MeshViewBindGroup in deferred lighting pass
DGriffin91 Jul 22, 2023
9d9b8d0
nits
DGriffin91 Jul 24, 2023
33252aa
bypass directly in PBRDeferredLightingPlugin
DGriffin91 Jul 24, 2023
a472635
don't include Deferred when set to Forward+Prepass in example
DGriffin91 Jul 24, 2023
03b1a4c
try to make ci happy
DGriffin91 Jul 24, 2023
ab2126f
try harder to make ci happy
DGriffin91 Jul 24, 2023
0057d9a
use frag_coord.z from PbrInput directly for depth
DGriffin91 Aug 3, 2023
03781c9
copy over rgb9e5 improvements
DGriffin91 Aug 3, 2023
31f6a66
don't set view_formats unnecessarily
DGriffin91 Aug 10, 2023
89b37e4
add docs for deferred prepass tex
DGriffin91 Aug 10, 2023
be9d2cd
rename PbrDeferredLightingPlugin
DGriffin91 Aug 10, 2023
b0d0f7f
add docs for DeferredPrepass
DGriffin91 Aug 10, 2023
c91a4f6
separate out depth stencil state into func
DGriffin91 Aug 10, 2023
7ff66d4
improve material props deferred naming
DGriffin91 Aug 10, 2023
e30a352
nits
DGriffin91 Aug 10, 2023
2871b1a
use Color::BLACK instead manually setting color
DGriffin91 Aug 11, 2023
c5a299b
When deferred is used with msaa, disable and warn instead of panic
DGriffin91 Aug 13, 2023
7070e06
add PbrDeferredLightingPlugin in PbrPlugin
DGriffin91 Aug 13, 2023
192090b
make core3d depth format configurable at runtime
DGriffin91 Aug 13, 2023
c16911d
manually define extractBits for webgl
DGriffin91 Aug 13, 2023
9963c44
Merge remote-tracking branch 'origin' into deferred
DGriffin91 Aug 13, 2023
41c043b
add per_object_binding_dynamic_offset to prepass
DGriffin91 Aug 13, 2023
121ce50
add WEBGL shaderdef to MeshPipeline
DGriffin91 Aug 13, 2023
40a4fb2
use None for BlendState instead of REPLACE
DGriffin91 Aug 13, 2023
6ca0b40
make ci happier
DGriffin91 Aug 13, 2023
4143efb
don't use builtin extractBits, it's also not working on dx12
DGriffin91 Aug 15, 2023
f7321dd
don't setup DepthStencilState when not using stencil
DGriffin91 Aug 15, 2023
45eb48e
add taa fix from 9462
DGriffin91 Aug 17, 2023
0513e2a
make DeferredLightingNode pub
DGriffin91 Aug 17, 2023
d813d56
nits
DGriffin91 Sep 4, 2023
ff2683d
Merge commit 'e8b38925174cea58c08877a7b410443dafe918ce' into deferred
DGriffin91 Sep 5, 2023
89317ab
Merge commit '4f1d9a63152589d5286647e68cc3ce0e67f1838c' into deferred
DGriffin91 Sep 5, 2023
dcf9101
remove per_object_binding_dynamic_offset
DGriffin91 Sep 5, 2023
34781d2
Merge remote-tracking branch 'upstream/main' into deferred
DGriffin91 Sep 5, 2023
44e9295
optionally query for deferred render phases
DGriffin91 Sep 5, 2023
43f273a
maybe make ci happy
DGriffin91 Sep 5, 2023
1b52d20
initial switch from stencil compare to depth
DGriffin91 Sep 5, 2023
7a78054
get dx12 working
DGriffin91 Sep 5, 2023
b79182d
Make lighting pass id configurable again.
DGriffin91 Sep 6, 2023
3316654
add clarifying comments regarding unorm conversion
DGriffin91 Sep 6, 2023
4038c37
more comments
DGriffin91 Sep 6, 2023
c03ef23
fix webgl2 deferred clearing issue
DGriffin91 Sep 6, 2023
665492f
centralize mesh_view_bindings
DGriffin91 Sep 6, 2023
adfffea
nits
DGriffin91 Sep 6, 2023
76e5790
ci
DGriffin91 Sep 6, 2023
f33b874
Merge remote-tracking branch 'upstream/main' into deferred
DGriffin91 Sep 7, 2023
562fec9
Merge remote-tracking branch 'upstream/main' into deferred
DGriffin91 Sep 7, 2023
ec14655
update for assetsv2
DGriffin91 Sep 7, 2023
3e89aff
Update examples/3d/deferred_rendering.rs
DGriffin91 Sep 23, 2023
8d0e319
Merge remote-tracking branch 'upstream/main' into deferred
DGriffin91 Sep 28, 2023
c475fa2
update phase items with batch & offset
DGriffin91 Sep 28, 2023
362af7a
imagine not checking for warnings before pushing
DGriffin91 Sep 28, 2023
83c6bb2
nits
DGriffin91 Oct 8, 2023
dab7ff5
Merge remote-tracking branch 'upstream/main' into deferred
DGriffin91 Oct 8, 2023
e9022bd
update to include SHADOW_FILTER_METHOD
DGriffin91 Oct 8, 2023
f284433
use LIGHTING_DEPTH_ID directly in default
DGriffin91 Oct 9, 2023
5347950
Merge remote-tracking branch 'upstream/main' into deferred
DGriffin91 Oct 9, 2023
7856085
oh god the lifetimes why
DGriffin91 Oct 9, 2023
fc8dca2
nits
DGriffin91 Oct 9, 2023
02c60fb
use optimized octahedral encode/decode
DGriffin91 Oct 10, 2023
d7fbc69
use get_instance_index
DGriffin91 Oct 10, 2023
231a650
clean up imports
DGriffin91 Oct 10, 2023
73b639d
update node names
DGriffin91 Oct 10, 2023
0968b9f
only use out inside DEFERRED_PREPASS
DGriffin91 Oct 11, 2023
942211c
add auto to OpaqueRendererMethod
DGriffin91 Oct 11, 2023
a7ce0b1
clarify create_texture_with_data
DGriffin91 Oct 11, 2023
67f2846
misc consistent naming
DGriffin91 Oct 11, 2023
cc2586b
remove unused shadow pass key
DGriffin91 Oct 11, 2023
f38bc1d
use TextureFormat::bevy_default()
DGriffin91 Oct 11, 2023
7599c3c
keep attachment count consistent
DGriffin91 Oct 11, 2023
f925875
reuse DrawPrepass draw command
DGriffin91 Oct 11, 2023
a58d7d2
remove redundant shader defs
DGriffin91 Oct 11, 2023
b58f33e
make ci happy
DGriffin91 Oct 11, 2023
33e542a
pretend I don't know about running ci locally
DGriffin91 Oct 11, 2023
9e4d37f
use octahedral funcs from bevy_pbr::utils
DGriffin91 Oct 11, 2023
df32a99
make auto render method unreachable for prepared material
DGriffin91 Oct 11, 2023
3eecd42
typo
DGriffin91 Oct 11, 2023
28d6750
improve docs
DGriffin91 Oct 12, 2023
865eb1f
MOTION_VECTOR_PREPASS_OR_DEFERRED_PREPASS
DGriffin91 Oct 12, 2023
5e84bbd
add END_PRE_PASSES sync point
DGriffin91 Oct 12, 2023
f7b4d89
rename to END_PREPASSES
DGriffin91 Oct 12, 2023
47cd785
Apply all material flags in both lit and unlit cases
DGriffin91 Oct 12, 2023
7168a57
don't use bevy_internal in examples
DGriffin91 Oct 12, 2023
1c983e2
Merge remote-tracking branch 'upstream/main' into deferred
DGriffin91 Oct 12, 2023
96fb4c8
fix typo
DGriffin91 Oct 12, 2023
beed2ff
make wgpu 0.17 happy
DGriffin91 Oct 12, 2023
5049944
Assign surface props, even when unlit
DGriffin91 Oct 12, 2023
b2fcfad
put vertex colors in the prepass
DGriffin91 Oct 12, 2023
3194fe9
make id tex size always match prepass textures
DGriffin91 Oct 12, 2023
c80be7d
Merge remote-tracking branch 'upstream/main' into deferred
DGriffin91 Oct 12, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,16 @@ description = "Illustrates bloom configuration using HDR and emissive materials"
category = "3D Rendering"
wasm = true

[[example]]
name = "deferred_rendering"
path = "examples/3d/deferred_rendering.rs"

[package.metadata.example.deferred_rendering]
name = "Deferred Rendering"
description = "Renders meshes with both forward and deferred pipelines"
category = "3D Rendering"
wasm = true

[[example]]
name = "load_gltf"
path = "examples/3d/load_gltf.rs"
Expand Down
4 changes: 2 additions & 2 deletions assets/shaders/array_texture.wgsl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#import bevy_pbr::mesh_vertex_output MeshVertexOutput
#import bevy_pbr::mesh_view_bindings view
#import bevy_pbr::pbr_types STANDARD_MATERIAL_FLAGS_DOUBLE_SIDED_BIT
#import bevy_pbr::pbr_types STANDARD_MATERIAL_FLAGS_DOUBLE_SIDED_BIT, PbrInput, pbr_input_new
#import bevy_core_pipeline::tonemapping tone_mapping
#import bevy_pbr::pbr_functions as fns

Expand All @@ -18,7 +18,7 @@ fn fragment(

// Prepare a 'processed' StandardMaterial by sampling all textures to resolve
// the material members
var pbr_input: fns::PbrInput = fns::pbr_input_new();
var pbr_input: PbrInput = pbr_input_new();

pbr_input.material.base_color = textureSample(my_array_texture, my_array_texture_sampler, mesh.uv, layer);
#ifdef VERTEX_COLORS
Expand Down
29 changes: 18 additions & 11 deletions crates/bevy_core_pipeline/src/core_3d/main_opaque_pass_3d_node.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{
clear_color::{ClearColor, ClearColorConfig},
core_3d::{Camera3d, Opaque3d},
prepass::{DepthPrepass, MotionVectorPrepass, NormalPrepass},
prepass::{DeferredPrepass, DepthPrepass, MotionVectorPrepass, NormalPrepass},
skybox::{SkyboxBindGroup, SkyboxPipelineId},
};
use bevy_ecs::{prelude::*, query::QueryItem};
Expand Down Expand Up @@ -34,6 +34,7 @@ impl ViewNode for MainOpaquePass3dNode {
Option<&'static DepthPrepass>,
Option<&'static NormalPrepass>,
Option<&'static MotionVectorPrepass>,
Option<&'static DeferredPrepass>,
Option<&'static SkyboxPipelineId>,
Option<&'static SkyboxBindGroup>,
&'static ViewUniformOffset,
Expand All @@ -53,12 +54,24 @@ impl ViewNode for MainOpaquePass3dNode {
depth_prepass,
normal_prepass,
motion_vector_prepass,
deferred_prepass,
skybox_pipeline,
skybox_bind_group,
view_uniform_offset,
): QueryItem<Self::ViewQuery>,
world: &World,
) -> Result<(), NodeRunError> {
let load = if deferred_prepass.is_none() {
match camera_3d.clear_color {
ClearColorConfig::Default => LoadOp::Clear(world.resource::<ClearColor>().0.into()),
ClearColorConfig::Custom(color) => LoadOp::Clear(color.into()),
ClearColorConfig::None => LoadOp::Load,
}
} else {
// If the deferred pass has run, don't clear again in this pass.
DGriffin91 marked this conversation as resolved.
Show resolved Hide resolved
LoadOp::Load
};

// Run the opaque pass, sorted front-to-back
// NOTE: Scoped to drop the mutable borrow of render_context
#[cfg(feature = "trace")]
Expand All @@ -69,23 +82,17 @@ impl ViewNode for MainOpaquePass3dNode {
label: Some("main_opaque_pass_3d"),
// NOTE: The opaque pass loads the color
// buffer as well as writing to it.
color_attachments: &[Some(target.get_color_attachment(Operations {
load: match camera_3d.clear_color {
ClearColorConfig::Default => {
LoadOp::Clear(world.resource::<ClearColor>().0.into())
}
ClearColorConfig::Custom(color) => LoadOp::Clear(color.into()),
ClearColorConfig::None => LoadOp::Load,
},
store: true,
}))],
color_attachments: &[Some(
target.get_color_attachment(Operations { load, store: true }),
)],
depth_stencil_attachment: Some(RenderPassDepthStencilAttachment {
view: &depth.view,
// NOTE: The opaque main pass loads the depth buffer and possibly overwrites it
depth_ops: Some(Operations {
load: if depth_prepass.is_some()
|| normal_prepass.is_some()
|| motion_vector_prepass.is_some()
|| deferred_prepass.is_some()
{
// if any prepass runs, it will generate a depth buffer so we should use it,
// even if only the normal_prepass is used.
Expand Down
131 changes: 121 additions & 10 deletions crates/bevy_core_pipeline/src/core_3d/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub mod graph {
pub mod node {
pub const MSAA_WRITEBACK: &str = "msaa_writeback";
pub const PREPASS: &str = "prepass";
pub const DEFERRED: &str = "deferred";
pub const START_MAIN_PASS: &str = "start_main_pass";
pub const MAIN_OPAQUE_PASS: &str = "main_opaque_pass";
pub const MAIN_TRANSPARENT_PASS: &str = "main_transparent_pass";
Expand All @@ -24,17 +25,27 @@ pub mod graph {
}
pub const CORE_3D: &str = graph::NAME;

#[derive(Resource, ExtractResource, Clone)]
pub struct Core3DDepthFormat(pub TextureFormat);
DGriffin91 marked this conversation as resolved.
Show resolved Hide resolved

impl Default for Core3DDepthFormat {
fn default() -> Self {
Core3DDepthFormat(TextureFormat::Depth32Float)
}
}

use std::cmp::Reverse;

pub use camera_3d::*;
pub use main_opaque_pass_3d_node::*;
pub use main_transparent_pass_3d_node::*;

use bevy_app::{App, Plugin};
use bevy_app::{App, Plugin, PostUpdate};
use bevy_ecs::prelude::*;
use bevy_render::{
camera::{Camera, ExtractedCamera},
extract_component::ExtractComponentPlugin,
extract_resource::{ExtractResource, ExtractResourcePlugin},
prelude::Msaa,
render_graph::{EmptyNode, RenderGraphApp, ViewNodeRunner},
render_phase::{
Expand All @@ -46,16 +57,20 @@ use bevy_render::{
TextureUsages,
},
renderer::RenderDevice,
settings::WgpuFeatures,
texture::TextureCache,
view::ViewDepthTexture,
Extract, ExtractSchedule, Render, RenderApp, RenderSet,
};
use bevy_utils::{FloatOrd, HashMap};
use bevy_utils::{tracing::warn, FloatOrd, HashMap};

use crate::{
deferred::{
node::DeferredNode, AlphaMask3dDeferred, Opaque3dDeferred, DEFERRED_PREPASS_FORMAT,
},
prepass::{
node::PrepassNode, AlphaMask3dPrepass, DepthPrepass, MotionVectorPrepass, NormalPrepass,
Opaque3dPrepass, ViewPrepassTextures, DEPTH_PREPASS_FORMAT, MOTION_VECTOR_PREPASS_FORMAT,
node::PrepassNode, AlphaMask3dPrepass, DeferredPrepass, DepthPrepass, MotionVectorPrepass,
NormalPrepass, Opaque3dPrepass, ViewPrepassTextures, MOTION_VECTOR_PREPASS_FORMAT,
NORMAL_PREPASS_FORMAT,
},
skybox::SkyboxPlugin,
Expand All @@ -67,9 +82,15 @@ pub struct Core3dPlugin;

impl Plugin for Core3dPlugin {
fn build(&self, app: &mut App) {
app.register_type::<Camera3d>()
app.init_resource::<Core3DDepthFormat>()
.register_type::<Camera3d>()
.register_type::<Camera3dDepthLoadOp>()
.add_plugins((SkyboxPlugin, ExtractComponentPlugin::<Camera3d>::default()));
.add_plugins((
SkyboxPlugin,
ExtractComponentPlugin::<Camera3d>::default(),
ExtractResourcePlugin::<Core3DDepthFormat>::default(),
))
.add_systems(PostUpdate, (check_msaa, check_depth_format));

let render_app = match app.get_sub_app_mut(RenderApp) {
Ok(render_app) => render_app,
Expand All @@ -82,6 +103,8 @@ impl Plugin for Core3dPlugin {
.init_resource::<DrawFunctions<Transparent3d>>()
.init_resource::<DrawFunctions<Opaque3dPrepass>>()
.init_resource::<DrawFunctions<AlphaMask3dPrepass>>()
.init_resource::<DrawFunctions<Opaque3dDeferred>>()
.init_resource::<DrawFunctions<AlphaMask3dDeferred>>()
.add_systems(ExtractSchedule, extract_core_3d_camera_phases)
.add_systems(ExtractSchedule, extract_camera_prepass_phase)
.add_systems(
Expand All @@ -98,13 +121,16 @@ impl Plugin for Core3dPlugin {
sort_phase_system::<Transparent3d>.in_set(RenderSet::PhaseSort),
sort_phase_system::<Opaque3dPrepass>.in_set(RenderSet::PhaseSort),
sort_phase_system::<AlphaMask3dPrepass>.in_set(RenderSet::PhaseSort),
sort_phase_system::<Opaque3dDeferred>.in_set(RenderSet::PhaseSort),
sort_phase_system::<AlphaMask3dDeferred>.in_set(RenderSet::PhaseSort),
),
);

use graph::node::*;
render_app
.add_render_sub_graph(CORE_3D)
.add_render_graph_node::<ViewNodeRunner<PrepassNode>>(CORE_3D, PREPASS)
.add_render_graph_node::<ViewNodeRunner<DeferredNode>>(CORE_3D, DEFERRED)
.add_render_graph_node::<EmptyNode>(CORE_3D, START_MAIN_PASS)
.add_render_graph_node::<ViewNodeRunner<MainOpaquePass3dNode>>(
CORE_3D,
Expand All @@ -122,6 +148,7 @@ impl Plugin for Core3dPlugin {
CORE_3D,
&[
PREPASS,
DEFERRED,
START_MAIN_PASS,
MAIN_OPAQUE_PASS,
MAIN_TRANSPARENT_PASS,
Expand Down Expand Up @@ -297,12 +324,14 @@ pub fn extract_camera_prepass_phase(
Option<&DepthPrepass>,
Option<&NormalPrepass>,
Option<&MotionVectorPrepass>,
Option<&DeferredPrepass>,
),
With<Camera3d>,
>,
>,
) {
for (entity, camera, depth_prepass, normal_prepass, motion_vector_prepass) in cameras_3d.iter()
for (entity, camera, depth_prepass, normal_prepass, motion_vector_prepass, deferred_prepass) in
cameras_3d.iter()
{
if camera.is_active {
let mut entity = commands.get_or_spawn(entity);
Expand All @@ -317,6 +346,13 @@ pub fn extract_camera_prepass_phase(
));
}

if deferred_prepass.is_some() {
entity.insert((
RenderPhase::<Opaque3dDeferred>::default(),
RenderPhase::<AlphaMask3dDeferred>::default(),
));
}

if depth_prepass.is_some() {
entity.insert(DepthPrepass);
}
Expand All @@ -326,12 +362,16 @@ pub fn extract_camera_prepass_phase(
if motion_vector_prepass.is_some() {
entity.insert(MotionVectorPrepass);
}
if deferred_prepass.is_some() {
entity.insert(DeferredPrepass);
}
}
}
}

pub fn prepare_core_3d_depth_textures(
mut commands: Commands,
depth_format: Res<Core3DDepthFormat>,
mut texture_cache: ResMut<TextureCache>,
msaa: Res<Msaa>,
render_device: Res<RenderDevice>,
Expand Down Expand Up @@ -374,7 +414,7 @@ pub fn prepare_core_3d_depth_textures(
sample_count: msaa.samples(),
dimension: TextureDimension::D2,
// PERF: vulkan docs recommend using 24 bit depth for better performance
DGriffin91 marked this conversation as resolved.
Show resolved Hide resolved
format: TextureFormat::Depth32Float,
format: depth_format.0,
usage,
view_formats: &[],
};
Expand All @@ -390,9 +430,53 @@ pub fn prepare_core_3d_depth_textures(
}
}

// Disable msaa and warn if using deferred rendering
DGriffin91 marked this conversation as resolved.
Show resolved Hide resolved
pub fn check_msaa(
mut msaa: ResMut<Msaa>,
views_3d: Query<Entity, (With<Camera>, With<DeferredPrepass>)>,
) {
if !views_3d.is_empty() {
match *msaa {
Msaa::Off => (),
_ => {
warn!("MSAA is incompatible with deferred rendering and has been disabled.");
*msaa = Msaa::Off;
}
};
}
}

// Automatically selects a supported depth stencil format if required.
pub fn check_depth_format(
DGriffin91 marked this conversation as resolved.
Show resolved Hide resolved
render_device: Option<Res<RenderDevice>>,
mut depth_format: ResMut<Core3DDepthFormat>,
views_3d: Query<Entity, (With<Camera>, With<DeferredPrepass>)>,
DGriffin91 marked this conversation as resolved.
Show resolved Hide resolved
) {
if let Some(render_device) = render_device {
if !views_3d.is_empty() {
match depth_format.0 {
TextureFormat::Depth24PlusStencil8 | TextureFormat::Depth32FloatStencil8 => (),
_ => {
let prev_depth_format = depth_format.0;
if render_device
.features()
.contains(WgpuFeatures::DEPTH32FLOAT_STENCIL8)
{
depth_format.0 = TextureFormat::Depth32FloatStencil8;
} else {
depth_format.0 = TextureFormat::Depth24PlusStencil8;
}
warn!("Deferred rendering requires a depth stencil format. Changing depth format from {:?} to {:?}.", prev_depth_format, depth_format.0);
}
}
}
}
}

// Prepares the textures used by the prepass
pub fn prepare_prepass_textures(
mut commands: Commands,
depth_format: Res<Core3DDepthFormat>,
mut texture_cache: ResMut<TextureCache>,
msaa: Res<Msaa>,
render_device: Res<RenderDevice>,
Expand All @@ -403,6 +487,7 @@ pub fn prepare_prepass_textures(
Option<&DepthPrepass>,
Option<&NormalPrepass>,
Option<&MotionVectorPrepass>,
Option<&DeferredPrepass>,
),
(
With<RenderPhase<Opaque3dPrepass>>,
Expand All @@ -412,8 +497,11 @@ pub fn prepare_prepass_textures(
) {
let mut depth_textures = HashMap::default();
let mut normal_textures = HashMap::default();
let mut deferred_textures = HashMap::default();
let mut motion_vectors_textures = HashMap::default();
for (entity, camera, depth_prepass, normal_prepass, motion_vector_prepass) in &views_3d {
for (entity, camera, depth_prepass, normal_prepass, motion_vector_prepass, deferred_prepass) in
&views_3d
{
let Some(physical_target_size) = camera.physical_target_size else {
continue;
};
Expand All @@ -434,7 +522,7 @@ pub fn prepare_prepass_textures(
mip_level_count: 1,
sample_count: msaa.samples(),
dimension: TextureDimension::D2,
format: DEPTH_PREPASS_FORMAT,
format: depth_format.0,
usage: TextureUsages::COPY_DST
| TextureUsages::RENDER_ATTACHMENT
| TextureUsages::TEXTURE_BINDING,
Expand Down Expand Up @@ -489,10 +577,33 @@ pub fn prepare_prepass_textures(
.clone()
});

let cached_deferred_texture = deferred_prepass.is_some().then(|| {
deferred_textures
.entry(camera.target.clone())
.or_insert_with(|| {
texture_cache.get(
&render_device,
TextureDescriptor {
label: Some("prepass_deferred_texture"),
size,
mip_level_count: 1,
sample_count: 1,
dimension: TextureDimension::D2,
format: DEFERRED_PREPASS_FORMAT,
usage: TextureUsages::RENDER_ATTACHMENT
| TextureUsages::TEXTURE_BINDING,
view_formats: &[],
},
)
})
.clone()
});

commands.entity(entity).insert(ViewPrepassTextures {
depth: cached_depth_texture,
normal: cached_normals_texture,
motion_vectors: cached_motion_vectors_texture,
deferred: cached_deferred_texture,
size,
});
}
Expand Down
Loading