diff --git a/Cargo.toml b/Cargo.toml index 8963b14..cc2d760 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ bevy = { version = "0.6", default-features = false, features = [ "bevy_render", "bevy_pbr" ] } +wgpu = { version = "0.12.0", features = ["spirv"] } itertools = "0.10" [dev-dependencies] diff --git a/src/deferred.rs b/src/deferred.rs index 5ead055..25d6245 100644 --- a/src/deferred.rs +++ b/src/deferred.rs @@ -283,14 +283,10 @@ impl render_graph::Node for DeferredPassNode { { let pass_descriptor = RenderPassDescriptor { label: Some("deferred_opaque_pass"), - color_attachments: &[RenderPassColorAttachment { - view: &overlay.albedo, - resolve_target: Some(&overlay.albedo_resolve), - ops: Operations { - load: LoadOp::Clear(Color::NONE.into()), - store: true, - }, - }], + color_attachments: &[overlay.albedo_color_attachment(Operations { + load: LoadOp::Clear(Color::NONE.into()), + store: true, + })], depth_stencil_attachment: Some(RenderPassDepthStencilAttachment { view: &overlay.albedo_depth.default_view, depth_ops: Some(Operations { @@ -320,14 +316,10 @@ impl render_graph::Node for DeferredPassNode { { let pass_descriptor = RenderPassDescriptor { label: Some("deferred_alpha_mask_pass"), - color_attachments: &[RenderPassColorAttachment { - view: &overlay.albedo, - resolve_target: Some(&overlay.albedo_resolve), - ops: Operations { - load: LoadOp::Load, - store: true, - }, - }], + color_attachments: &[overlay.albedo_color_attachment(Operations { + load: LoadOp::Load, + store: true, + })], depth_stencil_attachment: Some(RenderPassDepthStencilAttachment { view: &overlay.albedo_depth.default_view, depth_ops: Some(Operations { @@ -357,14 +349,10 @@ impl render_graph::Node for DeferredPassNode { { let pass_descriptor = RenderPassDescriptor { label: Some("deferred_transparent_pass"), - color_attachments: &[RenderPassColorAttachment { - view: &overlay.albedo, - resolve_target: Some(&overlay.albedo_resolve), - ops: Operations { - load: LoadOp::Load, - store: true, - }, - }], + color_attachments: &[overlay.albedo_color_attachment(Operations { + load: LoadOp::Load, + store: true, + })], depth_stencil_attachment: Some(RenderPassDepthStencilAttachment { view: &overlay.albedo_depth.default_view, depth_ops: Some(Operations { diff --git a/src/overlay.rs b/src/overlay.rs index 2e05c18..c716941 100644 --- a/src/overlay.rs +++ b/src/overlay.rs @@ -54,15 +54,12 @@ fn setup( mut meshes: ResMut>, mut materials: ResMut>, ) { - let irradiance_resolve = overlay.irradiance_resolve.clone(); - let albedo_resolve = overlay.albedo_resolve.clone(); + let irradiance = overlay.irradiance.clone(); + let albedo = overlay.albedo.clone(); commands.spawn_bundle(MaterialMeshBundle { mesh: meshes.add(shape::Quad::new(Vec2::ZERO).into()), - material: materials.add(OverlayMaterial { - irradiance_image: irradiance_resolve, - albedo_image: albedo_resolve, - }), + material: materials.add(OverlayMaterial { irradiance, albedo }), ..Default::default() }); } @@ -106,23 +103,28 @@ fn prepare_screen_overlay( ); let retrieve_textures = || { + let irradiance_sampled = match &overlay.irradiance_sampled { + Some(handle) => Some(images.get(handle)?.texture_view.clone()), + None => None, + }; let irradiance = images.get(&overlay.irradiance)?.texture_view.clone(); - let irradiance_resolve = images - .get(&overlay.irradiance_resolve)? - .texture_view - .clone(); + + let albedo_sampled = match &overlay.albedo_sampled { + Some(handle) => Some(images.get(handle)?.texture_view.clone()), + None => None, + }; let albedo = images.get(&overlay.albedo)?.texture_view.clone(); - let albedo_resolve = images.get(&overlay.albedo_resolve)?.texture_view.clone(); - Some((irradiance, irradiance_resolve, albedo, albedo_resolve)) + + Some((irradiance_sampled, irradiance, albedo_sampled, albedo)) }; - if let Some((irradiance, irradiance_resolve, albedo, albedo_resolve)) = retrieve_textures() { + if let Some((irradiance_sampled, irradiance, albedo_sampled, albedo)) = retrieve_textures() { commands.insert_resource(GpuScreenOverlay { + irradiance_sampled, irradiance, - irradiance_resolve, irradiance_depth, + albedo_sampled, albedo, - albedo_resolve, albedo_depth, }); } @@ -131,24 +133,64 @@ fn prepare_screen_overlay( #[derive(Debug, Clone)] pub struct ScreenOverlay { pub irradiance_size: Extent3d, + pub irradiance_sampled: Option>, pub irradiance: Handle, - pub irradiance_resolve: Handle, pub albedo_size: Extent3d, + pub albedo_sampled: Option>, pub albedo: Handle, - pub albedo_resolve: Handle, } pub struct GpuScreenOverlay { pub irradiance: TextureView, - pub irradiance_resolve: TextureView, + pub irradiance_sampled: Option, pub irradiance_depth: CachedTexture, pub albedo: TextureView, - pub albedo_resolve: TextureView, + pub albedo_sampled: Option, pub albedo_depth: CachedTexture, } +impl GpuScreenOverlay { + pub fn irradiance_color_attachment( + &self, + ops: Operations, + ) -> RenderPassColorAttachment { + RenderPassColorAttachment { + view: if let Some(sampled) = &self.irradiance_sampled { + sampled + } else { + &self.irradiance + }, + resolve_target: if self.irradiance_sampled.is_some() { + Some(&self.irradiance) + } else { + None + }, + ops, + } + } + + pub fn albedo_color_attachment( + &self, + ops: Operations, + ) -> RenderPassColorAttachment { + RenderPassColorAttachment { + view: if let Some(sampled) = &self.albedo_sampled { + sampled + } else { + &self.albedo + }, + resolve_target: if self.albedo_sampled.is_some() { + Some(&self.albedo) + } else { + None + }, + ops, + } + } +} + impl FromWorld for ScreenOverlay { fn from_world(world: &mut World) -> Self { let windows = world.get_resource::().unwrap(); @@ -179,10 +221,14 @@ impl FromWorld for ScreenOverlay { image.sampler_descriptor.min_filter = FilterMode::Linear; image.texture_descriptor.sample_count = samples; - let irradiance = images.add(image.clone()); + let irradiance_sampled = if samples > 1 { + Some(images.add(image.clone())) + } else { + None + }; image.texture_descriptor.sample_count = 1; - let irradiance_resolve = images.add(image); + let irradiance = images.add(image); let albedo_size = Extent3d { width, @@ -200,18 +246,22 @@ impl FromWorld for ScreenOverlay { | TextureUsages::TEXTURE_BINDING; image.texture_descriptor.sample_count = samples; - let albedo = images.add(image.clone()); + let albedo_sampled = if samples > 1 { + Some(images.add(image.clone())) + } else { + None + }; image.texture_descriptor.sample_count = 1; - let albedo_resolve = images.add(image); + let albedo = images.add(image); Self { irradiance_size, + irradiance_sampled, irradiance, - irradiance_resolve, albedo_size, + albedo_sampled, albedo, - albedo_resolve, } } } @@ -219,8 +269,8 @@ impl FromWorld for ScreenOverlay { #[derive(Debug, Clone, TypeUuid)] #[uuid = "3eb25222-95fd-11ec-b909-0242ac120002"] pub struct OverlayMaterial { - pub irradiance_image: Handle, - pub albedo_image: Handle, + pub irradiance: Handle, + pub albedo: Handle, } #[derive(Clone)] @@ -245,13 +295,13 @@ impl RenderAsset for OverlayMaterial { material: Self::ExtractedAsset, (render_device, material_pipeline, images): &mut SystemParamItem, ) -> Result> { - let irradiance = if let Some(result) = images.get(&material.irradiance_image) { + let irradiance = if let Some(result) = images.get(&material.irradiance) { result } else { return Err(PrepareAssetError::RetryNextUpdate(material)); }; - let albedo = if let Some(result) = images.get(&material.albedo_image) { + let albedo = if let Some(result) = images.get(&material.albedo) { result } else { return Err(PrepareAssetError::RetryNextUpdate(material)); diff --git a/src/tracing.rs b/src/tracing.rs index ba113f3..070dd6c 100644 --- a/src/tracing.rs +++ b/src/tracing.rs @@ -590,14 +590,10 @@ impl render_graph::Node for TracingPassNode { { let pass_descriptor = RenderPassDescriptor { label: Some("tracing_opaque_pass"), - color_attachments: &[RenderPassColorAttachment { - view: &overlay.irradiance, - resolve_target: Some(&overlay.irradiance_resolve), - ops: Operations { - load: LoadOp::Clear(Color::NONE.into()), - store: true, - }, - }], + color_attachments: &[overlay.irradiance_color_attachment(Operations { + load: LoadOp::Clear(Color::NONE.into()), + store: true, + })], depth_stencil_attachment: Some(RenderPassDepthStencilAttachment { view: &overlay.irradiance_depth.default_view, depth_ops: Some(Operations { @@ -627,14 +623,10 @@ impl render_graph::Node for TracingPassNode { { let pass_descriptor = RenderPassDescriptor { label: Some("tracing_alpha_mask_pass"), - color_attachments: &[RenderPassColorAttachment { - view: &overlay.irradiance, - resolve_target: Some(&overlay.irradiance_resolve), - ops: Operations { - load: LoadOp::Load, - store: true, - }, - }], + color_attachments: &[overlay.irradiance_color_attachment(Operations { + load: LoadOp::Load, + store: true, + })], depth_stencil_attachment: Some(RenderPassDepthStencilAttachment { view: &overlay.irradiance_depth.default_view, depth_ops: Some(Operations { @@ -664,14 +656,10 @@ impl render_graph::Node for TracingPassNode { { let pass_descriptor = RenderPassDescriptor { label: Some("tracing_transparent_pass"), - color_attachments: &[RenderPassColorAttachment { - view: &overlay.irradiance, - resolve_target: Some(&overlay.irradiance_resolve), - ops: Operations { - load: LoadOp::Load, - store: true, - }, - }], + color_attachments: &[overlay.irradiance_color_attachment(Operations { + load: LoadOp::Load, + store: true, + })], depth_stencil_attachment: Some(RenderPassDepthStencilAttachment { view: &overlay.irradiance_depth.default_view, depth_ops: Some(Operations { @@ -701,14 +689,10 @@ impl render_graph::Node for TracingPassNode { { let pass_descriptor = RenderPassDescriptor { label: Some("tracing_ambient_occlusion_pass"), - color_attachments: &[RenderPassColorAttachment { - view: &overlay.irradiance, - resolve_target: Some(&overlay.irradiance_resolve), - ops: Operations { - load: LoadOp::Load, - store: true, - }, - }], + color_attachments: &[overlay.irradiance_color_attachment(Operations { + load: LoadOp::Load, + store: true, + })], depth_stencil_attachment: Some(RenderPassDepthStencilAttachment { view: &overlay.irradiance_depth.default_view, depth_ops: Some(Operations {