|
|
|
|
@ -5,23 +5,31 @@ use crate::{
|
|
|
|
|
};
|
|
|
|
|
use bevy::{
|
|
|
|
|
core_pipeline::{
|
|
|
|
|
experimental::taa::{TemporalAntiAliasPlugin, TemporalAntiAliasSettings},
|
|
|
|
|
prepass::MotionVectorPrepass,
|
|
|
|
|
tonemapping::{DebandDither, Tonemapping},
|
|
|
|
|
Skybox,
|
|
|
|
|
},
|
|
|
|
|
input::mouse::{MouseButtonInput, MouseMotion, MouseScrollUnit, MouseWheel},
|
|
|
|
|
pbr::{
|
|
|
|
|
ScreenSpaceAmbientOcclusionBundle, ScreenSpaceAmbientOcclusionQualityLevel,
|
|
|
|
|
ScreenSpaceAmbientOcclusionSettings,
|
|
|
|
|
},
|
|
|
|
|
render::{
|
|
|
|
|
render_resource::{TextureViewDescriptor, TextureViewDimension},
|
|
|
|
|
view::ColorGrading,
|
|
|
|
|
},
|
|
|
|
|
window::PrimaryWindow,
|
|
|
|
|
};
|
|
|
|
|
use serde::{de, Deserialize, Deserializer};
|
|
|
|
|
use serde::Deserialize;
|
|
|
|
|
|
|
|
|
|
pub(crate) struct Display3dPlugin;
|
|
|
|
|
|
|
|
|
|
impl Plugin for Display3dPlugin {
|
|
|
|
|
fn build(&self, app: &mut App) {
|
|
|
|
|
app.add_systems(OnEnter(GameState::Loading), load_assets)
|
|
|
|
|
app.add_plugins(TemporalAntiAliasPlugin)
|
|
|
|
|
.add_systems(OnEnter(GameState::Loading), load_assets)
|
|
|
|
|
.insert_resource(Msaa::Off)
|
|
|
|
|
.add_systems(
|
|
|
|
|
OnExit(GameState::Loading),
|
|
|
|
|
(initialize, fix_skybox.before(initialize)),
|
|
|
|
|
@ -72,6 +80,7 @@ impl Plugin for Display3dPlugin {
|
|
|
|
|
opening_animation
|
|
|
|
|
.run_if(run_once())
|
|
|
|
|
.run_if(in_state(GameState::Play)),
|
|
|
|
|
update_tweaks,
|
|
|
|
|
),
|
|
|
|
|
)
|
|
|
|
|
.add_systems(OnExit(DisplayState::Display3d), deactivate::<Display3d>)
|
|
|
|
|
@ -213,11 +222,10 @@ fn hydrate_camera(
|
|
|
|
|
specular_map: assets.skybox.clone(),
|
|
|
|
|
},
|
|
|
|
|
UiCameraConfig { show_ui: true },
|
|
|
|
|
FogSettings {
|
|
|
|
|
color: Color::WHITE,
|
|
|
|
|
falloff: FogFalloff::from_visibility_colors(100.0, Color::NONE, Color::NONE),
|
|
|
|
|
..default()
|
|
|
|
|
},
|
|
|
|
|
FogSettings { ..default() },
|
|
|
|
|
ScreenSpaceAmbientOcclusionBundle { ..default() },
|
|
|
|
|
TemporalAntiAliasSettings { ..default() },
|
|
|
|
|
MotionVectorPrepass { ..default() },
|
|
|
|
|
Name::new("3D Camera"),
|
|
|
|
|
));
|
|
|
|
|
|
|
|
|
|
@ -237,28 +245,50 @@ fn hydrate_camera(
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Update display3d tweaks in the game
|
|
|
|
|
/// Triggered on entering 3d state and when the tweakfile is updated.
|
|
|
|
|
fn update_tweaks(
|
|
|
|
|
mut events: EventReader<AssetEvent<Tweakfile>>,
|
|
|
|
|
mut camera_settings: Query<
|
|
|
|
|
(&mut FogSettings, &mut ColorGrading, &mut Tonemapping),
|
|
|
|
|
(
|
|
|
|
|
Entity,
|
|
|
|
|
&mut FogSettings,
|
|
|
|
|
&mut ColorGrading,
|
|
|
|
|
&mut Tonemapping,
|
|
|
|
|
),
|
|
|
|
|
With<Display3d>,
|
|
|
|
|
>,
|
|
|
|
|
tweaks: Res<Assets<Tweakfile>>,
|
|
|
|
|
mut commands: Commands,
|
|
|
|
|
server: Res<AssetServer>,
|
|
|
|
|
) {
|
|
|
|
|
events.iter().for_each(|event| match event {
|
|
|
|
|
AssetEvent::Created { handle } | AssetEvent::Modified { handle } => {
|
|
|
|
|
if let Some(tweak) = tweaks.get(handle) {
|
|
|
|
|
camera_settings.iter_mut().for_each(
|
|
|
|
|
|(mut fog, mut color_grading, mut tonemapping)| {
|
|
|
|
|
*fog = tweak.display3d.fog.clone().into();
|
|
|
|
|
*color_grading = tweak.display3d.color.grading.clone().into();
|
|
|
|
|
*tonemapping = tweak.display3d.color.tonemapping.clone().into();
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
AssetEvent::Removed { .. } => debug!("Tweakfile removal not handled"),
|
|
|
|
|
});
|
|
|
|
|
let handle: Handle<Tweakfile> = server.load("martian.tweak.toml");
|
|
|
|
|
if let Some(tweak) = tweaks.get(&handle) {
|
|
|
|
|
camera_settings.iter_mut().for_each(
|
|
|
|
|
|(entity, mut fog, mut color_grading, mut tonemapping)| {
|
|
|
|
|
*fog = tweak.display3d.fog.clone().into();
|
|
|
|
|
*color_grading = tweak.display3d.color.grading.clone().into();
|
|
|
|
|
*tonemapping = tweak.display3d.color.tonemapping.clone().into();
|
|
|
|
|
|
|
|
|
|
let quality_level: Option<ScreenSpaceAmbientOcclusionQualityLevel> =
|
|
|
|
|
tweak.display3d.ssao.quality_level.clone().into();
|
|
|
|
|
match quality_level {
|
|
|
|
|
Some(quality_level) => {
|
|
|
|
|
commands
|
|
|
|
|
.entity(entity)
|
|
|
|
|
.insert(ScreenSpaceAmbientOcclusionSettings { quality_level });
|
|
|
|
|
commands.insert_resource(Msaa::Off);
|
|
|
|
|
}
|
|
|
|
|
None => {
|
|
|
|
|
commands
|
|
|
|
|
.entity(entity)
|
|
|
|
|
.remove::<ScreenSpaceAmbientOcclusionSettings>();
|
|
|
|
|
let msaa: Msaa = tweak.display3d.msaa.clone().into();
|
|
|
|
|
commands.insert_resource(msaa);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn fix_skybox(mut images: ResMut<Assets<Image>>, assets: Res<AssetsMap>) {
|
|
|
|
|
@ -758,7 +788,9 @@ fn switch_sides(
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub(crate) mod tweaks {
|
|
|
|
|
use bevy::core_pipeline::tonemapping::Tonemapping;
|
|
|
|
|
use bevy::{
|
|
|
|
|
core_pipeline::tonemapping::Tonemapping, pbr::ScreenSpaceAmbientOcclusionQualityLevel,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
|
|
@ -768,6 +800,10 @@ pub(crate) mod tweaks {
|
|
|
|
|
pub fog: FogTweaks,
|
|
|
|
|
#[serde(default)]
|
|
|
|
|
pub color: ColorTweaks,
|
|
|
|
|
#[serde(default)]
|
|
|
|
|
pub ssao: SsaoTweaks,
|
|
|
|
|
#[serde(default)]
|
|
|
|
|
pub msaa: MsaaTweaks,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Deserialize, Default)]
|
|
|
|
|
@ -903,4 +939,67 @@ pub(crate) mod tweaks {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, Default, Deserialize)]
|
|
|
|
|
pub(crate) struct SsaoTweaks {
|
|
|
|
|
#[serde(default)]
|
|
|
|
|
pub quality_level: SsaoQualityLevelTweak,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Deserialize, Default, Clone)]
|
|
|
|
|
pub(crate) enum SsaoQualityLevelTweak {
|
|
|
|
|
#[default]
|
|
|
|
|
Off,
|
|
|
|
|
Low,
|
|
|
|
|
Medium,
|
|
|
|
|
High,
|
|
|
|
|
Ultra,
|
|
|
|
|
Custom {
|
|
|
|
|
slice_count: u32,
|
|
|
|
|
samples_per_slice_side: u32,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Into<std::option::Option<ScreenSpaceAmbientOcclusionQualityLevel>> for SsaoQualityLevelTweak {
|
|
|
|
|
fn into(self) -> Option<ScreenSpaceAmbientOcclusionQualityLevel> {
|
|
|
|
|
match self {
|
|
|
|
|
SsaoQualityLevelTweak::Off => None,
|
|
|
|
|
SsaoQualityLevelTweak::Low => Some(ScreenSpaceAmbientOcclusionQualityLevel::Low),
|
|
|
|
|
SsaoQualityLevelTweak::Medium => {
|
|
|
|
|
Some(ScreenSpaceAmbientOcclusionQualityLevel::Medium)
|
|
|
|
|
}
|
|
|
|
|
SsaoQualityLevelTweak::High => Some(ScreenSpaceAmbientOcclusionQualityLevel::High),
|
|
|
|
|
SsaoQualityLevelTweak::Ultra => {
|
|
|
|
|
Some(ScreenSpaceAmbientOcclusionQualityLevel::Ultra)
|
|
|
|
|
}
|
|
|
|
|
SsaoQualityLevelTweak::Custom {
|
|
|
|
|
slice_count,
|
|
|
|
|
samples_per_slice_side,
|
|
|
|
|
} => Some(ScreenSpaceAmbientOcclusionQualityLevel::Custom {
|
|
|
|
|
slice_count,
|
|
|
|
|
samples_per_slice_side,
|
|
|
|
|
}),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Deserialize, Default, Clone)]
|
|
|
|
|
pub(crate) enum MsaaTweaks {
|
|
|
|
|
#[default]
|
|
|
|
|
Off,
|
|
|
|
|
Sample2,
|
|
|
|
|
Sample4,
|
|
|
|
|
Sample8,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Into<Msaa> for MsaaTweaks {
|
|
|
|
|
fn into(self) -> Msaa {
|
|
|
|
|
match self {
|
|
|
|
|
MsaaTweaks::Off => Msaa::Off,
|
|
|
|
|
MsaaTweaks::Sample2 => Msaa::Sample2,
|
|
|
|
|
MsaaTweaks::Sample4 => Msaa::Sample4,
|
|
|
|
|
MsaaTweaks::Sample8 => Msaa::Sample4,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|