mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Initial bloom impl
This commit is contained in:
31
assets/voxygen/shaders/duel-downsample-frag.glsl
Normal file
31
assets/voxygen/shaders/duel-downsample-frag.glsl
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#version 420 core
|
||||||
|
|
||||||
|
layout(set = 0, binding = 0)
|
||||||
|
uniform texture2D t_src_color;
|
||||||
|
layout(set = 0, binding = 1)
|
||||||
|
uniform sampler s_src_color;
|
||||||
|
layout(set = 0, binding = 2)
|
||||||
|
uniform vec2 halfpixel;
|
||||||
|
|
||||||
|
layout(location = 0) in vec2 uv;
|
||||||
|
|
||||||
|
layout(location = 0) out vec4 tgt_color;
|
||||||
|
|
||||||
|
vec4 simplesample(vec2 uv) {
|
||||||
|
return textureLod(sampler2D(t_src_color, s_src_color), uv, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// From: https://community.arm.com/cfs-file/__key/communityserver-blogs-components-weblogfiles/00-00-00-20-66/siggraph2015_2D00_mmg_2D00_marius_2D00_notes.pdf
|
||||||
|
vec4 downsample(vec2 uv, vec2 halfpixel) {
|
||||||
|
vec4 sum = simplesample(uv) * 4.0;
|
||||||
|
sum += simplesample(uv - halfpixel.xy);
|
||||||
|
sum += simplesample(uv + halfpixel.xy);
|
||||||
|
sum += simplesample(uv + vec2(halfpixel.x, -halfpixel.y));
|
||||||
|
sum += simplesample(uv - vec2(halfpixel.x, -halfpixel.y));
|
||||||
|
|
||||||
|
return sum / 8.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
tgt_color = downsample(uv, halfpixel);
|
||||||
|
}
|
33
assets/voxygen/shaders/duel-upsample-frag.glsl
Normal file
33
assets/voxygen/shaders/duel-upsample-frag.glsl
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#version 420 core
|
||||||
|
|
||||||
|
layout(set = 0, binding = 0)
|
||||||
|
uniform texture2D t_src_color;
|
||||||
|
layout(set = 0, binding = 1)
|
||||||
|
uniform sampler s_src_color;
|
||||||
|
layout(set = 0, binding = 2)
|
||||||
|
uniform vec2 halfpixel;
|
||||||
|
|
||||||
|
layout(location = 0) in vec2 uv;
|
||||||
|
|
||||||
|
layout(location = 0) out vec4 tgt_color;
|
||||||
|
|
||||||
|
vec4 simplesample(vec2 uv) {
|
||||||
|
return textureLod(sampler2D(t_src_color, s_src_color), uv, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// From: https://community.arm.com/cfs-file/__key/communityserver-blogs-components-weblogfiles/00-00-00-20-66/siggraph2015_2D00_mmg_2D00_marius_2D00_notes.pdf
|
||||||
|
vec4 upsample(vec2 uv, vec2 halfpixel) {
|
||||||
|
vec4 sum = simplesample(uv + vec2(-halfpixel.x * 2.0, 0.0));
|
||||||
|
sum += simplesample(uv + vec2(-halfpixel.x, halfpixel.y)) * 2.0;
|
||||||
|
sum += simplesample(uv + vec2(0.0, halfpixel.y * 2.0));
|
||||||
|
sum += simplesample(uv + vec2(halfpixel.x, halfpixel.y)) * 2.0;
|
||||||
|
sum += simplesample(uv + vec2(halfpixel.x * 2.0, 0.0));
|
||||||
|
sum += simplesample(uv + vec2(halfpixel.x, -halfpixel.y)) * 2.0;
|
||||||
|
sum += simplesample(uv + vec2(0.0, -halfpixel.y * 2.0));
|
||||||
|
sum += simplesample(uv + vec2(-halfpixel.x, -halfpixel.y)) * 2.0;
|
||||||
|
return sum / 12.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
tgt_color = upsample(uv, halfpixel);
|
||||||
|
}
|
@ -25,6 +25,8 @@
|
|||||||
layout(set = 1, binding = 0)
|
layout(set = 1, binding = 0)
|
||||||
uniform texture2D t_src_color;
|
uniform texture2D t_src_color;
|
||||||
layout(set = 1, binding = 1)
|
layout(set = 1, binding = 1)
|
||||||
|
uniform texture2D t_src_bloom;
|
||||||
|
layout(set = 1, binding = 2)
|
||||||
uniform sampler s_src_color;
|
uniform sampler s_src_color;
|
||||||
|
|
||||||
|
|
||||||
@ -182,6 +184,10 @@ void main() {
|
|||||||
|
|
||||||
vec4 aa_color = aa_apply(t_src_color, s_src_color, uv * screen_res.xy, screen_res.xy);
|
vec4 aa_color = aa_apply(t_src_color, s_src_color, uv * screen_res.xy, screen_res.xy);
|
||||||
|
|
||||||
|
// Bloom
|
||||||
|
vec4 bloom = textureLod(sampler2D(t_src_bloom, s_src_color), uv, 0) * 0.05;
|
||||||
|
aa_color += bloom;
|
||||||
|
|
||||||
// Tonemapping
|
// Tonemapping
|
||||||
float exposure_offset = 1.0;
|
float exposure_offset = 1.0;
|
||||||
// Adding an in-code offset to gamma and exposure let us have more precise control over the game's look
|
// Adding an in-code offset to gamma and exposure let us have more precise control over the game's look
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
#![deny(clippy::clone_on_ref_ptr)]
|
#![deny(clippy::clone_on_ref_ptr)]
|
||||||
#![feature(
|
#![feature(
|
||||||
array_map,
|
array_map,
|
||||||
|
array_methods,
|
||||||
|
array_zip,
|
||||||
bool_to_option,
|
bool_to_option,
|
||||||
const_generics,
|
const_generics,
|
||||||
drain_filter,
|
drain_filter,
|
||||||
|
197
voxygen/src/render/pipelines/bloom.rs
Normal file
197
voxygen/src/render/pipelines/bloom.rs
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
use super::super::Consts;
|
||||||
|
use bytemuck::{Pod, Zeroable};
|
||||||
|
use vek::*;
|
||||||
|
|
||||||
|
/// Each level is a multiple of 2 smaller in both dimensions.
|
||||||
|
/// For a total of 8 passes from the largest to the smallest to the largest
|
||||||
|
/// again.
|
||||||
|
pub const NUM_SIZES: usize = 5;
|
||||||
|
|
||||||
|
pub struct BindGroup {
|
||||||
|
pub(in super::super) bind_group: wgpu::BindGroup,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Copy, Clone, Debug, Zeroable, Pod)]
|
||||||
|
pub struct HalfPixel([f32; 2]);
|
||||||
|
|
||||||
|
impl HalfPixel {
|
||||||
|
pub fn new(source_texture_resolution: Vec2<f32>) -> Self {
|
||||||
|
Self(source_texture_resolution.map(|e| 0.5 / e).into_array())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct BloomLayout {
|
||||||
|
pub layout: wgpu::BindGroupLayout,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BloomLayout {
|
||||||
|
pub fn new(device: &wgpu::Device) -> Self {
|
||||||
|
Self {
|
||||||
|
layout: device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||||
|
label: None,
|
||||||
|
entries: &[
|
||||||
|
// Color source
|
||||||
|
wgpu::BindGroupLayoutEntry {
|
||||||
|
binding: 0,
|
||||||
|
visibility: wgpu::ShaderStage::FRAGMENT,
|
||||||
|
ty: wgpu::BindingType::Texture {
|
||||||
|
sample_type: wgpu::TextureSampleType::Float { filterable: true },
|
||||||
|
view_dimension: wgpu::TextureViewDimension::D2,
|
||||||
|
multisampled: false,
|
||||||
|
},
|
||||||
|
count: None,
|
||||||
|
},
|
||||||
|
wgpu::BindGroupLayoutEntry {
|
||||||
|
binding: 1,
|
||||||
|
visibility: wgpu::ShaderStage::FRAGMENT,
|
||||||
|
ty: wgpu::BindingType::Sampler {
|
||||||
|
filtering: true,
|
||||||
|
comparison: false,
|
||||||
|
},
|
||||||
|
count: None,
|
||||||
|
},
|
||||||
|
// halfpixel
|
||||||
|
wgpu::BindGroupLayoutEntry {
|
||||||
|
binding: 2,
|
||||||
|
visibility: wgpu::ShaderStage::FRAGMENT,
|
||||||
|
ty: wgpu::BindingType::Buffer {
|
||||||
|
ty: wgpu::BufferBindingType::Uniform,
|
||||||
|
has_dynamic_offset: false,
|
||||||
|
min_binding_size: None,
|
||||||
|
},
|
||||||
|
count: None,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bind(
|
||||||
|
&self,
|
||||||
|
device: &wgpu::Device,
|
||||||
|
src_color: &wgpu::TextureView,
|
||||||
|
sampler: &wgpu::Sampler,
|
||||||
|
half_pixel: Consts<HalfPixel>,
|
||||||
|
) -> BindGroup {
|
||||||
|
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||||
|
label: None,
|
||||||
|
layout: &self.layout,
|
||||||
|
entries: &[
|
||||||
|
wgpu::BindGroupEntry {
|
||||||
|
binding: 0,
|
||||||
|
resource: wgpu::BindingResource::TextureView(src_color),
|
||||||
|
},
|
||||||
|
wgpu::BindGroupEntry {
|
||||||
|
binding: 1,
|
||||||
|
resource: wgpu::BindingResource::Sampler(sampler),
|
||||||
|
},
|
||||||
|
wgpu::BindGroupEntry {
|
||||||
|
binding: 2,
|
||||||
|
resource: half_pixel.buf().as_entire_binding(),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
BindGroup { bind_group }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct BloomPipelines {
|
||||||
|
//pub downsample_filtered: wgpu::RenderPipeline,
|
||||||
|
pub downsample: wgpu::RenderPipeline,
|
||||||
|
pub upsample: wgpu::RenderPipeline,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BloomPipelines {
|
||||||
|
pub fn new(
|
||||||
|
device: &wgpu::Device,
|
||||||
|
vs_module: &wgpu::ShaderModule,
|
||||||
|
//downsample_filtered_fs_module: &wgpu::ShaderModule,
|
||||||
|
downsample_fs_module: &wgpu::ShaderModule,
|
||||||
|
upsample_fs_module: &wgpu::ShaderModule,
|
||||||
|
target_format: wgpu::TextureFormat,
|
||||||
|
layout: &BloomLayout,
|
||||||
|
) -> Self {
|
||||||
|
common_base::span!(_guard, "BloomPipelines::new");
|
||||||
|
let render_pipeline_layout =
|
||||||
|
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||||
|
label: Some("Bloom pipelines layout"),
|
||||||
|
push_constant_ranges: &[],
|
||||||
|
bind_group_layouts: &[&layout.layout],
|
||||||
|
});
|
||||||
|
|
||||||
|
let downsample_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||||
|
label: Some("Bloom downsample pipeline"),
|
||||||
|
layout: Some(&render_pipeline_layout),
|
||||||
|
vertex: wgpu::VertexState {
|
||||||
|
module: vs_module,
|
||||||
|
entry_point: "main",
|
||||||
|
buffers: &[],
|
||||||
|
},
|
||||||
|
primitive: wgpu::PrimitiveState {
|
||||||
|
topology: wgpu::PrimitiveTopology::TriangleList,
|
||||||
|
strip_index_format: None,
|
||||||
|
front_face: wgpu::FrontFace::Ccw,
|
||||||
|
cull_mode: None,
|
||||||
|
clamp_depth: false,
|
||||||
|
polygon_mode: wgpu::PolygonMode::Fill,
|
||||||
|
conservative: false,
|
||||||
|
},
|
||||||
|
depth_stencil: None,
|
||||||
|
multisample: wgpu::MultisampleState {
|
||||||
|
count: 1,
|
||||||
|
mask: !0,
|
||||||
|
alpha_to_coverage_enabled: false,
|
||||||
|
},
|
||||||
|
fragment: Some(wgpu::FragmentState {
|
||||||
|
module: downsample_fs_module,
|
||||||
|
entry_point: "main",
|
||||||
|
targets: &[wgpu::ColorTargetState {
|
||||||
|
format: target_format,
|
||||||
|
blend: None,
|
||||||
|
write_mask: wgpu::ColorWrite::ALL,
|
||||||
|
}],
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
let upsample_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||||
|
label: Some("Bloom upsample pipeline"),
|
||||||
|
layout: Some(&render_pipeline_layout),
|
||||||
|
vertex: wgpu::VertexState {
|
||||||
|
module: vs_module,
|
||||||
|
entry_point: "main",
|
||||||
|
buffers: &[],
|
||||||
|
},
|
||||||
|
primitive: wgpu::PrimitiveState {
|
||||||
|
topology: wgpu::PrimitiveTopology::TriangleList,
|
||||||
|
strip_index_format: None,
|
||||||
|
front_face: wgpu::FrontFace::Ccw,
|
||||||
|
cull_mode: None,
|
||||||
|
clamp_depth: false,
|
||||||
|
polygon_mode: wgpu::PolygonMode::Fill,
|
||||||
|
conservative: false,
|
||||||
|
},
|
||||||
|
depth_stencil: None,
|
||||||
|
multisample: wgpu::MultisampleState {
|
||||||
|
count: 1,
|
||||||
|
mask: !0,
|
||||||
|
alpha_to_coverage_enabled: false,
|
||||||
|
},
|
||||||
|
fragment: Some(wgpu::FragmentState {
|
||||||
|
module: upsample_fs_module,
|
||||||
|
entry_point: "main",
|
||||||
|
targets: &[wgpu::ColorTargetState {
|
||||||
|
format: target_format,
|
||||||
|
blend: None,
|
||||||
|
write_mask: wgpu::ColorWrite::ALL,
|
||||||
|
}],
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
Self {
|
||||||
|
downsample: downsample_pipeline,
|
||||||
|
upsample: upsample_pipeline,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
pub mod blit;
|
pub mod blit;
|
||||||
|
pub mod bloom;
|
||||||
pub mod clouds;
|
pub mod clouds;
|
||||||
pub mod debug;
|
pub mod debug;
|
||||||
pub mod figure;
|
pub mod figure;
|
||||||
|
@ -39,7 +39,19 @@ impl PostProcessLayout {
|
|||||||
// src color
|
// src color
|
||||||
wgpu::BindGroupLayoutEntry {
|
wgpu::BindGroupLayoutEntry {
|
||||||
binding: 0,
|
binding: 0,
|
||||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
visibility: wgpu::ShaderStage::FRAGMENT,
|
||||||
|
ty: wgpu::BindingType::Texture {
|
||||||
|
sample_type: wgpu::TextureSampleType::Float { filterable: true },
|
||||||
|
view_dimension: wgpu::TextureViewDimension::D2,
|
||||||
|
multisampled: false,
|
||||||
|
},
|
||||||
|
count: None,
|
||||||
|
},
|
||||||
|
// TODO: make optional
|
||||||
|
// src bloom
|
||||||
|
wgpu::BindGroupLayoutEntry {
|
||||||
|
binding: 0,
|
||||||
|
visibility: wgpu::ShaderStage::FRAGMENT,
|
||||||
ty: wgpu::BindingType::Texture {
|
ty: wgpu::BindingType::Texture {
|
||||||
sample_type: wgpu::TextureSampleType::Float { filterable: true },
|
sample_type: wgpu::TextureSampleType::Float { filterable: true },
|
||||||
view_dimension: wgpu::TextureViewDimension::D2,
|
view_dimension: wgpu::TextureViewDimension::D2,
|
||||||
@ -49,7 +61,7 @@ impl PostProcessLayout {
|
|||||||
},
|
},
|
||||||
wgpu::BindGroupLayoutEntry {
|
wgpu::BindGroupLayoutEntry {
|
||||||
binding: 1,
|
binding: 1,
|
||||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
visibility: wgpu::ShaderStage::FRAGMENT,
|
||||||
ty: wgpu::BindingType::Sampler {
|
ty: wgpu::BindingType::Sampler {
|
||||||
filtering: true,
|
filtering: true,
|
||||||
comparison: false,
|
comparison: false,
|
||||||
@ -76,6 +88,7 @@ impl PostProcessLayout {
|
|||||||
&self,
|
&self,
|
||||||
device: &wgpu::Device,
|
device: &wgpu::Device,
|
||||||
src_color: &wgpu::TextureView,
|
src_color: &wgpu::TextureView,
|
||||||
|
src_bloom: &wgpu::TextureView,
|
||||||
sampler: &wgpu::Sampler,
|
sampler: &wgpu::Sampler,
|
||||||
locals: &Consts<Locals>,
|
locals: &Consts<Locals>,
|
||||||
) -> BindGroup {
|
) -> BindGroup {
|
||||||
@ -87,6 +100,14 @@ impl PostProcessLayout {
|
|||||||
binding: 0,
|
binding: 0,
|
||||||
resource: wgpu::BindingResource::TextureView(src_color),
|
resource: wgpu::BindingResource::TextureView(src_color),
|
||||||
},
|
},
|
||||||
|
// TODO: might be cheaper to premix bloom at lower resolution if we are doing
|
||||||
|
// extensive upscaling
|
||||||
|
// TODO: if there is no upscaling we can do the last bloom upsampling in post
|
||||||
|
// process to save a pass and the need for the final full size bloom render target
|
||||||
|
wgpu::BindGroupEntry {
|
||||||
|
binding: 0,
|
||||||
|
resource: wgpu::BindingResource::TextureView(src_bloom),
|
||||||
|
},
|
||||||
wgpu::BindGroupEntry {
|
wgpu::BindGroupEntry {
|
||||||
binding: 1,
|
binding: 1,
|
||||||
resource: wgpu::BindingResource::Sampler(sampler),
|
resource: wgpu::BindingResource::Sampler(sampler),
|
||||||
|
@ -21,8 +21,8 @@ use super::{
|
|||||||
mesh::Mesh,
|
mesh::Mesh,
|
||||||
model::{DynamicModel, Model},
|
model::{DynamicModel, Model},
|
||||||
pipelines::{
|
pipelines::{
|
||||||
blit, clouds, debug, figure, postprocess, shadow, sprite, terrain, ui, GlobalsBindGroup,
|
blit, bloom, clouds, debug, figure, postprocess, shadow, sprite, terrain, ui,
|
||||||
GlobalsLayouts, ShadowTexturesBindGroup,
|
GlobalsBindGroup, GlobalsLayouts, ShadowTexturesBindGroup,
|
||||||
},
|
},
|
||||||
texture::Texture,
|
texture::Texture,
|
||||||
AaMode, AddressMode, FilterMode, RenderError, RenderMode, ShadowMapMode, ShadowMode, Vertex,
|
AaMode, AddressMode, FilterMode, RenderError, RenderMode, ShadowMapMode, ShadowMode, Vertex,
|
||||||
@ -49,13 +49,14 @@ const QUAD_INDEX_BUFFER_U32_START_VERT_LEN: u32 = 3000;
|
|||||||
struct Layouts {
|
struct Layouts {
|
||||||
global: GlobalsLayouts,
|
global: GlobalsLayouts,
|
||||||
|
|
||||||
clouds: clouds::CloudsLayout,
|
|
||||||
debug: debug::DebugLayout,
|
debug: debug::DebugLayout,
|
||||||
figure: figure::FigureLayout,
|
figure: figure::FigureLayout,
|
||||||
postprocess: postprocess::PostProcessLayout,
|
|
||||||
shadow: shadow::ShadowLayout,
|
shadow: shadow::ShadowLayout,
|
||||||
sprite: sprite::SpriteLayout,
|
sprite: sprite::SpriteLayout,
|
||||||
terrain: terrain::TerrainLayout,
|
terrain: terrain::TerrainLayout,
|
||||||
|
clouds: clouds::CloudsLayout,
|
||||||
|
bloom: bloom::BloomLayout,
|
||||||
|
postprocess: postprocess::PostProcessLayout,
|
||||||
ui: ui::UiLayout,
|
ui: ui::UiLayout,
|
||||||
blit: blit::BlitLayout,
|
blit: blit::BlitLayout,
|
||||||
}
|
}
|
||||||
@ -67,6 +68,8 @@ struct Views {
|
|||||||
|
|
||||||
tgt_color: wgpu::TextureView,
|
tgt_color: wgpu::TextureView,
|
||||||
tgt_depth: wgpu::TextureView,
|
tgt_depth: wgpu::TextureView,
|
||||||
|
|
||||||
|
bloom_tgts: [wgpu::TextureView; bloom::NUM_SIZES],
|
||||||
// TODO: rename
|
// TODO: rename
|
||||||
tgt_color_pp: wgpu::TextureView,
|
tgt_color_pp: wgpu::TextureView,
|
||||||
}
|
}
|
||||||
@ -305,26 +308,28 @@ impl Renderer {
|
|||||||
let layouts = {
|
let layouts = {
|
||||||
let global = GlobalsLayouts::new(&device);
|
let global = GlobalsLayouts::new(&device);
|
||||||
|
|
||||||
let clouds = clouds::CloudsLayout::new(&device);
|
|
||||||
let debug = debug::DebugLayout::new(&device);
|
let debug = debug::DebugLayout::new(&device);
|
||||||
let figure = figure::FigureLayout::new(&device);
|
let figure = figure::FigureLayout::new(&device);
|
||||||
let postprocess = postprocess::PostProcessLayout::new(&device);
|
|
||||||
let shadow = shadow::ShadowLayout::new(&device);
|
let shadow = shadow::ShadowLayout::new(&device);
|
||||||
let sprite = sprite::SpriteLayout::new(&device);
|
let sprite = sprite::SpriteLayout::new(&device);
|
||||||
let terrain = terrain::TerrainLayout::new(&device);
|
let terrain = terrain::TerrainLayout::new(&device);
|
||||||
|
let clouds = clouds::CloudsLayout::new(&device);
|
||||||
|
let bloom = bloom::BloomLayout::new(&device);
|
||||||
|
let postprocess = postprocess::PostProcessLayout::new(&device);
|
||||||
let ui = ui::UiLayout::new(&device);
|
let ui = ui::UiLayout::new(&device);
|
||||||
let blit = blit::BlitLayout::new(&device);
|
let blit = blit::BlitLayout::new(&device);
|
||||||
|
|
||||||
Layouts {
|
Layouts {
|
||||||
global,
|
global,
|
||||||
|
|
||||||
clouds,
|
|
||||||
debug,
|
debug,
|
||||||
figure,
|
figure,
|
||||||
postprocess,
|
|
||||||
shadow,
|
shadow,
|
||||||
sprite,
|
sprite,
|
||||||
terrain,
|
terrain,
|
||||||
|
clouds,
|
||||||
|
bloom,
|
||||||
|
postprocess,
|
||||||
ui,
|
ui,
|
||||||
blit,
|
blit,
|
||||||
}
|
}
|
||||||
@ -350,7 +355,8 @@ impl Renderer {
|
|||||||
creating,
|
creating,
|
||||||
};
|
};
|
||||||
|
|
||||||
let views = Self::create_rt_views(&device, (dims.width, dims.height), &mode)?;
|
let (views, bloom_sizes) =
|
||||||
|
Self::create_rt_views(&device, (dims.width, dims.height), &mode)?;
|
||||||
|
|
||||||
let create_sampler = |filter| {
|
let create_sampler = |filter| {
|
||||||
device.create_sampler(&wgpu::SamplerDescriptor {
|
device.create_sampler(&wgpu::SamplerDescriptor {
|
||||||
@ -379,6 +385,8 @@ impl Renderer {
|
|||||||
|
|
||||||
let clouds_locals =
|
let clouds_locals =
|
||||||
Self::create_consts_inner(&device, &queue, &[clouds::Locals::default()]);
|
Self::create_consts_inner(&device, &queue, &[clouds::Locals::default()]);
|
||||||
|
let bloom_locals = bloom_sizes
|
||||||
|
.map(|size| Self::create_consts_inner(&device, &queue, &[bloom::HalfPixel::new(size)]));
|
||||||
let postprocess_locals =
|
let postprocess_locals =
|
||||||
Self::create_consts_inner(&device, &queue, &[postprocess::Locals::default()]);
|
Self::create_consts_inner(&device, &queue, &[postprocess::Locals::default()]);
|
||||||
|
|
||||||
@ -386,9 +394,18 @@ impl Renderer {
|
|||||||
&device,
|
&device,
|
||||||
&layouts,
|
&layouts,
|
||||||
clouds_locals,
|
clouds_locals,
|
||||||
|
bloom_locals,
|
||||||
postprocess_locals,
|
postprocess_locals,
|
||||||
&views.tgt_color,
|
&views.tgt_color,
|
||||||
&views.tgt_depth,
|
&views.tgt_depth,
|
||||||
|
[
|
||||||
|
&views.tgt_color,
|
||||||
|
&views.bloom_tgts[1],
|
||||||
|
&views.bloom_tgts[2],
|
||||||
|
&views.bloom_tgts[3],
|
||||||
|
&views.bloom_tgts[4],
|
||||||
|
],
|
||||||
|
&views.bloom_tgts[0],
|
||||||
&views.tgt_color_pp,
|
&views.tgt_color_pp,
|
||||||
&sampler,
|
&sampler,
|
||||||
&depth_sampler,
|
&depth_sampler,
|
||||||
@ -546,13 +563,26 @@ impl Renderer {
|
|||||||
self.swap_chain = self.device.create_swap_chain(&self.surface, &self.sc_desc);
|
self.swap_chain = self.device.create_swap_chain(&self.surface, &self.sc_desc);
|
||||||
|
|
||||||
// Resize other render targets
|
// Resize other render targets
|
||||||
self.views = Self::create_rt_views(&self.device, (dims.x, dims.y), &self.mode)?;
|
let (views, bloom_sizes) =
|
||||||
|
Self::create_rt_views(&self.device, (dims.x, dims.y), &self.mode)?;
|
||||||
|
self.views = views;
|
||||||
|
let bloom_locals =
|
||||||
|
bloom_sizes.map(|size| self.create_consts(&[bloom::HalfPixel::new(size)]));
|
||||||
// Rebind views to clouds/postprocess bind groups
|
// Rebind views to clouds/postprocess bind groups
|
||||||
self.locals.rebind(
|
self.locals.rebind(
|
||||||
&self.device,
|
&self.device,
|
||||||
&self.layouts,
|
&self.layouts,
|
||||||
|
bloom_locals,
|
||||||
&self.views.tgt_color,
|
&self.views.tgt_color,
|
||||||
&self.views.tgt_depth,
|
&self.views.tgt_depth,
|
||||||
|
[
|
||||||
|
&self.views.tgt_color,
|
||||||
|
&self.views.bloom_tgts[1],
|
||||||
|
&self.views.bloom_tgts[2],
|
||||||
|
&self.views.bloom_tgts[3],
|
||||||
|
&self.views.bloom_tgts[4],
|
||||||
|
],
|
||||||
|
&self.views.bloom_tgts[0],
|
||||||
&self.views.tgt_color_pp,
|
&self.views.tgt_color_pp,
|
||||||
&self.sampler,
|
&self.sampler,
|
||||||
&self.depth_sampler,
|
&self.depth_sampler,
|
||||||
@ -625,7 +655,7 @@ impl Renderer {
|
|||||||
device: &wgpu::Device,
|
device: &wgpu::Device,
|
||||||
size: (u32, u32),
|
size: (u32, u32),
|
||||||
mode: &RenderMode,
|
mode: &RenderMode,
|
||||||
) -> Result<Views, RenderError> {
|
) -> Result<(Views, [Vec2<f32>; bloom::NUM_SIZES]), RenderError> {
|
||||||
let upscaled = Vec2::<u32>::from(size)
|
let upscaled = Vec2::<u32>::from(size)
|
||||||
.map(|e| (e as f32 * mode.upscale_mode.factor) as u32)
|
.map(|e| (e as f32 * mode.upscale_mode.factor) as u32)
|
||||||
.into_tuple();
|
.into_tuple();
|
||||||
@ -637,7 +667,7 @@ impl Renderer {
|
|||||||
};
|
};
|
||||||
let levels = 1;
|
let levels = 1;
|
||||||
|
|
||||||
let color_view = || {
|
let color_view = |width, height| {
|
||||||
let tex = device.create_texture(&wgpu::TextureDescriptor {
|
let tex = device.create_texture(&wgpu::TextureDescriptor {
|
||||||
label: None,
|
label: None,
|
||||||
size: wgpu::Extent3d {
|
size: wgpu::Extent3d {
|
||||||
@ -665,8 +695,19 @@ impl Renderer {
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
let tgt_color_view = color_view();
|
let tgt_color_view = color_view(width, height);
|
||||||
let tgt_color_pp_view = color_view();
|
let tgt_color_pp_view = color_view(width, height);
|
||||||
|
|
||||||
|
let mut size_shift = 0;
|
||||||
|
// TODO: skip creating bloom stuff when it is disabled
|
||||||
|
let bloom_sizes = [(); bloom::NUM_SIZES].map(|()| {
|
||||||
|
// .max(1) to ensure we don't create zero sized textures
|
||||||
|
let size = Vec2::new(width, height).map(|e| (e >> size_shift).max(1));
|
||||||
|
size_shift += 1;
|
||||||
|
size
|
||||||
|
});
|
||||||
|
|
||||||
|
let bloom_tgt_views = bloom_sizes.map(|size| color_view(size.x, size.y));
|
||||||
|
|
||||||
let tgt_depth_tex = device.create_texture(&wgpu::TextureDescriptor {
|
let tgt_depth_tex = device.create_texture(&wgpu::TextureDescriptor {
|
||||||
label: None,
|
label: None,
|
||||||
@ -717,12 +758,16 @@ impl Renderer {
|
|||||||
array_layer_count: None,
|
array_layer_count: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(Views {
|
Ok((
|
||||||
|
Views {
|
||||||
tgt_color: tgt_color_view,
|
tgt_color: tgt_color_view,
|
||||||
tgt_depth: tgt_depth_view,
|
tgt_depth: tgt_depth_view,
|
||||||
|
bloom_tgts: bloom_tgt_views,
|
||||||
tgt_color_pp: tgt_color_pp_view,
|
tgt_color_pp: tgt_color_pp_view,
|
||||||
_win_depth: win_depth_view,
|
_win_depth: win_depth_view,
|
||||||
})
|
},
|
||||||
|
bloom_sizes.map(|s| s.map(|e| e as f32)),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the resolution of the render target.
|
/// Get the resolution of the render target.
|
||||||
|
@ -4,8 +4,8 @@ use super::{
|
|||||||
instances::Instances,
|
instances::Instances,
|
||||||
model::{DynamicModel, Model, SubModel},
|
model::{DynamicModel, Model, SubModel},
|
||||||
pipelines::{
|
pipelines::{
|
||||||
blit, clouds, debug, figure, fluid, lod_terrain, particle, shadow, skybox, sprite,
|
blit, bloom, clouds, debug, figure, fluid, lod_terrain, particle, shadow, skybox,
|
||||||
terrain, ui, ColLights, GlobalsBindGroup, ShadowTexturesBindGroup,
|
sprite, terrain, ui, ColLights, GlobalsBindGroup, ShadowTexturesBindGroup,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Renderer, ShadowMap, ShadowMapRenderer,
|
Renderer, ShadowMap, ShadowMapRenderer,
|
||||||
@ -241,6 +241,57 @@ impl<'frame> Drawer<'frame> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// To be ran between the second pass and the third pass
|
||||||
|
/// does nothing if the ingame pipelines are not yet ready
|
||||||
|
pub fn run_bloom_passes(&mut self) {
|
||||||
|
let pipelines = match self.borrow.pipelines.all() {
|
||||||
|
Some(p) => p,
|
||||||
|
None => return,
|
||||||
|
};
|
||||||
|
|
||||||
|
let locals = &self.borrow.locals;
|
||||||
|
let views = &self.borrow.views;
|
||||||
|
|
||||||
|
let encoder = self.encoder.as_mut().unwrap();
|
||||||
|
let device = self.borrow.device;
|
||||||
|
|
||||||
|
let mut run_bloom_pass = |bind, view, label: String, pipeline| {
|
||||||
|
let mut render_pass =
|
||||||
|
encoder.scoped_render_pass(&label, device, &wgpu::RenderPassDescriptor {
|
||||||
|
label: Some(&label),
|
||||||
|
color_attachments: &[wgpu::RenderPassColorAttachment {
|
||||||
|
resolve_target: None,
|
||||||
|
view,
|
||||||
|
ops: wgpu::Operations {
|
||||||
|
load: wgpu::LoadOp::Clear(wgpu::Color::TRANSPARENT),
|
||||||
|
store: true,
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
depth_stencil_attachment: None,
|
||||||
|
});
|
||||||
|
|
||||||
|
render_pass.set_bind_group(0, bind, &[]);
|
||||||
|
render_pass.set_pipeline(pipeline);
|
||||||
|
render_pass.draw(0..3, 0..1);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Downsample filter passes
|
||||||
|
(0..bloom::NUM_SIZES - 1).for_each(|index| {
|
||||||
|
let bind = &locals.bloom_binds[index].bind_group;
|
||||||
|
let view = &views.bloom_tgts[index + 1];
|
||||||
|
let label = format!("bloom downsample pass {}", index + 1);
|
||||||
|
run_bloom_pass(bind, view, label, &pipelines.bloom.downsample);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Upsample filter passes
|
||||||
|
(0..bloom::NUM_SIZES - 1).for_each(|index| {
|
||||||
|
let bind = &locals.bloom_binds[bloom::NUM_SIZES - 1 - index].bind_group;
|
||||||
|
let view = &views.bloom_tgts[bloom::NUM_SIZES - 2 - index];
|
||||||
|
let label = format!("bloom upsample pass {}", index + 1);
|
||||||
|
run_bloom_pass(bind, view, label, &pipelines.bloom.upsample);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
pub fn third_pass(&mut self) -> ThirdPassDrawer {
|
pub fn third_pass(&mut self) -> ThirdPassDrawer {
|
||||||
let encoder = self.encoder.as_mut().unwrap();
|
let encoder = self.encoder.as_mut().unwrap();
|
||||||
let device = self.borrow.device;
|
let device = self.borrow.device;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use super::{
|
use super::{
|
||||||
super::{
|
super::{
|
||||||
consts::Consts,
|
consts::Consts,
|
||||||
pipelines::{clouds, postprocess},
|
pipelines::{bloom, clouds, postprocess},
|
||||||
},
|
},
|
||||||
Layouts,
|
Layouts,
|
||||||
};
|
};
|
||||||
@ -10,6 +10,8 @@ pub struct Locals {
|
|||||||
pub clouds: Consts<clouds::Locals>,
|
pub clouds: Consts<clouds::Locals>,
|
||||||
pub clouds_bind: clouds::BindGroup,
|
pub clouds_bind: clouds::BindGroup,
|
||||||
|
|
||||||
|
pub bloom_binds: [bloom::BindGroup; bloom::NUM_SIZES],
|
||||||
|
|
||||||
pub postprocess: Consts<postprocess::Locals>,
|
pub postprocess: Consts<postprocess::Locals>,
|
||||||
pub postprocess_bind: postprocess::BindGroup,
|
pub postprocess_bind: postprocess::BindGroup,
|
||||||
}
|
}
|
||||||
@ -19,9 +21,12 @@ impl Locals {
|
|||||||
device: &wgpu::Device,
|
device: &wgpu::Device,
|
||||||
layouts: &Layouts,
|
layouts: &Layouts,
|
||||||
clouds_locals: Consts<clouds::Locals>,
|
clouds_locals: Consts<clouds::Locals>,
|
||||||
|
bloom_locals: [Consts<bloom::HalfPixel>; bloom::NUM_SIZES],
|
||||||
postprocess_locals: Consts<postprocess::Locals>,
|
postprocess_locals: Consts<postprocess::Locals>,
|
||||||
tgt_color_view: &wgpu::TextureView,
|
tgt_color_view: &wgpu::TextureView,
|
||||||
tgt_depth_view: &wgpu::TextureView,
|
tgt_depth_view: &wgpu::TextureView,
|
||||||
|
bloom_src_views: [&wgpu::TextureView; bloom::NUM_SIZES],
|
||||||
|
bloom_final_tgt_view: &wgpu::TextureView,
|
||||||
tgt_color_pp_view: &wgpu::TextureView,
|
tgt_color_pp_view: &wgpu::TextureView,
|
||||||
sampler: &wgpu::Sampler,
|
sampler: &wgpu::Sampler,
|
||||||
depth_sampler: &wgpu::Sampler,
|
depth_sampler: &wgpu::Sampler,
|
||||||
@ -34,14 +39,22 @@ impl Locals {
|
|||||||
depth_sampler,
|
depth_sampler,
|
||||||
&clouds_locals,
|
&clouds_locals,
|
||||||
);
|
);
|
||||||
let postprocess_bind =
|
let bloom_binds = bloom_src_views
|
||||||
layouts
|
.zip(bloom_locals)
|
||||||
.postprocess
|
.map(|(view, locals)| layouts.bloom.bind(device, view, sampler, locals));
|
||||||
.bind(device, tgt_color_pp_view, sampler, &postprocess_locals);
|
|
||||||
|
let postprocess_bind = layouts.postprocess.bind(
|
||||||
|
device,
|
||||||
|
tgt_color_pp_view,
|
||||||
|
bloom_final_tgt_view,
|
||||||
|
sampler,
|
||||||
|
&postprocess_locals,
|
||||||
|
);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
clouds: clouds_locals,
|
clouds: clouds_locals,
|
||||||
clouds_bind,
|
clouds_bind,
|
||||||
|
bloom_binds,
|
||||||
postprocess: postprocess_locals,
|
postprocess: postprocess_locals,
|
||||||
postprocess_bind,
|
postprocess_bind,
|
||||||
}
|
}
|
||||||
@ -53,8 +66,11 @@ impl Locals {
|
|||||||
layouts: &Layouts,
|
layouts: &Layouts,
|
||||||
// Call when these are recreated and need to be rebound
|
// Call when these are recreated and need to be rebound
|
||||||
// e.g. resizing
|
// e.g. resizing
|
||||||
|
bloom_locals: [Consts<bloom::HalfPixel>; bloom::NUM_SIZES],
|
||||||
tgt_color_view: &wgpu::TextureView,
|
tgt_color_view: &wgpu::TextureView,
|
||||||
tgt_depth_view: &wgpu::TextureView,
|
tgt_depth_view: &wgpu::TextureView,
|
||||||
|
bloom_src_views: [&wgpu::TextureView; bloom::NUM_SIZES],
|
||||||
|
bloom_final_tgt_view: &wgpu::TextureView,
|
||||||
tgt_color_pp_view: &wgpu::TextureView,
|
tgt_color_pp_view: &wgpu::TextureView,
|
||||||
sampler: &wgpu::Sampler,
|
sampler: &wgpu::Sampler,
|
||||||
depth_sampler: &wgpu::Sampler,
|
depth_sampler: &wgpu::Sampler,
|
||||||
@ -67,9 +83,15 @@ impl Locals {
|
|||||||
depth_sampler,
|
depth_sampler,
|
||||||
&self.clouds,
|
&self.clouds,
|
||||||
);
|
);
|
||||||
self.postprocess_bind =
|
self.bloom_binds = bloom_src_views
|
||||||
layouts
|
.zip(bloom_locals)
|
||||||
.postprocess
|
.map(|(view, locals)| layouts.bloom.bind(device, view, sampler, locals));
|
||||||
.bind(device, tgt_color_pp_view, sampler, &self.postprocess);
|
self.postprocess_bind = layouts.postprocess.bind(
|
||||||
|
device,
|
||||||
|
tgt_color_pp_view,
|
||||||
|
bloom_final_tgt_view,
|
||||||
|
sampler,
|
||||||
|
&self.postprocess,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use super::{
|
use super::{
|
||||||
super::{
|
super::{
|
||||||
pipelines::{
|
pipelines::{
|
||||||
blit, clouds, debug, figure, fluid, lod_terrain, particle, postprocess, shadow, skybox,
|
blit, bloom, clouds, debug, figure, fluid, lod_terrain, particle, postprocess, shadow,
|
||||||
sprite, terrain, ui,
|
skybox, sprite, terrain, ui,
|
||||||
},
|
},
|
||||||
AaMode, CloudMode, FluidMode, LightingMode, RenderError, RenderMode, ShadowMode,
|
AaMode, CloudMode, FluidMode, LightingMode, RenderError, RenderMode, ShadowMode,
|
||||||
},
|
},
|
||||||
@ -20,6 +20,7 @@ pub struct Pipelines {
|
|||||||
pub lod_terrain: lod_terrain::LodTerrainPipeline,
|
pub lod_terrain: lod_terrain::LodTerrainPipeline,
|
||||||
pub particle: particle::ParticlePipeline,
|
pub particle: particle::ParticlePipeline,
|
||||||
pub clouds: clouds::CloudsPipeline,
|
pub clouds: clouds::CloudsPipeline,
|
||||||
|
pub bloom: bloom::BloomPipelines,
|
||||||
pub postprocess: postprocess::PostProcessPipeline,
|
pub postprocess: postprocess::PostProcessPipeline,
|
||||||
// Consider reenabling at some time
|
// Consider reenabling at some time
|
||||||
// player_shadow: figure::FigurePipeline,
|
// player_shadow: figure::FigurePipeline,
|
||||||
@ -39,6 +40,7 @@ pub struct IngamePipelines {
|
|||||||
lod_terrain: lod_terrain::LodTerrainPipeline,
|
lod_terrain: lod_terrain::LodTerrainPipeline,
|
||||||
particle: particle::ParticlePipeline,
|
particle: particle::ParticlePipeline,
|
||||||
clouds: clouds::CloudsPipeline,
|
clouds: clouds::CloudsPipeline,
|
||||||
|
bloom: bloom::BloomPipelines,
|
||||||
postprocess: postprocess::PostProcessPipeline,
|
postprocess: postprocess::PostProcessPipeline,
|
||||||
// Consider reenabling at some time
|
// Consider reenabling at some time
|
||||||
// player_shadow: figure::FigurePipeline,
|
// player_shadow: figure::FigurePipeline,
|
||||||
@ -74,6 +76,7 @@ impl Pipelines {
|
|||||||
lod_terrain: ingame.lod_terrain,
|
lod_terrain: ingame.lod_terrain,
|
||||||
particle: ingame.particle,
|
particle: ingame.particle,
|
||||||
clouds: ingame.clouds,
|
clouds: ingame.clouds,
|
||||||
|
bloom: ingame.bloom,
|
||||||
postprocess: ingame.postprocess,
|
postprocess: ingame.postprocess,
|
||||||
//player_shadow: ingame.player_shadow,
|
//player_shadow: ingame.player_shadow,
|
||||||
skybox: ingame.skybox,
|
skybox: ingame.skybox,
|
||||||
@ -107,6 +110,8 @@ struct ShaderModules {
|
|||||||
lod_terrain_frag: wgpu::ShaderModule,
|
lod_terrain_frag: wgpu::ShaderModule,
|
||||||
clouds_vert: wgpu::ShaderModule,
|
clouds_vert: wgpu::ShaderModule,
|
||||||
clouds_frag: wgpu::ShaderModule,
|
clouds_frag: wgpu::ShaderModule,
|
||||||
|
duel_downsample_frag: wgpu::ShaderModule,
|
||||||
|
duel_upsample_frag: wgpu::ShaderModule,
|
||||||
postprocess_vert: wgpu::ShaderModule,
|
postprocess_vert: wgpu::ShaderModule,
|
||||||
postprocess_frag: wgpu::ShaderModule,
|
postprocess_frag: wgpu::ShaderModule,
|
||||||
blit_vert: wgpu::ShaderModule,
|
blit_vert: wgpu::ShaderModule,
|
||||||
@ -255,6 +260,8 @@ impl ShaderModules {
|
|||||||
lod_terrain_frag: create_shader("lod-terrain-frag", ShaderKind::Fragment)?,
|
lod_terrain_frag: create_shader("lod-terrain-frag", ShaderKind::Fragment)?,
|
||||||
clouds_vert: create_shader("clouds-vert", ShaderKind::Vertex)?,
|
clouds_vert: create_shader("clouds-vert", ShaderKind::Vertex)?,
|
||||||
clouds_frag: create_shader("clouds-frag", ShaderKind::Fragment)?,
|
clouds_frag: create_shader("clouds-frag", ShaderKind::Fragment)?,
|
||||||
|
duel_downsample_frag: create_shader("duel-downsample-frag", ShaderKind::Fragment)?,
|
||||||
|
duel_upsample_frag: create_shader("duel-upsample-frag", ShaderKind::Fragment)?,
|
||||||
postprocess_vert: create_shader("postprocess-vert", ShaderKind::Vertex)?,
|
postprocess_vert: create_shader("postprocess-vert", ShaderKind::Vertex)?,
|
||||||
postprocess_frag: create_shader("postprocess-frag", ShaderKind::Fragment)?,
|
postprocess_frag: create_shader("postprocess-frag", ShaderKind::Fragment)?,
|
||||||
blit_vert: create_shader("blit-vert", ShaderKind::Vertex)?,
|
blit_vert: create_shader("blit-vert", ShaderKind::Vertex)?,
|
||||||
@ -360,7 +367,7 @@ fn create_interface_pipelines(
|
|||||||
fn create_ingame_and_shadow_pipelines(
|
fn create_ingame_and_shadow_pipelines(
|
||||||
needs: PipelineNeeds,
|
needs: PipelineNeeds,
|
||||||
pool: &rayon::ThreadPool,
|
pool: &rayon::ThreadPool,
|
||||||
tasks: [Task; 13],
|
tasks: [Task; 14],
|
||||||
) -> IngameAndShadowPipelines {
|
) -> IngameAndShadowPipelines {
|
||||||
prof_span!(_guard, "create_ingame_and_shadow_pipelines");
|
prof_span!(_guard, "create_ingame_and_shadow_pipelines");
|
||||||
|
|
||||||
@ -382,6 +389,7 @@ fn create_ingame_and_shadow_pipelines(
|
|||||||
particle_task,
|
particle_task,
|
||||||
lod_terrain_task,
|
lod_terrain_task,
|
||||||
clouds_task,
|
clouds_task,
|
||||||
|
bloom_task,
|
||||||
postprocess_task,
|
postprocess_task,
|
||||||
// TODO: if these are ever actually optionally done, counting them
|
// TODO: if these are ever actually optionally done, counting them
|
||||||
// as tasks to do beforehand seems kind of iffy since they will just
|
// as tasks to do beforehand seems kind of iffy since they will just
|
||||||
@ -535,6 +543,22 @@ fn create_ingame_and_shadow_pipelines(
|
|||||||
"clouds pipeline creation",
|
"clouds pipeline creation",
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
// Pipelines for rendering our bloom
|
||||||
|
let create_bloom = || {
|
||||||
|
bloom_task.run(
|
||||||
|
|| {
|
||||||
|
bloom::BloomPipelines::new(
|
||||||
|
device,
|
||||||
|
&shaders.blit_vert,
|
||||||
|
&shaders.duel_downsample_frag,
|
||||||
|
&shaders.duel_upsample_frag,
|
||||||
|
wgpu::TextureFormat::Rgba16Float,
|
||||||
|
&layouts.bloom,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
"bloom pipelines creation",
|
||||||
|
)
|
||||||
|
};
|
||||||
// Pipeline for rendering our post-processing
|
// Pipeline for rendering our post-processing
|
||||||
let create_postprocess = || {
|
let create_postprocess = || {
|
||||||
postprocess_task.run(
|
postprocess_task.run(
|
||||||
@ -622,7 +646,7 @@ fn create_ingame_and_shadow_pipelines(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let j1 = || pool.join(create_debug, || pool.join(create_skybox, create_figure));
|
let j1 = || pool.join(create_debug, || pool.join(create_skybox, create_figure));
|
||||||
let j2 = || pool.join(create_terrain, create_fluid);
|
let j2 = || pool.join(create_terrain, || pool.join(create_fluid, create_bloom));
|
||||||
let j3 = || pool.join(create_sprite, create_particle);
|
let j3 = || pool.join(create_sprite, create_particle);
|
||||||
let j4 = || pool.join(create_lod_terrain, create_clouds);
|
let j4 = || pool.join(create_lod_terrain, create_clouds);
|
||||||
let j5 = || pool.join(create_postprocess, create_point_shadow);
|
let j5 = || pool.join(create_postprocess, create_point_shadow);
|
||||||
@ -636,7 +660,7 @@ fn create_ingame_and_shadow_pipelines(
|
|||||||
// Ignore this
|
// Ignore this
|
||||||
let (
|
let (
|
||||||
(
|
(
|
||||||
((debug, (skybox, figure)), (terrain, fluid)),
|
((debug, (skybox, figure)), (terrain, (fluid, bloom))),
|
||||||
((sprite, particle), (lod_terrain, clouds)),
|
((sprite, particle), (lod_terrain, clouds)),
|
||||||
),
|
),
|
||||||
((postprocess, point_shadow), (terrain_directed_shadow, figure_directed_shadow)),
|
((postprocess, point_shadow), (terrain_directed_shadow, figure_directed_shadow)),
|
||||||
@ -653,6 +677,7 @@ fn create_ingame_and_shadow_pipelines(
|
|||||||
lod_terrain,
|
lod_terrain,
|
||||||
particle,
|
particle,
|
||||||
clouds,
|
clouds,
|
||||||
|
bloom,
|
||||||
postprocess,
|
postprocess,
|
||||||
skybox,
|
skybox,
|
||||||
sprite,
|
sprite,
|
||||||
|
@ -1483,6 +1483,12 @@ impl PlayState for SessionState {
|
|||||||
second_pass.draw_clouds();
|
second_pass.draw_clouds();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Bloom
|
||||||
|
// TODO: make optional
|
||||||
|
{
|
||||||
|
prof_span!("bloom");
|
||||||
|
drawer.run_bloom_passes()
|
||||||
|
}
|
||||||
// PostProcess and UI
|
// PostProcess and UI
|
||||||
{
|
{
|
||||||
prof_span!("post-process and ui");
|
prof_span!("post-process and ui");
|
||||||
|
Reference in New Issue
Block a user