Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
fa703f0
Rewrite RenderGraph to use Schedule.
tychedelia Dec 15, 2025
7ac2277
Merge branch 'main' into render-graph-as-systems
tychedelia Dec 15, 2025
2e0c5a6
Fmt.
tychedelia Dec 15, 2025
8ea6a02
Ci.
tychedelia Dec 16, 2025
e5ca7e2
Insert apply deferred automatically.
tychedelia Dec 16, 2025
63388ed
Try pushing command encoders.
tychedelia Dec 16, 2025
c6a6706
Tracing.
tychedelia Dec 16, 2025
57d84be
Don't parallelize.
tychedelia Dec 16, 2025
f5c54e0
Fix shadow ordering.
tychedelia Dec 16, 2025
8c01b32
ci
atlv24 Dec 16, 2025
ff8f43f
examples
atlv24 Dec 16, 2025
6342c31
example imports
atlv24 Dec 16, 2025
b83663b
fix
atlv24 Dec 16, 2025
790a86d
fix guides
atlv24 Dec 16, 2025
1958963
tweaks
atlv24 Dec 16, 2025
1a7a9f4
Merge pull request #4 from atlv24/ad/render-graph-systems
tychedelia Dec 16, 2025
bad4c5e
Merge branch 'main' into render-graph-as-systems
tychedelia Jan 13, 2026
6651227
Re-move for diff.
tychedelia Jan 13, 2026
ea05761
Ci.
tychedelia Jan 13, 2026
ca6343d
Fix occlusion culling.
tychedelia Jan 14, 2026
f715177
Ci.
tychedelia Jan 14, 2026
3a9a97f
Merge remote-tracking branch 'origin/main' into render-graph-as-systems
tychedelia Jan 15, 2026
8d5dc16
Ci.
tychedelia Jan 15, 2026
cd7baed
Oops.
tychedelia Jan 15, 2026
6766122
Fix game of life.
tychedelia Jan 15, 2026
9c80e00
Wasm atomics.
tychedelia Jan 15, 2026
eaa90bb
Docs.
tychedelia Jan 15, 2026
b1da2ce
Ci.
tychedelia Jan 15, 2026
23803dd
Docs.
tychedelia Jan 15, 2026
e99c18a
More wasm atomics.
tychedelia Jan 15, 2026
55a9596
Fix custom_render_phase.
tychedelia Jan 15, 2026
4189f4f
Merge branch 'main' into render-graph-as-systems
tychedelia Jan 15, 2026
e1ecbf7
More constraints
tychedelia Jan 16, 2026
3cc28a4
Respond to feedback.
tychedelia Jan 16, 2026
ac21b06
Respond to feedback.
tychedelia Jan 16, 2026
6d4a4b6
Merge remote-tracking branch 'origin/main' into render-graph-as-systems
tychedelia Jan 16, 2026
b07aed1
Fix compute mesh example.
tychedelia Jan 16, 2026
415f636
Restore missing solari code.
tychedelia Jan 16, 2026
092a5e0
Merge remote-tracking branch 'origin/main' into render-graph-as-systems
tychedelia Jan 19, 2026
f786942
Solari fixes.
tychedelia Jan 19, 2026
72fb694
Use chaining
tychedelia Jan 19, 2026
7c8c843
Restore comments.
tychedelia Jan 19, 2026
8e4b968
Fix render system ordering.
tychedelia Jan 19, 2026
c41b2e1
Add AntiAliasing system set.
tychedelia Jan 19, 2026
a012cad
Add AntiAliasing system set.
tychedelia Jan 19, 2026
32a6f25
Use single system sets rather than begin/end system sets.
tychedelia Jan 20, 2026
c8a7ab9
Merge remote-tracking branch 'origin/main' into render-graph-as-systems
tychedelia Jan 20, 2026
bd962c2
Try fixing solari again.
tychedelia Jan 20, 2026
e29562b
Correctly submit only once.
tychedelia Jan 20, 2026
9238715
Merge remote-tracking branch 'origin/main' into render-graph-as-systems
tychedelia Jan 21, 2026
17c70cb
Ci.
tychedelia Jan 21, 2026
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
1 change: 1 addition & 0 deletions crates/bevy_anti_alias/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ bevy_shader = { path = "../bevy_shader", version = "0.19.0-dev" }
bevy_ecs = { path = "../bevy_ecs", version = "0.19.0-dev" }
bevy_core_pipeline = { path = "../bevy_core_pipeline", version = "0.19.0-dev" }
bevy_diagnostic = { path = "../bevy_diagnostic", version = "0.19.0-dev" }
bevy_post_process = { path = "../bevy_post_process", version = "0.19.0-dev" }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this makes clean compile a bit worse cus linearizes compilation of these two crates, but its probably fine. could use system sets to avoid it though


