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

Remove slots in render graph #7995

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 11 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -1385,11 +1385,21 @@ name = "post_processing"
path = "examples/shader/post_processing.rs"

[package.metadata.example.post_processing]
name = "Post Processing"
name = "Post Processing - Render To Texture"
description = "A custom post processing effect, using two cameras, with one reusing the render texture of the first one"
category = "Shaders"
wasm = true

[[example]]
name = "post_process_pass"
path = "examples/shader/post_process_pass.rs"

[package.metadata.example.post_process_pass]
name = "Post Processing - Custom Render Pass"
description = "A custom post processing effect, using a custom render pass that runs after the main pass"
category = "Shaders"
wasm = true

[[example]]
name = "shader_defs"
path = "examples/shader/shader_defs.rs"
Expand Down
48 changes: 48 additions & 0 deletions assets/shaders/post_process_pass.wgsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// This shader computes the chromatic aberration effect

#import bevy_pbr::utils

// Since post processing is a fullscreen effect, we use the fullscreen vertex shader provided by bevy.
// This will import a vertex shader that renders a single fullscreen triangle.
//
// A fullscreen triangle is a single triangle that covers the entire screen.
// The box in the top left in that diagram is the screen. The 4 x are the corner of the screen
//
// Y axis
// 1 | x-----x......
// 0 | | s | . ´
// -1 | x_____x´
// -2 | : .´
// -3 | :´
// +--------------- X axis
// -1 0 1 2 3
//
// As you can see, the triangle ends up bigger than the screen.
//
// You don't need to worry about this too much since bevy will compute the correct UVs for you.
#import bevy_core_pipeline::fullscreen_vertex_shader

@group(0) @binding(0)
var screen_texture: texture_2d<f32>;
@group(0) @binding(1)
var texture_sampler: sampler;
struct PostProcessSettings {
intensity: f32,
}
@group(0) @binding(2)
var<uniform> settings: PostProcessSettings;

@fragment
fn fragment(in: FullscreenVertexOutput) -> @location(0) vec4<f32> {
// Chromatic aberration strength
let offset_strength = settings.intensity;

// Sample each color channel with an arbitrary shift
return vec4<f32>(
textureSample(screen_texture, texture_sampler, in.uv + vec2<f32>(offset_strength, -offset_strength)).r,
textureSample(screen_texture, texture_sampler, in.uv + vec2<f32>(-offset_strength, 0.0)).g,
textureSample(screen_texture, texture_sampler, in.uv + vec2<f32>(0.0, offset_strength)).b,
1.0
);
}

80 changes: 24 additions & 56 deletions crates/bevy_core_pipeline/src/bloom/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ mod upsampling_pipeline;

pub use settings::{BloomCompositeMode, BloomPrefilterSettings, BloomSettings};

use crate::{core_2d, core_3d};
use crate::{add_node, core_2d, core_3d};
use bevy_app::{App, Plugin};
use bevy_asset::{load_internal_asset, HandleUntyped};
use bevy_ecs::{
prelude::{Component, Entity},
query::{QueryState, With},
schedule::IntoSystemConfig,
system::{Commands, Query, Res, ResMut},
world::World,
world::{FromWorld, World},
};
use bevy_math::UVec2;
use bevy_reflect::TypeUuid;
Expand All @@ -22,7 +22,7 @@ use bevy_render::{
ComponentUniforms, DynamicUniformIndex, ExtractComponentPlugin, UniformComponentPlugin,
},
prelude::Color,
render_graph::{Node, NodeRunError, RenderGraph, RenderGraphContext, SlotInfo, SlotType},
render_graph::{Node, NodeRunError, RenderGraphContext},
render_resource::*,
renderer::{RenderContext, RenderDevice},
texture::{CachedTexture, TextureCache},
Expand Down Expand Up @@ -79,54 +79,28 @@ impl Plugin for BloomPlugin {
));

// Add bloom to the 3d render graph
{
let bloom_node = BloomNode::new(&mut render_app.world);
let mut graph = render_app.world.resource_mut::<RenderGraph>();
let draw_3d_graph = graph
.get_sub_graph_mut(crate::core_3d::graph::NAME)
.unwrap();
draw_3d_graph.add_node(core_3d::graph::node::BLOOM, bloom_node);
draw_3d_graph.add_slot_edge(
draw_3d_graph.input_node().id,
crate::core_3d::graph::input::VIEW_ENTITY,
core_3d::graph::node::BLOOM,
BloomNode::IN_VIEW,
);
// MAIN_PASS -> BLOOM -> TONEMAPPING
draw_3d_graph.add_node_edge(
crate::core_3d::graph::node::MAIN_PASS,
core_3d::graph::node::BLOOM,
);
draw_3d_graph.add_node_edge(
add_node::<BloomNode>(
render_app,
core_3d::graph::NAME,
core_3d::graph::node::BLOOM,
&[
core_3d::graph::node::MAIN_PASS,
core_3d::graph::node::BLOOM,
crate::core_3d::graph::node::TONEMAPPING,
);
}
core_3d::graph::node::TONEMAPPING,
],
);

