diff --git a/crates/bevy_core_pipeline/src/contrast_adaptive_sharpening/mod.rs b/crates/bevy_core_pipeline/src/contrast_adaptive_sharpening/mod.rs index 61f72f39fadc8b..5dabaa08533a35 100644 --- a/crates/bevy_core_pipeline/src/contrast_adaptive_sharpening/mod.rs +++ b/crates/bevy_core_pipeline/src/contrast_adaptive_sharpening/mod.rs @@ -16,7 +16,7 @@ use bevy_render::{ mod node; -pub use node::ContrastAdaptiveSharpeningNode; +pub use node::CASNode; /// Applies a contrast adaptive sharpening (CAS) filter to the camera. /// @@ -24,7 +24,7 @@ pub use node::ContrastAdaptiveSharpeningNode; /// such as FXAA or TAA to regain some of the lost detail from the blurring that they introduce. /// /// CAS is designed to adjust the amount of sharpening applied to different areas of an image -/// based on the local contrast.This can help avoid over-sharpening areas with high contrast +/// based on the local contrast. This can help avoid over-sharpening areas with high contrast /// and under-sharpening areas with low contrast. /// /// To use this, add the [`ContrastAdaptiveSharpeningSettings`] component to a 2D or 3D camera. @@ -82,9 +82,9 @@ const CONTRAST_ADAPTIVE_SHARPENING_SHADER_HANDLE: HandleUntyped = HandleUntyped::weak_from_u64(Shader::TYPE_UUID, 6925381244141981602); /// Adds Support for Contrast Adaptive Sharpening (CAS). -pub struct ContrastAdaptiveSharpeningPlugin; +pub struct CASPlugin; -impl Plugin for ContrastAdaptiveSharpeningPlugin { +impl Plugin for CASPlugin { fn build(&self, app: &mut App) { load_internal_asset!( app, @@ -102,14 +102,11 @@ impl Plugin for ContrastAdaptiveSharpeningPlugin { Err(_) => return, }; render_app - .init_resource::() - .init_resource::>() - .add_system_to_stage( - RenderStage::Prepare, - prepare_contrast_adaptive_sharpening_pipelines, - ); + .init_resource::() + .init_resource::>() + .add_system_to_stage(RenderStage::Prepare, prepare_cas_pipelines); { - let cas_node = ContrastAdaptiveSharpeningNode::new(&mut render_app.world); + let cas_node = CASNode::new(&mut render_app.world); let mut binding = render_app.world.resource_mut::(); let graph = binding.get_sub_graph_mut(core_3d::graph::NAME).unwrap(); @@ -119,7 +116,7 @@ impl Plugin for ContrastAdaptiveSharpeningPlugin { graph.input_node().id, core_3d::graph::input::VIEW_ENTITY, core_3d::graph::node::CONTRAST_ADAPTIVE_SHARPENING, - ContrastAdaptiveSharpeningNode::IN_VIEW, + CASNode::IN_VIEW, ); graph.add_node_edge( @@ -132,7 +129,7 @@ impl Plugin for ContrastAdaptiveSharpeningPlugin { ); } { - let cas_node = ContrastAdaptiveSharpeningNode::new(&mut render_app.world); + let cas_node = CASNode::new(&mut render_app.world); let mut binding = render_app.world.resource_mut::(); let graph = binding.get_sub_graph_mut(core_2d::graph::NAME).unwrap(); @@ -142,7 +139,7 @@ impl Plugin for ContrastAdaptiveSharpeningPlugin { graph.input_node().id, core_2d::graph::input::VIEW_ENTITY, core_2d::graph::node::CONTRAST_ADAPTIVE_SHARPENING, - ContrastAdaptiveSharpeningNode::IN_VIEW, + CASNode::IN_VIEW, ); graph.add_node_edge( @@ -158,12 +155,12 @@ impl Plugin for ContrastAdaptiveSharpeningPlugin { } #[derive(Resource)] -pub struct ContrastAdaptiveSharpeningPipeline { +pub struct CASPipeline { texture_bind_group: BindGroupLayout, sampler: Sampler, } -impl FromWorld for ContrastAdaptiveSharpeningPipeline { +impl FromWorld for CASPipeline { fn from_world(render_world: &mut World) -> Self { let render_device = render_world.resource::(); let texture_bind_group = @@ -191,7 +188,7 @@ impl FromWorld for ContrastAdaptiveSharpeningPipeline { binding: 2, ty: BindingType::Buffer { ty: BufferBindingType::Uniform, - has_dynamic_offset: false, + has_dynamic_offset: true, min_binding_size: Some(CASUniform::min_size()), }, visibility: ShaderStages::FRAGMENT, @@ -202,7 +199,7 @@ impl FromWorld for ContrastAdaptiveSharpeningPipeline { let sampler = render_device.create_sampler(&SamplerDescriptor::default()); - ContrastAdaptiveSharpeningPipeline { + CASPipeline { texture_bind_group, sampler, } @@ -210,12 +207,12 @@ impl FromWorld for ContrastAdaptiveSharpeningPipeline { } #[derive(PartialEq, Eq, Hash, Clone, Copy)] -pub struct SharpeningPipelineKey { +pub struct CASPipelineKey { texture_format: TextureFormat, } -impl SpecializedRenderPipeline for ContrastAdaptiveSharpeningPipeline { - type Key = SharpeningPipelineKey; +impl SpecializedRenderPipeline for CASPipeline { + type Key = CASPipelineKey; fn specialize(&self, key: Self::Key) -> RenderPipelineDescriptor { RenderPipelineDescriptor { @@ -239,11 +236,11 @@ impl SpecializedRenderPipeline for ContrastAdaptiveSharpeningPipeline { } } -pub fn prepare_contrast_adaptive_sharpening_pipelines( +pub fn prepare_cas_pipelines( mut commands: Commands, pipeline_cache: Res, - mut pipelines: ResMut>, - sharpening_pipeline: Res, + mut pipelines: ResMut>, + sharpening_pipeline: Res, views: Query<(Entity, &ExtractedView, &CASUniform)>, ) { for (entity, view, sharpening) in &views { @@ -253,7 +250,7 @@ pub fn prepare_contrast_adaptive_sharpening_pipelines( let pipeline_id = pipelines.specialize( &pipeline_cache, &sharpening_pipeline, - SharpeningPipelineKey { + CASPipelineKey { texture_format: if view.hdr { ViewTarget::TEXTURE_FORMAT_HDR } else { @@ -262,11 +259,9 @@ pub fn prepare_contrast_adaptive_sharpening_pipelines( }, ); - commands - .entity(entity) - .insert(ViewContrastAdaptiveSharpeningPipeline(pipeline_id)); + commands.entity(entity).insert(ViewCASPipeline(pipeline_id)); } } #[derive(Component)] -pub struct ViewContrastAdaptiveSharpeningPipeline(CachedRenderPipelineId); +pub struct ViewCASPipeline(CachedRenderPipelineId); diff --git a/crates/bevy_core_pipeline/src/contrast_adaptive_sharpening/node.rs b/crates/bevy_core_pipeline/src/contrast_adaptive_sharpening/node.rs index 9e62b1e01c8151..3082b5a55f15a6 100644 --- a/crates/bevy_core_pipeline/src/contrast_adaptive_sharpening/node.rs +++ b/crates/bevy_core_pipeline/src/contrast_adaptive_sharpening/node.rs @@ -1,10 +1,10 @@ use std::sync::Mutex; -use crate::contrast_adaptive_sharpening::ViewContrastAdaptiveSharpeningPipeline; +use crate::contrast_adaptive_sharpening::ViewCASPipeline; use bevy_ecs::prelude::*; use bevy_ecs::query::QueryState; use bevy_render::{ - extract_component::ComponentUniforms, + extract_component::{ComponentUniforms, DynamicUniformIndex}, render_graph::{Node, NodeRunError, RenderGraphContext, SlotInfo, SlotType}, render_resource::{ BindGroup, BindGroupDescriptor, BindGroupEntry, BindingResource, Operations, PipelineCache, @@ -14,21 +14,21 @@ use bevy_render::{ view::{ExtractedView, ViewTarget}, }; -use super::{CASUniform, ContrastAdaptiveSharpeningPipeline}; +use super::{CASPipeline, CASUniform}; -pub struct ContrastAdaptiveSharpeningNode { +pub struct CASNode { query: QueryState< ( &'static ViewTarget, - &'static ViewContrastAdaptiveSharpeningPipeline, - // &'static CASUniform, + &'static ViewCASPipeline, + &'static DynamicUniformIndex, ), With, >, cached_texture_bind_group: Mutex>, } -impl ContrastAdaptiveSharpeningNode { +impl CASNode { pub const IN_VIEW: &'static str = "view"; pub fn new(world: &mut World) -> Self { @@ -39,12 +39,9 @@ impl ContrastAdaptiveSharpeningNode { } } -impl Node for ContrastAdaptiveSharpeningNode { +impl Node for CASNode { fn input(&self) -> Vec { - vec![SlotInfo::new( - ContrastAdaptiveSharpeningNode::IN_VIEW, - SlotType::Entity, - )] + vec![SlotInfo::new(CASNode::IN_VIEW, SlotType::Entity)] } fn update(&mut self, world: &mut World) { @@ -59,10 +56,12 @@ impl Node for ContrastAdaptiveSharpeningNode { ) -> Result<(), NodeRunError> { let view_entity = graph.get_input_entity(Self::IN_VIEW)?; let pipeline_cache = world.resource::(); - let sharpening_pipeline = world.resource::(); + let sharpening_pipeline = world.resource::(); let uniforms = world.resource::>(); - let Ok((target, pipeline)) = self.query.get_manual(world, view_entity) else { return Ok(()) }; + let Ok((target, pipeline, uniform_index)) = self.query.get_manual(world, view_entity) else { return Ok(()) }; + + let Some(uniforms) = uniforms.binding() else { return Ok(()) }; let pipeline = pipeline_cache.get_render_pipeline(pipeline.0).unwrap(); @@ -93,7 +92,7 @@ impl Node for ContrastAdaptiveSharpeningNode { }, BindGroupEntry { binding: 2, - resource: uniforms.binding().unwrap(), + resource: uniforms, }, ], }); @@ -118,7 +117,7 @@ impl Node for ContrastAdaptiveSharpeningNode { .begin_render_pass(&pass_descriptor); render_pass.set_pipeline(pipeline); - render_pass.set_bind_group(0, bind_group, &[]); + render_pass.set_bind_group(0, bind_group, &[uniform_index.index()]); render_pass.draw(0..3, 0..1); Ok(()) diff --git a/crates/bevy_core_pipeline/src/lib.rs b/crates/bevy_core_pipeline/src/lib.rs index 20f3ce36b37ff6..bc6f551a9e03f8 100644 --- a/crates/bevy_core_pipeline/src/lib.rs +++ b/crates/bevy_core_pipeline/src/lib.rs @@ -21,7 +21,7 @@ pub mod prelude { use crate::{ bloom::BloomPlugin, clear_color::{ClearColor, ClearColorConfig}, - contrast_adaptive_sharpening::ContrastAdaptiveSharpeningPlugin, + contrast_adaptive_sharpening::CASPlugin, core_2d::Core2dPlugin, core_3d::Core3dPlugin, fullscreen_vertex_shader::FULLSCREEN_SHADER_HANDLE, @@ -58,6 +58,6 @@ impl Plugin for CorePipelinePlugin { .add_plugin(UpscalingPlugin) .add_plugin(BloomPlugin) .add_plugin(FxaaPlugin) - .add_plugin(ContrastAdaptiveSharpeningPlugin); + .add_plugin(CASPlugin); } }