Skip to content

Commit 2314a89

Browse files
committed
.
1 parent e79106c commit 2314a89

File tree

9 files changed

+852
-11
lines changed

9 files changed

+852
-11
lines changed

crates/bevy_anti_alias/src/contrast_adaptive_sharpening/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ use bevy_camera::Camera;
44
use bevy_core_pipeline::{
55
core_2d::graph::{Core2d, Node2d},
66
core_3d::graph::{Core3d, Node3d},
7+
schedule::{Core2dSchedule, Core2dSystems},
78
FullscreenShader,
89
};
10+
use crate::fxaa::fxaa;
911
use bevy_ecs::{prelude::*, query::QueryItem};
1012
use bevy_image::BevyDefault as _;
1113
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
@@ -26,6 +28,7 @@ use bevy_utils::default;
2628
mod node;
2729

2830
pub use node::CasNode;
31+
pub(crate) use node::cas;
2932

3033
/// Applies a contrast adaptive sharpening (CAS) filter to the camera.
3134
///
@@ -150,6 +153,11 @@ impl Plugin for CasPlugin {
150153
Node2d::ContrastAdaptiveSharpening,
151154
Node2d::EndMainPassPostProcessing,
152155
),
156+
)
157+
.add_systems(
158+
Core2dSchedule,
159+
cas.after(fxaa)
160+
.before(Core2dSystems::EndMainPassPostProcessing),
153161
);
154162
}
155163
}

crates/bevy_anti_alias/src/contrast_adaptive_sharpening/node.rs

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use bevy_render::{
1010
BindGroup, BindGroupEntries, BufferId, Operations, PipelineCache,
1111
RenderPassColorAttachment, RenderPassDescriptor, TextureViewId,
1212
},
13-
renderer::RenderContext,
13+
renderer::{CurrentView, RenderContext, RenderContextParam},
1414
view::{ExtractedView, ViewTarget},
1515
};
1616

@@ -124,3 +124,87 @@ impl Node for CasNode {
124124
Ok(())
125125
}
126126
}
127+
128+
// =============================================================================
129+
// Schedule-based system (new approach)
130+
// =============================================================================
131+
132+
/// Render system for Contrast Adaptive Sharpening.
133+
///
134+
/// This is the schedule-based replacement for [`CasNode`].
135+
pub(crate) fn cas(
136+
view: CurrentView,
137+
view_query: Query<
138+
(
139+
&ViewTarget,
140+
&ViewCasPipeline,
141+
&DynamicUniformIndex<CasUniform>,
142+
),
143+
With<ExtractedView>,
144+
>,
145+
sharpening_pipeline: Res<CasPipeline>,
146+
pipeline_cache: Res<PipelineCache>,
147+
uniforms: Res<ComponentUniforms<CasUniform>>,
148+
mut ctx: RenderContextParam,
149+
mut cached_bind_group: Local<Option<(BufferId, TextureViewId, BindGroup)>>,
150+
) {
151+
let view_entity = view.entity();
152+
153+
let Ok((target, pipeline, uniform_index)) = view_query.get(view_entity) else {
154+
return;
155+
};
156+
157+
let uniforms_id = uniforms.buffer().unwrap().id();
158+
let Some(uniforms_binding) = uniforms.binding() else {
159+
return;
160+
};
161+
162+
let Some(pipeline) = pipeline_cache.get_render_pipeline(pipeline.0) else {
163+
return;
164+
};
165+
166+
let view_target = target.post_process_write();
167+
let source = view_target.source;
168+
let destination = view_target.destination;
169+
170+
let bind_group = match &mut *cached_bind_group {
171+
Some((buffer_id, texture_id, bind_group))
172+
if source.id() == *texture_id && uniforms_id == *buffer_id =>
173+
{
174+
bind_group
175+
}
176+
cached => {
177+
let bind_group = ctx.render_device().create_bind_group(
178+
"cas_bind_group",
179+
&pipeline_cache.get_bind_group_layout(&sharpening_pipeline.texture_bind_group),
180+
&BindGroupEntries::sequential((
181+
view_target.source,
182+
&sharpening_pipeline.sampler,
183+
uniforms_binding,
184+
)),
185+
);
186+
187+
let (_, _, bind_group) = cached.insert((uniforms_id, source.id(), bind_group));
188+
bind_group
189+
}
190+
};
191+
192+
let pass_descriptor = RenderPassDescriptor {
193+
label: Some("contrast_adaptive_sharpening"),
194+
color_attachments: &[Some(RenderPassColorAttachment {
195+
view: destination,
196+
depth_slice: None,
197+
resolve_target: None,
198+
ops: Operations::default(),
199+
})],
200+
depth_stencil_attachment: None,
201+
timestamp_writes: None,
202+
occlusion_query_set: None,
203+
};
204+
205+
let mut render_pass = ctx.command_encoder().begin_render_pass(&pass_descriptor);
206+
207+
render_pass.set_pipeline(pipeline);
208+
render_pass.set_bind_group(0, bind_group, &[uniform_index.index()]);
209+
render_pass.draw(0..3, 0..1);
210+
}