// Add bloom to the 2d render graph
{
let bloom_node = BloomNode::new(&mut render_app.world);
let mut graph = render_app.world.resource_mut::<RenderGraph>();
let draw_2d_graph = graph
.get_sub_graph_mut(crate::core_2d::graph::NAME)
.unwrap();
draw_2d_graph.add_node(core_2d::graph::node::BLOOM, bloom_node);
draw_2d_graph.add_slot_edge(
draw_2d_graph.input_node().id,
crate::core_2d::graph::input::VIEW_ENTITY,
add_node::<BloomNode>(
render_app,
core_2d::graph::NAME,
core_2d::graph::node::BLOOM,
&[
core_2d::graph::node::MAIN_PASS,
core_2d::graph::node::BLOOM,
BloomNode::IN_VIEW,
);
// MAIN_PASS -> BLOOM -> TONEMAPPING
draw_2d_graph.add_node_edge(
crate::core_2d::graph::node::MAIN_PASS,
core_2d::graph::node::BLOOM,
);
draw_2d_graph.add_node_edge(
core_2d::graph::node::BLOOM,
crate::core_2d::graph::node::TONEMAPPING,
);
}
core_2d::graph::node::TONEMAPPING,
],
);
}
}

Expand All @@ -143,21 +117,15 @@ pub struct BloomNode {
)>,
}

