use crate::phases::PostProcessRenderPhase;
use rafx::framework::{MaterialPassResource, ResourceArc};
use rafx::graph::*;
use rafx::render_features::RenderPhase;
use super::ModernPipelineContext;
use super::EMPTY_VERTEX_LAYOUT;
use crate::shaders::post_shared::bloom_blur_frag;
use rafx::api::RafxSampleCount;
#[derive(PartialEq)]
pub(super) enum BlurDirection {
Horizontal,
Vertical,
}
pub(super) struct BloomBlurPass {
pub(super) color: RenderGraphImageUsageId,
}
pub(super) fn blur_pass(
context: &mut ModernPipelineContext,
bloom_blur_material_pass: ResourceArc<MaterialPassResource>,
bloom_extract_hdr_image: RenderGraphImageUsageId,
pass_count: usize,
) -> BloomBlurPass {
let mut blur_src = bloom_extract_hdr_image;
for _ in 0..pass_count {
blur_src = bloom_blur_internal_pass(
context,
&bloom_blur_material_pass,
blur_src,
BlurDirection::Vertical,
);
blur_src = bloom_blur_internal_pass(
context,
&bloom_blur_material_pass,
blur_src,
BlurDirection::Horizontal,
);
}
return BloomBlurPass { color: blur_src };
}
pub(super) fn bloom_blur_pass(
context: &mut ModernPipelineContext,
bloom_blur_material_pass: ResourceArc<MaterialPassResource>,
bloom_extract_hdr_image: RenderGraphImageUsageId,
) -> BloomBlurPass {
blur_pass(
context,
bloom_blur_material_pass,
bloom_extract_hdr_image,
context.graph_config.blur_pass_count,
)
}
fn bloom_blur_internal_pass(
context: &mut ModernPipelineContext,
bloom_blur_material_pass: &ResourceArc<MaterialPassResource>,
blur_src: RenderGraphImageUsageId,
blur_direction: BlurDirection,
) -> RenderGraphImageUsageId {
let node = context
.graph
.add_renderpass_node("BloomBlur", RenderGraphQueue::DefaultGraphics);
let blur_dst = context.graph.create_color_attachment(
node,
0,
Some(Default::default()),
RenderGraphImageConstraint {
samples: Some(RafxSampleCount::SampleCount1),
format: Some(context.graph_config.color_format),
..Default::default()
},
Default::default(),
);
context.graph.set_image_name(blur_dst, "blur_dst");
let sample_image =
context
.graph
.sample_image(node, blur_src, Default::default(), Default::default());
context.graph.set_image_name(blur_src, "blur_src");
let bloom_blur_material_pass = bloom_blur_material_pass.clone();
context.graph.set_renderpass_callback(node, move |args| {
let sample_image = args.graph_context.image_view(sample_image);
let pipeline = args
.graph_context
.resource_context()
.graphics_pipeline_cache()
.get_or_create_graphics_pipeline(
Some(PostProcessRenderPhase::render_phase_index()),
&bloom_blur_material_pass,
&args.render_target_meta,
&EMPTY_VERTEX_LAYOUT,
)?;
let descriptor_set_layouts = &pipeline.get_raw().descriptor_set_layouts;
let mut descriptor_set_allocator = args
.graph_context
.resource_context()
.create_descriptor_set_allocator();
let horizontal = if blur_direction == BlurDirection::Horizontal {
1
} else {
0
};
let bloom_blur_material_dyn_set = descriptor_set_allocator.create_descriptor_set(
&descriptor_set_layouts[bloom_blur_frag::TEX_DESCRIPTOR_SET_INDEX],
bloom_blur_frag::DescriptorSet0Args {
tex: sample_image.as_ref().unwrap(),
config: &bloom_blur_frag::ConfigUniform {
horizontal,
..Default::default()
},
},
)?;
descriptor_set_allocator.flush_changes()?;
let command_buffer = &args.command_buffer;
command_buffer.cmd_bind_pipeline(&*pipeline.get_raw().pipeline)?;
bloom_blur_material_dyn_set.bind(command_buffer)?;
command_buffer.cmd_draw(3, 0)?;
Ok(())
});
blur_dst
}