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

fix some post-processing issues #7460

Closed
wants to merge 7 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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion crates/bevy_core_pipeline/src/fxaa/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::fxaa::{CameraFxaaPipeline, Fxaa, FxaaPipeline};
use bevy_ecs::prelude::*;
use bevy_ecs::query::QueryState;
use bevy_render::{
camera::ExtractedCamera,
render_graph::{Node, NodeRunError, RenderGraphContext, SlotInfo, SlotType},
render_resource::{
BindGroup, BindGroupDescriptor, BindGroupEntry, BindingResource, FilterMode, Operations,
Expand All @@ -21,6 +22,7 @@ pub struct FxaaNode {
&'static ViewTarget,
&'static CameraFxaaPipeline,
&'static Fxaa,
&'static ExtractedCamera,
),
With<ExtractedView>,
>,
Expand Down Expand Up @@ -57,7 +59,7 @@ impl Node for FxaaNode {
let pipeline_cache = world.resource::<PipelineCache>();
let fxaa_pipeline = world.resource::<FxaaPipeline>();

let (target, pipeline, fxaa) = match self.query.get_manual(world, view_entity) {
let (target, pipeline, fxaa, camera) = match self.query.get_manual(world, view_entity) {
Ok(result) => result,
Err(_) => return Ok(()),
};
Expand Down Expand Up @@ -125,6 +127,18 @@ impl Node for FxaaNode {

render_pass.set_pipeline(pipeline);
render_pass.set_bind_group(0, bind_group, &[]);

if let Some(viewport) = camera.viewport.as_ref() {
render_pass.set_viewport(
viewport.physical_position.x as f32,
viewport.physical_position.y as f32,
viewport.physical_size.x as f32,
viewport.physical_size.y as f32,
viewport.depth.start,
viewport.depth.end,
);
}

render_pass.draw(0..3, 0..1);

Ok(())
Expand Down
27 changes: 24 additions & 3 deletions crates/bevy_core_pipeline/src/tonemapping/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ use bevy_asset::{load_internal_asset, HandleUntyped};
use bevy_ecs::prelude::*;
use bevy_ecs::query::QueryItem;
use bevy_reflect::{Reflect, TypeUuid};
use bevy_render::camera::Camera;
use bevy_render::camera::{Camera, ExtractedCamera, NormalizedRenderTarget};
use bevy_render::extract_component::{ExtractComponent, ExtractComponentPlugin};
use bevy_render::renderer::RenderDevice;
use bevy_render::view::ViewTarget;
use bevy_render::{render_resource::*, RenderApp, RenderStage};

mod node;

use bevy_utils::HashMap;
pub use node::TonemappingNode;

const TONEMAPPING_SHADER_HANDLE: HandleUntyped =
Expand Down Expand Up @@ -129,9 +130,29 @@ pub fn queue_view_tonemapping_pipelines(
pipeline_cache: Res<PipelineCache>,
mut pipelines: ResMut<SpecializedRenderPipelines<TonemappingPipeline>>,
upscaling_pipeline: Res<TonemappingPipeline>,
view_targets: Query<(Entity, &Tonemapping)>,
view_targets: Query<(Entity, &Tonemapping, &ExtractedCamera)>,
) {
for (entity, tonemapping) in view_targets.iter() {
// record the highest camera order number for each view target
let mut final_order = HashMap::<NormalizedRenderTarget, isize>::default();
for (_, _, camera) in view_targets.iter() {
if let Some(target) = camera.target.as_ref() {
let entry = final_order.entry(target.clone()).or_insert(isize::MIN);
*entry = camera.order.max(*entry);
}
}

for (entity, tonemapping, camera) in view_targets.iter() {
let is_final = camera
.target
.as_ref()
.map(|target| final_order.get(target) == Some(&camera.order))
.unwrap_or(true);

// only apply tonemapping if this is the final camera
if !is_final {
continue;
}

if let Tonemapping::Enabled { deband_dither } = tonemapping {
let key = TonemappingPipelineKey {
deband_dither: *deband_dither,
Expand Down
51 changes: 44 additions & 7 deletions crates/bevy_core_pipeline/src/upscaling/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,17 @@ use bevy_app::prelude::*;
use bevy_asset::{load_internal_asset, HandleUntyped};
use bevy_ecs::prelude::*;
use bevy_reflect::TypeUuid;
use bevy_render::renderer::RenderDevice;
use bevy_render::view::ViewTarget;
use bevy_render::{
camera::{ExtractedCamera, NormalizedRenderTarget},
renderer::RenderDevice,
view::Msaa,
};
use bevy_render::{render_resource::*, RenderApp, RenderStage};

mod node;

use bevy_utils::HashMap;
pub use node::UpscalingNode;

const UPSCALING_SHADER_HANDLE: HandleUntyped =
Expand Down Expand Up @@ -80,6 +85,7 @@ pub enum UpscalingMode {
pub struct UpscalingPipelineKey {
upscaling_mode: UpscalingMode,
texture_format: TextureFormat,
msaa_samples: u32,
}

impl SpecializedRenderPipeline for UpscalingPipeline {
Expand All @@ -102,30 +108,61 @@ impl SpecializedRenderPipeline for UpscalingPipeline {
}),
primitive: PrimitiveState::default(),
depth_stencil: None,
multisample: MultisampleState::default(),
multisample: MultisampleState {
count: key.msaa_samples,
..Default::default()
},
}
}
}

#[derive(Component)]
pub struct ViewUpscalingPipeline(CachedRenderPipelineId);
pub struct ViewUpscalingPipeline {
pipeline: CachedRenderPipelineId,
is_final: bool,
}

fn queue_view_upscaling_pipelines(
mut commands: Commands,
pipeline_cache: Res<PipelineCache>,
mut pipelines: ResMut<SpecializedRenderPipelines<UpscalingPipeline>>,
upscaling_pipeline: Res<UpscalingPipeline>,
view_targets: Query<(Entity, &ViewTarget)>,
view_targets: Query<(Entity, &ViewTarget, &ExtractedCamera)>,
msaa: Res<Msaa>,
) {
for (entity, view_target) in view_targets.iter() {
// record the highest camera order number for each view target
let mut final_order = HashMap::<NormalizedRenderTarget, isize>::default();
for (_, _, camera) in view_targets.iter() {
if let Some(target) = camera.target.as_ref() {
let entry = final_order.entry(target.clone()).or_insert(isize::MIN);
*entry = camera.order.max(*entry);
}
}

for (entity, view_target, camera) in view_targets.iter() {
let is_final = camera
.target
.as_ref()
.map(|target| final_order.get(target) == Some(&camera.order))
.unwrap_or(true);
let texture_format = if is_final {
// write to output
view_target.out_texture_format()
} else {
// write back to input
view_target.main_texture_format()
};
let msaa_samples = if is_final { 1 } else { msaa.samples() };

let key = UpscalingPipelineKey {
upscaling_mode: UpscalingMode::Filtering,
texture_format: view_target.out_texture_format(),
texture_format,
msaa_samples,
};
let pipeline = pipelines.specialize(&pipeline_cache, &upscaling_pipeline, key);

commands
.entity(entity)
.insert(ViewUpscalingPipeline(pipeline));
.insert(ViewUpscalingPipeline { pipeline, is_final });
}
}
15 changes: 13 additions & 2 deletions crates/bevy_core_pipeline/src/upscaling/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ impl Node for UpscalingNode {
Err(_) => return Ok(()),
};

if !upscaling_target.is_final && target.is_current_base() {
// input is already output, nothing to do
return Ok(());
}

let upscaled_texture = target.main_texture();

let mut cached_bind_group = self.cached_texture_bind_group.lock().unwrap();
Expand Down Expand Up @@ -89,15 +94,21 @@ impl Node for UpscalingNode {
}
};

let pipeline = match pipeline_cache.get_render_pipeline(upscaling_target.0) {
let pipeline = match pipeline_cache.get_render_pipeline(upscaling_target.pipeline) {
Some(pipeline) => pipeline,
None => return Ok(()),
};

let view_attachment = if upscaling_target.is_final {
target.out_texture()
} else {
target.base_texture()
};

let pass_descriptor = RenderPassDescriptor {
label: Some("upscaling_pass"),
color_attachments: &[Some(RenderPassColorAttachment {
view: target.out_texture(),
view: view_attachment,
resolve_target: None,
ops: Operations {
load: LoadOp::Clear(Default::default()),
Expand Down
10 changes: 10 additions & 0 deletions crates/bevy_render/src/view/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,16 @@ impl ViewTarget {
&self.out_texture
}

/// the initial texture that will be written to.
pub fn base_texture(&self) -> &TextureView {
self.sampled_main_texture().unwrap_or(&self.main_textures.a)
}

/// is the last written texture also the base texture
pub fn is_current_base(&self) -> bool {
self.sampled_main_texture().is_none() && self.main_texture.load(Ordering::SeqCst) == 0
}

/// The format of the final texture this view will render to
#[inline]
pub fn out_texture_format(&self) -> TextureFormat {
Expand Down