impl BloomNode {
pub const IN_VIEW: &'static str = "view";

pub fn new(world: &mut World) -> Self {
impl FromWorld for BloomNode {
fn from_world(world: &mut World) -> Self {
Self {
view_query: QueryState::new(world),
}
}
}

impl Node for BloomNode {
fn input(&self) -> Vec<SlotInfo> {
vec![SlotInfo::new(Self::IN_VIEW, SlotType::Entity)]
}

fn update(&mut self, world: &mut World) {
self.view_query.update_archetypes(world);
}
Expand All @@ -177,7 +145,7 @@ impl Node for BloomNode {
let downsampling_pipeline_res = world.resource::<BloomDownsamplingPipeline>();
let pipeline_cache = world.resource::<PipelineCache>();
let uniforms = world.resource::<ComponentUniforms<BloomUniforms>>();
let view_entity = graph.get_input_entity(Self::IN_VIEW)?;
let view_entity = graph.view_entity();
let Ok((
camera,
view_target,
Expand Down
8 changes: 2 additions & 6 deletions crates/bevy_core_pipeline/src/core_2d/main_pass_2d_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
use bevy_ecs::prelude::*;
use bevy_render::{
camera::ExtractedCamera,
render_graph::{Node, NodeRunError, RenderGraphContext, SlotInfo, SlotType},
render_graph::{Node, NodeRunError, RenderGraphContext},
render_phase::RenderPhase,
render_resource::{LoadOp, Operations, RenderPassDescriptor},
renderer::RenderContext,
Expand Down Expand Up @@ -37,10 +37,6 @@ impl MainPass2dNode {
}

impl Node for MainPass2dNode {
fn input(&self) -> Vec<SlotInfo> {
vec![SlotInfo::new(MainPass2dNode::IN_VIEW, SlotType::Entity)]
}

fn update(&mut self, world: &mut World) {
self.query.update_archetypes(world);
}
Expand All @@ -51,7 +47,7 @@ impl Node for MainPass2dNode {
render_context: &mut RenderContext,
world: &World,
) -> Result<(), NodeRunError> {
let view_entity = graph.get_input_entity(Self::IN_VIEW)?;
let view_entity = graph.view_entity();
let (camera, transparent_phase, target, camera_2d) =
if let Ok(result) = self.query.get_manual(world, view_entity) {
result
Expand Down
53 changes: 20 additions & 33 deletions crates/bevy_core_pipeline/src/core_2d/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use bevy_ecs::prelude::*;
use bevy_render::{
camera::Camera,
extract_component::ExtractComponentPlugin,
render_graph::{EmptyNode, RenderGraph, SlotInfo, SlotType},
render_graph::{EmptyNode, RenderGraph},
render_phase::{
batch_phase_system, sort_phase_system, BatchedPhaseItem, CachedRenderPipelinePhaseItem,
DrawFunctionId, DrawFunctions, PhaseItem, RenderPhase,
Expand Down Expand Up @@ -61,46 +61,33 @@ impl Plugin for Core2dPlugin {
));

let pass_node_2d = MainPass2dNode::new(&mut render_app.world);
let tonemapping = TonemappingNode::new(&mut render_app.world);
let upscaling = UpscalingNode::new(&mut render_app.world);
let tonemapping = TonemappingNode::from_world(&mut render_app.world);
let upscaling = UpscalingNode::from_world(&mut render_app.world);
let mut graph = render_app.world.resource_mut::<RenderGraph>();

let mut draw_2d_graph = RenderGraph::default();
draw_2d_graph.add_node(graph::node::MAIN_PASS, pass_node_2d);
draw_2d_graph.add_node(graph::node::TONEMAPPING, tonemapping);

draw_2d_graph.add_node_with_edges(graph::node::MAIN_PASS, pass_node_2d, &[]);
draw_2d_graph.add_node(graph::node::END_MAIN_PASS_POST_PROCESSING, EmptyNode);
draw_2d_graph.add_node(graph::node::UPSCALING, upscaling);
let input_node_id = draw_2d_graph.set_input(vec![SlotInfo::new(
graph::input::VIEW_ENTITY,
SlotType::Entity,
)]);
draw_2d_graph.add_slot_edge(
input_node_id,
graph::input::VIEW_ENTITY,
graph::node::MAIN_PASS,
MainPass2dNode::IN_VIEW,
);
draw_2d_graph.add_slot_edge(
input_node_id,
graph::input::VIEW_ENTITY,
graph::node::TONEMAPPING,
TonemappingNode::IN_VIEW,
);
draw_2d_graph.add_slot_edge(
input_node_id,
graph::input::VIEW_ENTITY,
graph::node::UPSCALING,
UpscalingNode::IN_VIEW,
);
draw_2d_graph.add_node_edge(graph::node::MAIN_PASS, graph::node::TONEMAPPING);
draw_2d_graph.add_node_edge(

draw_2d_graph.add_node_with_edges(
graph::node::TONEMAPPING,
graph::node::END_MAIN_PASS_POST_PROCESSING,
tonemapping,
&[
graph::node::MAIN_PASS,
graph::node::TONEMAPPING,
graph::node::END_MAIN_PASS_POST_PROCESSING,
],
);
draw_2d_graph.add_node_edge(
graph::node::END_MAIN_PASS_POST_PROCESSING,
draw_2d_graph.add_node_with_edges(
graph::node::UPSCALING,
upscaling,
&[
graph::node::END_MAIN_PASS_POST_PROCESSING,
graph::node::UPSCALING,
],
);

graph.add_sub_graph(graph::NAME, draw_2d_graph);
}
}
Expand Down
19 changes: 9 additions & 10 deletions crates/bevy_core_pipeline/src/core_3d/main_pass_3d_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::{
use bevy_ecs::prelude::*;
use bevy_render::{
camera::ExtractedCamera,
render_graph::{Node, NodeRunError, RenderGraphContext, SlotInfo, SlotType},
render_graph::{Node, NodeRunError, RenderGraphContext},
render_phase::RenderPhase,
render_resource::{LoadOp, Operations, RenderPassDepthStencilAttachment, RenderPassDescriptor},
renderer::RenderContext,
Expand Down Expand Up @@ -34,21 +34,19 @@ pub struct MainPass3dNode {
>,
}

impl MainPass3dNode {
pub const IN_VIEW: &'static str = "view";

pub fn new(world: &mut World) -> Self {
impl FromWorld for MainPass3dNode {
fn from_world(world: &mut World) -> Self {
Self {
query: world.query_filtered(),
}
}
}

impl Node for MainPass3dNode {
fn input(&self) -> Vec<SlotInfo> {
vec![SlotInfo::new(MainPass3dNode::IN_VIEW, SlotType::Entity)]
}
impl MainPass3dNode {
pub const IN_VIEW: &'static str = "view";
}

impl Node for MainPass3dNode {
fn update(&mut self, world: &mut World) {
self.query.update_archetypes(world);
}
Expand All @@ -59,7 +57,7 @@ impl Node for MainPass3dNode {
render_context: &mut RenderContext,
world: &World,
) -> Result<(), NodeRunError> {
let view_entity = graph.get_input_entity(Self::IN_VIEW)?;
let view_entity = graph.view_entity();
let Ok((
camera,
opaque_phase,
Expand All @@ -71,6 +69,7 @@ impl Node for MainPass3dNode {
depth_prepass,
normal_prepass,
)) = self.query.get_manual(world, view_entity) else {
bevy_utils::tracing::error!("no view_entity");
// No window
return Ok(());
};
Expand Down