# other
tracing = { version = "0.1", default-features = false, features = ["std"] }
Expand Down
56 changes: 16 additions & 40 deletions crates/bevy_anti_alias/src/contrast_adaptive_sharpening/mod.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
use crate::{fxaa::fxaa, AntiAliasing};
use bevy_app::prelude::*;
use bevy_asset::{embedded_asset, load_embedded_asset, AssetServer};
use bevy_camera::Camera;
use bevy_core_pipeline::{
core_2d::graph::{Core2d, Node2d},
core_3d::graph::{Core3d, Node3d},
schedule::{Core2d, Core2dSystems, Core3d, Core3dSystems},
FullscreenShader,
};
use bevy_ecs::{prelude::*, query::QueryItem};
use bevy_image::BevyDefault as _;
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
use bevy_render::{
extract_component::{ExtractComponent, ExtractComponentPlugin, UniformComponentPlugin},
render_graph::RenderGraphExt,
render_resource::{
binding_types::{sampler, texture_2d, uniform_buffer},
*,
Expand All @@ -23,7 +22,7 @@ use bevy_render::{

mod node;

pub use node::CasNode;
pub(crate) use node::cas;

/// Applies a contrast adaptive sharpening (CAS) filter to the camera.
///
Expand Down Expand Up @@ -113,42 +112,19 @@ impl Plugin for CasPlugin {
};
render_app
.add_systems(RenderStartup, init_cas_pipeline)
.add_systems(Render, prepare_cas_pipelines.in_set(RenderSystems::Prepare));

{
render_app
.add_render_graph_node::<CasNode>(Core3d, Node3d::ContrastAdaptiveSharpening)
.add_render_graph_edge(
Core3d,
Node3d::Tonemapping,
Node3d::ContrastAdaptiveSharpening,
)
.add_render_graph_edges(
Core3d,
(
Node3d::Fxaa,
Node3d::ContrastAdaptiveSharpening,
Node3d::EndMainPassPostProcessing,
),
);
}
{
render_app
.add_render_graph_node::<CasNode>(Core2d, Node2d::ContrastAdaptiveSharpening)
.add_render_graph_edge(
Core2d,
Node2d::Tonemapping,
Node2d::ContrastAdaptiveSharpening,
)
.add_render_graph_edges(
Core2d,
(
Node2d::Fxaa,
Node2d::ContrastAdaptiveSharpening,
Node2d::EndMainPassPostProcessing,
),
);
}
.add_systems(Render, prepare_cas_pipelines.in_set(RenderSystems::Prepare))
.add_systems(
Core3d,
cas.after(fxaa)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reviewer note: fxaa is ordered after tonemapping, so the .after tonemapping here is redundant thus removed

.in_set(Core3dSystems::PostProcess)
.in_set(AntiAliasing),
)
.add_systems(
Core2d,
cas.after(fxaa)
.in_set(Core2dSystems::PostProcess)
.in_set(AntiAliasing),
);
}
}

Expand Down
167 changes: 69 additions & 98 deletions crates/bevy_anti_alias/src/contrast_adaptive_sharpening/node.rs
Original file line number Diff line number Diff line change
@@ -1,126 +1,97 @@
use std::sync::Mutex;

use crate::contrast_adaptive_sharpening::ViewCasPipeline;
use bevy_ecs::prelude::*;
use bevy_render::{
diagnostic::RecordDiagnostics,
extract_component::{ComponentUniforms, DynamicUniformIndex},
render_graph::{Node, NodeRunError, RenderGraphContext},
render_resource::{
BindGroup, BindGroupEntries, BufferId, Operations, PipelineCache,
RenderPassColorAttachment, RenderPassDescriptor, TextureViewId,
},
renderer::RenderContext,
renderer::{RenderContext, ViewQuery},
view::{ExtractedView, ViewTarget},
};

use super::{CasPipeline, CasUniform};

pub struct CasNode {
query: QueryState<
pub(crate) fn cas(
view: ViewQuery<
(
&'static ViewTarget,
&'static ViewCasPipeline,
&'static DynamicUniformIndex<CasUniform>,
&ViewTarget,
&ViewCasPipeline,
&DynamicUniformIndex<CasUniform>,
),
With<ExtractedView>,
>,
cached_bind_group: Mutex<Option<(BufferId, TextureViewId, BindGroup)>>,
}

impl FromWorld for CasNode {
fn from_world(world: &mut World) -> Self {
Self {
query: QueryState::new(world),
cached_bind_group: Mutex::new(None),
sharpening_pipeline: Res<CasPipeline>,
pipeline_cache: Res<PipelineCache>,
uniforms: Res<ComponentUniforms<CasUniform>>,
mut ctx: RenderContext,
mut cached_bind_group: Local<Option<(BufferId, TextureViewId, BindGroup)>>,
) {
let (target, pipeline, uniform_index) = view.into_inner();

let uniforms_id = uniforms.buffer().unwrap().id();
let Some(uniforms_binding) = uniforms.binding() else {
return;
};

let Some(pipeline) = pipeline_cache.get_render_pipeline(pipeline.0) else {
return;
};

let view_target = target.post_process_write();
let source = view_target.source;
let destination = view_target.destination;

let bind_group = match &mut *cached_bind_group {
Some((buffer_id, texture_id, bind_group))
if source.id() == *texture_id && uniforms_id == *buffer_id =>
{
bind_group
}
}
}

impl Node for CasNode {
fn update(&mut self, world: &mut World) {
self.query.update_archetypes(world);
}

fn run(
&self,
graph: &mut RenderGraphContext,
render_context: &mut RenderContext,
world: &World,
) -> Result<(), NodeRunError> {
let view_entity = graph.view_entity();
let pipeline_cache = world.resource::<PipelineCache>();
let sharpening_pipeline = world.resource::<CasPipeline>();
let uniforms = world.resource::<ComponentUniforms<CasUniform>>();

let Ok((target, pipeline, uniform_index)) = self.query.get_manual(world, view_entity)
else {
return Ok(());
};

let uniforms_id = uniforms.buffer().unwrap().id();
let Some(uniforms) = uniforms.binding() else {
return Ok(());
};

let Some(pipeline) = pipeline_cache.get_render_pipeline(pipeline.0) else {
return Ok(());
};

let diagnostics = render_context.diagnostic_recorder();

let view_target = target.post_process_write();
let source = view_target.source;
let destination = view_target.destination;

let mut cached_bind_group = self.cached_bind_group.lock().unwrap();
let bind_group = match &mut *cached_bind_group {
Some((buffer_id, texture_id, bind_group))
if source.id() == *texture_id && uniforms_id == *buffer_id =>
{
bind_group
}
cached_bind_group => {
let bind_group = render_context.render_device().create_bind_group(
"cas_bind_group",
&pipeline_cache.get_bind_group_layout(&sharpening_pipeline.layout),
&BindGroupEntries::sequential((
view_target.source,
&sharpening_pipeline.sampler,
uniforms,
)),
);

let (_, _, bind_group) =
cached_bind_group.insert((uniforms_id, source.id(), bind_group));
bind_group
}
};

let pass_descriptor = RenderPassDescriptor {
label: Some("contrast_adaptive_sharpening"),
color_attachments: &[Some(RenderPassColorAttachment {
view: destination,
depth_slice: None,
resolve_target: None,
ops: Operations::default(),
})],
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
};

let mut render_pass = render_context
.command_encoder()
.begin_render_pass(&pass_descriptor);
cached => {
let bind_group = ctx.render_device().create_bind_group(
"cas_bind_group",
&pipeline_cache.get_bind_group_layout(&sharpening_pipeline.layout),
&BindGroupEntries::sequential((
view_target.source,
&sharpening_pipeline.sampler,
uniforms_binding,
)),
);

let (_, _, bind_group) = cached.insert((uniforms_id, source.id(), bind_group));
bind_group
}
};

let pass_descriptor = RenderPassDescriptor {
label: Some("contrast_adaptive_sharpening"),
color_attachments: &[Some(RenderPassColorAttachment {
view: destination,
depth_slice: None,
resolve_target: None,
ops: Operations::default(),
})],
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
};

let diagnostics = ctx.diagnostic_recorder();
let diagnostics = diagnostics.as_deref();
let time_span = diagnostics.time_span(ctx.command_encoder(), "contrast_adaptive_sharpening");

{
let mut render_pass = ctx.command_encoder().begin_render_pass(&pass_descriptor);
let pass_span = diagnostics.pass_span(&mut render_pass, "contrast_adaptive_sharpening");

render_pass.set_pipeline(pipeline);
render_pass.set_bind_group(0, bind_group, &[uniform_index.index()]);
render_pass.draw(0..3, 0..1);

pass_span.end(&mut render_pass);

Ok(())
}

time_span.end(ctx.command_encoder());
}
34 changes: 13 additions & 21 deletions crates/bevy_anti_alias/src/dlss/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,18 @@ mod prepare;

pub use dlss_wgpu::DlssPerfQualityMode;

use crate::AntiAliasing;
use bevy_app::{App, Plugin};
use bevy_core_pipeline::{
core_3d::graph::{Core3d, Node3d},
prepass::{DepthPrepass, MotionVectorPrepass},
schedule::{Core3d, Core3dSystems},
};
use bevy_ecs::prelude::*;
use bevy_math::{UVec2, Vec2};
use bevy_post_process::{bloom::bloom, motion_blur::node::motion_blur};
use bevy_reflect::{reflect_remote, Reflect};
use bevy_render::{
camera::{MipBias, TemporalJitter},
render_graph::{RenderGraphExt, ViewNodeRunner},
renderer::{
raw_vulkan_init::{AdditionalVulkanFeatures, RawVulkanInitSettings},
RenderDevice, RenderQueue,
Expand Down Expand Up @@ -187,26 +188,17 @@ impl Plugin for DlssPlugin {
)
.in_set(RenderSystems::ManageViews)
.before(prepare_view_targets),
)
.add_render_graph_node::<ViewNodeRunner<node::DlssNode<DlssSuperResolutionFeature>>>(
Core3d,
Node3d::DlssSuperResolution,
)
.add_render_graph_node::<ViewNodeRunner<node::DlssNode<DlssRayReconstructionFeature>>>(
Core3d,
Node3d::DlssRayReconstruction,
)
.add_render_graph_edges(
Core3d,
(
Node3d::EndMainPass,
Node3d::MotionBlur, // Running before DLSS reduces edge artifacts and noise
Node3d::DlssSuperResolution,
Node3d::DlssRayReconstruction,
Node3d::Bloom,
Node3d::Tonemapping,
),
);

app.sub_app_mut(RenderApp).add_systems(
Core3d,
(node::dlss_super_resolution, node::dlss_ray_reconstruction)
.chain()
.after(motion_blur)
.before(bloom)
.in_set(Core3dSystems::PostProcess)
.in_set(AntiAliasing),
);
}
}

Expand Down
Loading