crates/bevy_anti_alias/src/fxaa/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ use bevy_camera::Camera;
44
use bevy_core_pipeline::{
55
core_2d::graph::{Core2d, Node2d},
66
core_3d::graph::{Core3d, Node3d},
7+
schedule::{Core2dSchedule, Core2dSystems},
8+
tonemapping::tonemapping,
79
FullscreenShader,
810
};
911
use bevy_ecs::prelude::*;
@@ -26,6 +28,7 @@ use bevy_utils::default;
2628
mod node;
2729

2830
pub use node::FxaaNode;
31+
pub(crate) use node::fxaa;
2932

3033
#[derive(Debug, Reflect, Eq, PartialEq, Hash, Clone, Copy)]
3134
#[reflect(PartialEq, Hash, Clone)]
@@ -117,6 +120,11 @@ impl Plugin for FxaaPlugin {
117120
Node2d::Fxaa,
118121
Node2d::EndMainPassPostProcessing,
119122
),
123+
)
124+
.add_systems(
125+
Core2dSchedule,
126+
fxaa.after(tonemapping)
127+
.before(Core2dSystems::EndMainPassPostProcessing),
120128
);
121129
}
122130
}

crates/bevy_anti_alias/src/fxaa/node.rs

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use bevy_render::{
99
BindGroup, BindGroupEntries, Operations, PipelineCache, RenderPassColorAttachment,
1010
RenderPassDescriptor, TextureViewId,
1111
},
12-
renderer::RenderContext,
12+
renderer::{CurrentView, RenderContext, RenderContextParam},
1313
view::ViewTarget,
1414
};
1515

@@ -90,3 +90,69 @@ impl ViewNode for FxaaNode {
9090
Ok(())
9191
}
9292
}
93+
94+
// =============================================================================
95+
// Schedule-based system (new approach)
96+
// =============================================================================
97+
98+
/// Render system for FXAA anti-aliasing.
99+
///
100+
/// This is the schedule-based replacement for [`FxaaNode`].
101+
pub(crate) fn fxaa(
102+
view: CurrentView,
103+
view_query: Query<(&ViewTarget, &CameraFxaaPipeline, &Fxaa)>,
104+
fxaa_pipeline: Res<FxaaPipeline>,
105+
pipeline_cache: Res<PipelineCache>,
106+
mut ctx: RenderContextParam,
107+
mut cached_bind_group: Local<Option<(TextureViewId, BindGroup)>>,
108+
) {
109+
let view_entity = view.entity();
110+
111+
let Ok((target, pipeline, fxaa)) = view_query.get(view_entity) else {
112+
return;
113+
};
114+
115+
if !fxaa.enabled {
116+
return;
117+
}
118+
119+
let Some(pipeline) = pipeline_cache.get_render_pipeline(pipeline.pipeline_id) else {
120+
return;
121+
};
122+
123+
let post_process = target.post_process_write();
124+
let source = post_process.source;
125+
let destination = post_process.destination;
126+
let bind_group = match &mut *cached_bind_group {
127+
Some((id, bind_group)) if source.id() == *id => bind_group,
128+
cached => {
129+
let bind_group = ctx.render_device().create_bind_group(
130+
None,
131+
&pipeline_cache.get_bind_group_layout(&fxaa_pipeline.texture_bind_group),
132+
&BindGroupEntries::sequential((source, &fxaa_pipeline.sampler)),
133+
);
134+
135+
let (_, bind_group) = cached.insert((source.id(), bind_group));
136+
bind_group
137+
}
138+
};
139+
140+
let pass_descriptor = RenderPassDescriptor {
141+
label: Some("fxaa"),
142+
color_attachments: &[Some(RenderPassColorAttachment {
143+
view: destination,
144+
depth_slice: None,
145+
resolve_target: None,
146+
ops: Operations::default(),
147+
})],
148+
depth_stencil_attachment: None,
149+
timestamp_writes: None,
150+
occlusion_query_set: None,
151+
};
152+
153+
let mut render_pass = ctx.command_encoder().begin_render_pass(&pass_descriptor);
154+
155+
render_pass.set_pipeline(pipeline);
156+
render_pass.set_bind_group(0, bind_group, &[]);
157+
render_pass.draw(0..3, 0..1);
158+
}

0 commit comments

Comments
 (0)