mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Make bloom intensity configurable, make whether less blurred layers are added in toggleable, hold onto copy of pipeline modes instead of returning it from pipeline creation
This commit is contained in:
parent
147e4f00f6
commit
a1026c36f5
@ -24,9 +24,6 @@
|
||||
#define SHADOW_MODE_CHEAP 1
|
||||
#define SHADOW_MODE_MAP 2
|
||||
|
||||
#define BLOOM_DISABLED 0
|
||||
#define BLOOM_ENABLED 1
|
||||
|
||||
/* Unlike the other flags (for now anyway), these are bitmask values */
|
||||
#define LIGHTING_TYPE_REFLECTION 0x01
|
||||
#define LIGHTING_TYPE_TRANSMISSION 0x02
|
||||
|
@ -35,7 +35,7 @@ uniform u_locals {
|
||||
mat4 view_mat_inv;
|
||||
};
|
||||
|
||||
#if (BLOOM == BLOOM_ENABLED)
|
||||
#ifdef BLOOM_FACTOR
|
||||
layout(set = 1, binding = 3)
|
||||
uniform texture2D t_src_bloom;
|
||||
#endif
|
||||
@ -187,11 +187,13 @@ void main() {
|
||||
vec4 aa_color = aa_apply(t_src_color, s_src_color, uv * screen_res.xy, screen_res.xy);
|
||||
|
||||
// Bloom
|
||||
#if (BLOOM == BLOOM_ENABLED)
|
||||
// divide by 4.0 to account for adding blurred layers together
|
||||
vec4 bloom = textureLod(sampler2D(t_src_bloom, s_src_color), uv, 0) / 4.0;
|
||||
float bloom_factor = 0.10;
|
||||
aa_color = mix(aa_color, bloom, bloom_factor);
|
||||
#ifdef BLOOM_FACTOR
|
||||
vec4 bloom = textureLod(sampler2D(t_src_bloom, s_src_color), uv, 0);
|
||||
#if (BLOOM_UNIFORM_BLUR == false)
|
||||
// divide by 4.0 to account for adding blurred layers together
|
||||
bloom /= 4.0;
|
||||
#endif
|
||||
aa_color = mix(aa_color, bloom, BLOOM_FACTOR);
|
||||
#endif
|
||||
|
||||
// Tonemapping
|
||||
|
@ -265,6 +265,66 @@ impl From<PresentMode> for wgpu::PresentMode {
|
||||
}
|
||||
}
|
||||
|
||||
/// Bloom factor
|
||||
/// Controls fraction of output image luminosity that is blurred bloom
|
||||
#[derive(PartialEq, Clone, Copy, Debug, Serialize, Deserialize)]
|
||||
pub enum BloomFactor {
|
||||
Low,
|
||||
High,
|
||||
/// Max valid value is 1.0
|
||||
Custom(f32),
|
||||
// other variant has to be placed last
|
||||
#[serde(other)]
|
||||
Standard,
|
||||
}
|
||||
|
||||
impl Default for BloomFactor {
|
||||
fn default() -> Self { Self::Standard }
|
||||
}
|
||||
|
||||
impl BloomFactor {
|
||||
/// Fraction of output image luminosity that is blurred bloom
|
||||
pub fn fraction(self) -> f32 {
|
||||
match self {
|
||||
Self::Low => 0.05,
|
||||
Self::Standard => 0.10,
|
||||
Self::High => 0.25,
|
||||
Self::Custom(val) => val.max(0.0).min(1.0),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Bloom settings
|
||||
#[derive(PartialEq, Clone, Copy, Debug, Serialize, Deserialize)]
|
||||
pub struct BloomConfig {
|
||||
/// Controls fraction of output image luminosity that is blurred bloom
|
||||
///
|
||||
/// Defaults to `Standard`
|
||||
factor: BloomFactor,
|
||||
/// Turning this on make the bloom blur less sharply concentrated around the
|
||||
/// high intensity phenomena (removes adding in less blurred layers to the
|
||||
/// final blur)
|
||||
///
|
||||
/// Defaults to `false`
|
||||
uniform_blur: bool,
|
||||
// TODO: allow configuring the blur radius and/or the number of passes
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Copy, Debug, Serialize, Deserialize)]
|
||||
pub enum BloomMode {
|
||||
On(BloomConfig),
|
||||
#[serde(other)]
|
||||
Off,
|
||||
}
|
||||
|
||||
impl Default for BloomMode {
|
||||
fn default() -> Self { Self::Off }
|
||||
}
|
||||
|
||||
impl BloomMode {
|
||||
fn is_on(&self) -> bool { matches!(self, BloomMode::On(_)) }
|
||||
}
|
||||
|
||||
/// Render modes
|
||||
#[derive(PartialEq, Clone, Debug, Default, Serialize, Deserialize)]
|
||||
#[serde(default)]
|
||||
@ -274,7 +334,7 @@ pub struct RenderMode {
|
||||
pub fluid: FluidMode,
|
||||
pub lighting: LightingMode,
|
||||
pub shadow: ShadowMode,
|
||||
pub bloom: bool,
|
||||
pub bloom: BloomMode,
|
||||
|
||||
pub upscale_mode: UpscaleMode,
|
||||
pub present_mode: PresentMode,
|
||||
@ -310,7 +370,7 @@ pub struct PipelineModes {
|
||||
fluid: FluidMode,
|
||||
lighting: LightingMode,
|
||||
pub shadow: ShadowMode,
|
||||
bloom: bool,
|
||||
bloom: BloomMode,
|
||||
}
|
||||
|
||||
/// Other render modes that don't effect pipelines
|
||||
|
@ -2,7 +2,7 @@
|
||||
//!
|
||||
//! See additional details in the [NUM_SIZES] docs
|
||||
|
||||
use super::super::Consts;
|
||||
use super::super::{BloomConfig, Consts};
|
||||
use bytemuck::{Pod, Zeroable};
|
||||
use vek::*;
|
||||
|
||||
@ -152,6 +152,7 @@ impl BloomPipelines {
|
||||
upsample_fs_module: &wgpu::ShaderModule,
|
||||
target_format: wgpu::TextureFormat,
|
||||
layout: &BloomLayout,
|
||||
bloom_config: &BloomConfig,
|
||||
) -> Self {
|
||||
common_base::span!(_guard, "BloomPipelines::new");
|
||||
let render_pipeline_layout =
|
||||
@ -207,18 +208,14 @@ impl BloomPipelines {
|
||||
let upsample_pipeline = create_pipeline(
|
||||
"Bloom upsample pipeline",
|
||||
upsample_fs_module,
|
||||
Some(wgpu::BlendState {
|
||||
(!bloom_config.uniform_blur).then(|| wgpu::BlendState {
|
||||
color: wgpu::BlendComponent {
|
||||
src_factor: wgpu::BlendFactor::One,
|
||||
dst_factor: wgpu::BlendFactor::One,
|
||||
operation: wgpu::BlendOperation::Add,
|
||||
},
|
||||
// we don't really use this, but... we need something here
|
||||
alpha: wgpu::BlendComponent {
|
||||
src_factor: wgpu::BlendFactor::One,
|
||||
dst_factor: wgpu::BlendFactor::One,
|
||||
operation: wgpu::BlendOperation::Add,
|
||||
},
|
||||
// We don't reaaly use this but we need something here..
|
||||
alpha: wgpu::BlendComponent::REPLACE,
|
||||
}),
|
||||
);
|
||||
|
||||
|
@ -66,7 +66,7 @@ impl PostProcessLayout {
|
||||
},
|
||||
];
|
||||
|
||||
if pipeline_modes.bloom {
|
||||
if pipeline_modes.bloom.is_on() {
|
||||
bind_entries.push(
|
||||
// src bloom
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
|
@ -111,19 +111,19 @@ enum State {
|
||||
Complete {
|
||||
pipelines: Pipelines,
|
||||
shadow: Shadow,
|
||||
recreating: Option<
|
||||
recreating: Option<(
|
||||
PipelineModes,
|
||||
PipelineCreation<
|
||||
Result<
|
||||
(
|
||||
Pipelines,
|
||||
ShadowPipelines,
|
||||
PipelineModes,
|
||||
Arc<postprocess::PostProcessLayout>,
|
||||
),
|
||||
RenderError,
|
||||
>,
|
||||
>,
|
||||
>,
|
||||
)>,
|
||||
},
|
||||
}
|
||||
|
||||
@ -522,7 +522,7 @@ impl Renderer {
|
||||
/// Returns `Some((total, complete))` if in progress
|
||||
pub fn pipeline_recreation_status(&self) -> Option<(usize, usize)> {
|
||||
if let State::Complete { recreating, .. } = &self.state {
|
||||
recreating.as_ref().map(|r| r.status())
|
||||
recreating.as_ref().map(|(_, c)| c.status())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@ -765,6 +765,7 @@ impl Renderer {
|
||||
|
||||
let bloom_tgt_views = pipeline_modes
|
||||
.bloom
|
||||
.is_on()
|
||||
.then(|| bloom_sizes.map(|size| color_view(size.x, size.y)));
|
||||
|
||||
let tgt_depth_tex = device.create_texture(&wgpu::TextureDescriptor {
|
||||
@ -964,11 +965,11 @@ impl Renderer {
|
||||
} else if let State::Complete {
|
||||
pipelines,
|
||||
mut shadow,
|
||||
recreating: Some(recreating),
|
||||
recreating: Some((new_pipeline_modes, pipeline_creation)),
|
||||
} = state
|
||||
{
|
||||
match recreating.try_complete() {
|
||||
Ok(Ok((pipelines, shadow_pipelines, new_pipeline_modes, postprocess_layout))) => {
|
||||
match pipeline_creation.try_complete() {
|
||||
Ok(Ok((pipelines, shadow_pipelines, postprocess_layout))) => {
|
||||
if let (
|
||||
Some(point_pipeline),
|
||||
Some(terrain_directed_pipeline),
|
||||
@ -1007,10 +1008,10 @@ impl Renderer {
|
||||
}
|
||||
},
|
||||
// Not complete
|
||||
Err(recreating) => State::Complete {
|
||||
Err(pipeline_creation) => State::Complete {
|
||||
pipelines,
|
||||
shadow,
|
||||
recreating: Some(recreating),
|
||||
recreating: Some((new_pipeline_modes, pipeline_creation)),
|
||||
},
|
||||
}
|
||||
} else {
|
||||
@ -1080,16 +1081,20 @@ impl Renderer {
|
||||
State::Complete {
|
||||
recreating, shadow, ..
|
||||
} => {
|
||||
*recreating = Some(pipeline_creation::recreate_pipelines(
|
||||
Arc::clone(&self.device),
|
||||
Arc::clone(&self.layouts.immutable),
|
||||
self.shaders.read().clone(),
|
||||
self.pipeline_modes.clone(),
|
||||
// NOTE: if present_mode starts to be used to configure pipelines then it needs
|
||||
// to become a part of the pipeline modes (note here since the present mode is
|
||||
// accessible through the swap chain descriptor)
|
||||
self.sc_desc.clone(), // Note: cheap clone
|
||||
shadow.map.is_enabled(),
|
||||
*recreating = Some((
|
||||
pipeline_modes.clone(),
|
||||
pipeline_creation::recreate_pipelines(
|
||||
Arc::clone(&self.device),
|
||||
Arc::clone(&self.layouts.immutable),
|
||||
self.shaders.read().clone(),
|
||||
pipeline_modes,
|
||||
// NOTE: if present_mode starts to be used to configure pipelines then it
|
||||
// needs to become a part of the pipeline modes
|
||||
// (note here since the present mode is accessible
|
||||
// through the swap chain descriptor)
|
||||
self.sc_desc.clone(), // Note: cheap clone
|
||||
shadow.map.is_enabled(),
|
||||
),
|
||||
));
|
||||
},
|
||||
State::Interface { .. } => {
|
||||
|
@ -4,7 +4,8 @@ use super::{
|
||||
blit, bloom, clouds, debug, figure, fluid, lod_terrain, particle, postprocess, shadow,
|
||||
skybox, sprite, terrain, ui,
|
||||
},
|
||||
AaMode, CloudMode, FluidMode, LightingMode, PipelineModes, RenderError, ShadowMode,
|
||||
AaMode, BloomMode, CloudMode, FluidMode, LightingMode, PipelineModes, RenderError,
|
||||
ShadowMode,
|
||||
},
|
||||
shaders::Shaders,
|
||||
ImmutableLayouts, Layouts,
|
||||
@ -151,7 +152,6 @@ impl ShaderModules {
|
||||
#define CLOUD_MODE {}
|
||||
#define LIGHTING_ALGORITHM {}
|
||||
#define SHADOW_MODE {}
|
||||
#define BLOOM {}
|
||||
|
||||
"#,
|
||||
&constants.0,
|
||||
@ -179,13 +179,26 @@ impl ShaderModules {
|
||||
ShadowMode::Map(_) if has_shadow_views => "SHADOW_MODE_MAP",
|
||||
ShadowMode::Cheap | ShadowMode::Map(_) => "SHADOW_MODE_CHEAP",
|
||||
},
|
||||
if pipeline_modes.bloom {
|
||||
"BLOOM_ENABLED"
|
||||
} else {
|
||||
"BLOOM_DISABLED"
|
||||
},
|
||||
);
|
||||
|
||||
let constants = match pipeline_modes.bloom {
|
||||
BloomMode::Off => constants,
|
||||
BloomMode::On(config) => {
|
||||
format!(
|
||||
r#"
|
||||
{}
|
||||
|
||||
#define BLOOM_FACTOR {}
|
||||
#define BLOOM_UNIFORM_BLUR {}
|
||||
|
||||
"#,
|
||||
constants,
|
||||
config.factor.fraction(),
|
||||
config.uniform_blur,
|
||||
)
|
||||
},
|
||||
};
|
||||
|
||||
let anti_alias = shaders
|
||||
.get(match pipeline_modes.aa {
|
||||
AaMode::None => "antialias.none",
|
||||
@ -558,7 +571,11 @@ fn create_ingame_and_shadow_pipelines(
|
||||
let create_bloom = || {
|
||||
bloom_task.run(
|
||||
|| {
|
||||
pipeline_modes.bloom.then(|| {
|
||||
match &pipeline_modes.bloom {
|
||||
BloomMode::Off => None,
|
||||
BloomMode::On(config) => Some(config),
|
||||
}
|
||||
.map(|bloom_config| {
|
||||
bloom::BloomPipelines::new(
|
||||
device,
|
||||
&shaders.blit_vert,
|
||||
@ -567,6 +584,7 @@ fn create_ingame_and_shadow_pipelines(
|
||||
&shaders.dual_upsample_frag,
|
||||
wgpu::TextureFormat::Rgba16Float,
|
||||
&layouts.bloom,
|
||||
bloom_config,
|
||||
)
|
||||
})
|
||||
},
|
||||
@ -797,7 +815,6 @@ pub(super) fn recreate_pipelines(
|
||||
(
|
||||
Pipelines,
|
||||
ShadowPipelines,
|
||||
PipelineModes,
|
||||
Arc<postprocess::PostProcessLayout>,
|
||||
),
|
||||
RenderError,
|
||||
@ -871,7 +888,6 @@ pub(super) fn recreate_pipelines(
|
||||
.send(Ok((
|
||||
Pipelines::consolidate(interface, ingame),
|
||||
shadow,
|
||||
pipeline_modes,
|
||||
layouts.postprocess,
|
||||
)))
|
||||
.expect("Channel disconnected");
|
||||
|
@ -43,7 +43,6 @@ pub struct GraphicsSettings {
|
||||
pub window_size: [u16; 2],
|
||||
pub fullscreen: FullScreenSettings,
|
||||
pub lod_detail: u32,
|
||||
pub bloom_enabled: bool,
|
||||
}
|
||||
|
||||
impl Default for GraphicsSettings {
|
||||
@ -63,7 +62,6 @@ impl Default for GraphicsSettings {
|
||||
window_size: [1280, 720],
|
||||
fullscreen: FullScreenSettings::default(),
|
||||
lod_detail: 250,
|
||||
bloom_enabled: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user