diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c8f39b70d..163566091b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added screen-space reflection and refraction shaders - Added reflection quality setting - UI: Added a poise indicator to the player's status bars +- FxUpscale AA mode for higher quality graphics at reduced internal resolutions +- Graphics presets ### Changed - Use fluent for translations diff --git a/assets/voxygen/i18n/en/hud/settings.ftl b/assets/voxygen/i18n/en/hud/settings.ftl index e60754abd1..c64b5693c3 100644 --- a/assets/voxygen/i18n/en/hud/settings.ftl +++ b/assets/voxygen/i18n/en/hud/settings.ftl @@ -111,6 +111,11 @@ hud-settings-rain_occlusion-resolution = Rain Occlusion Resolution hud-settings-lod_detail = LoD Detail hud-settings-save_window_size = Save window size hud-settings-reset_graphics = Reset to Defaults +hud-settings-minimal_graphics = Minimal +hud-settings-low_graphics = Low +hud-settings-medium_graphics = Medium +hud-settings-high_graphics = High +hud-settings-ultra_graphics = Ultra hud-settings-bloom = Bloom hud-settings-point_glow = Point Glow hud-settings-master_volume = Master Volume diff --git a/assets/voxygen/shaders/include/light.glsl b/assets/voxygen/shaders/include/light.glsl index 213ad56551..999cf2cdb5 100644 --- a/assets/voxygen/shaders/include/light.glsl +++ b/assets/voxygen/shaders/include/light.glsl @@ -110,7 +110,7 @@ float shadow_at(vec3 wpos, vec3 wnorm) { diff.z = -sign(diff.z) * diff.z * 0.1; } - float shade = max(pow(diff.x * diff.x + diff.y * diff.y + diff.z * diff.z, 0.25) / pow(radius * radius * 0.5, 0.25), 0.5); + float shade = max(pow(diff.x * diff.x + diff.y * diff.y + diff.z * diff.z, 0.35) / pow(radius * radius * 0.5, 0.5), 0.5); // float shade = max(pow(dot(diff, diff) / (radius * radius * 0.5), 0.25), 0.5); // float shade = dot(diff, diff) / (radius * radius * 0.5); diff --git a/voxygen/src/hud/mod.rs b/voxygen/src/hud/mod.rs index 3424fbdefb..3c594a3857 100644 --- a/voxygen/src/hud/mod.rs +++ b/voxygen/src/hud/mod.rs @@ -193,6 +193,7 @@ const DEFAULT_NPC: Color = Color::Rgba(1.0, 1.0, 1.0, 1.0); // UI Color-Theme const UI_MAIN: Color = Color::Rgba(0.61, 0.70, 0.70, 1.0); // Greenish Blue +const UI_SUBTLE: Color = Color::Rgba(0.2, 0.24, 0.24, 1.0); // Dark Greenish Blue //const UI_MAIN: Color = Color::Rgba(0.1, 0.1, 0.1, 0.97); // Dark const UI_HIGHLIGHT_0: Color = Color::Rgba(0.79, 1.09, 1.09, 1.0); // Pull-Down menu BG color diff --git a/voxygen/src/hud/settings_window/video.rs b/voxygen/src/hud/settings_window/video.rs index c548c3cea3..a53b73b597 100644 --- a/voxygen/src/hud/settings_window/video.rs +++ b/voxygen/src/hud/settings_window/video.rs @@ -3,14 +3,14 @@ use super::{RESET_BUTTONS_HEIGHT, RESET_BUTTONS_WIDTH}; use crate::{ hud::{ img_ids::Imgs, CRITICAL_HP_COLOR, HP_COLOR, LOW_HP_COLOR, MENU_BG, STAMINA_COLOR, - TEXT_COLOR, + TEXT_COLOR, UI_HIGHLIGHT_0, UI_MAIN, UI_SUBTLE, }, render::{ AaMode, BloomConfig, BloomFactor, BloomMode, CloudMode, FluidMode, LightingMode, PresentMode, ReflectionMode, RenderMode, ShadowMapMode, ShadowMode, UpscaleMode, }, session::settings_change::Graphics as GraphicsChange, - settings::Fps, + settings::{Fps, GraphicsSettings}, ui::{fonts::Fonts, ImageSlider, ToggleButton}, window::{FullScreenSettings, FullscreenMode}, GlobalState, @@ -25,7 +25,7 @@ use core::convert::TryFrom; use i18n::Localization; use itertools::Itertools; -use std::iter::once; +use std::{iter::once, rc::Rc}; use winit::monitor::VideoMode; widget_ids! { @@ -34,6 +34,11 @@ widget_ids! { window_r, window_scrollbar, reset_graphics_button, + minimal_graphics_button, + low_graphics_button, + medium_graphics_button, + high_graphics_button, + ultra_graphics_button, fps_counter, pipeline_recreation_text, terrain_vd_slider, @@ -284,9 +289,81 @@ impl<'a> Widget for Video<'a> { .set(state.ids.pipeline_recreation_text, ui); } + // Reset the graphics settings to the default settings + if Button::image(self.imgs.button) + .w_h(RESET_BUTTONS_WIDTH, RESET_BUTTONS_HEIGHT) + .hover_image(self.imgs.button_hover) + .press_image(self.imgs.button_press) + .top_left_with_margins_on(state.ids.window, 10.0, 10.0) + .label( + &self + .localized_strings + .get_msg("hud-settings-reset_graphics"), + ) + .label_font_size(self.fonts.cyri.scale(14)) + .label_color(TEXT_COLOR) + .label_font_id(self.fonts.cyri.conrod_id) + .label_y(Relative::Scalar(2.0)) + .set(state.ids.reset_graphics_button, ui) + .was_clicked() + { + events.push(GraphicsChange::ResetGraphicsSettings); + } + + // Graphics presets buttons + let preset_buttons: [(_, _, fn(_) -> _); 5] = [ + ( + "hud-settings-minimal_graphics", + state.ids.minimal_graphics_button, + GraphicsSettings::into_minimal, + ), + ( + "hud-settings-low_graphics", + state.ids.low_graphics_button, + GraphicsSettings::into_low, + ), + ( + "hud-settings-medium_graphics", + state.ids.medium_graphics_button, + GraphicsSettings::into_medium, + ), + ( + "hud-settings-high_graphics", + state.ids.high_graphics_button, + GraphicsSettings::into_high, + ), + ( + "hud-settings-ultra_graphics", + state.ids.ultra_graphics_button, + GraphicsSettings::into_ultra, + ), + ]; + + let mut lhs = state.ids.reset_graphics_button; + + for (msg, id, change_fn) in preset_buttons { + if Button::new() + .label(&self.localized_strings.get_msg(msg)) + .w_h(80.0, 34.0) + .color(UI_SUBTLE) + .hover_color(UI_MAIN) + .press_color(UI_HIGHLIGHT_0) + .right_from(lhs, 12.0) + .label_font_size(self.fonts.cyri.scale(14)) + .label_color(TEXT_COLOR) + .label_font_id(self.fonts.cyri.conrod_id) + .label_y(Relative::Scalar(2.0)) + .set(id, ui) + .was_clicked() + { + events.push(GraphicsChange::ChangeGraphicsSettings(Rc::new(change_fn))); + } + lhs = id; + } + // View Distance Text::new(&self.localized_strings.get_msg("hud-settings-view_distance")) - .top_left_with_margins_on(state.ids.window, 10.0, 10.0) + .down_from(state.ids.reset_graphics_button, 10.0) .font_size(self.fonts.cyri.scale(14)) .font_id(self.fonts.cyri.conrod_id) .color(TEXT_COLOR) @@ -1671,28 +1748,6 @@ impl<'a> Widget for Video<'a> { )); } - // Reset the graphics settings to the default settings - if Button::image(self.imgs.button) - .w_h(RESET_BUTTONS_WIDTH, RESET_BUTTONS_HEIGHT) - .hover_image(self.imgs.button_hover) - .press_image(self.imgs.button_press) - .down_from(state.ids.fullscreen_mode_list, 12.0) - .right_from(state.ids.save_window_size_button, 12.0) - .label( - &self - .localized_strings - .get_msg("hud-settings-reset_graphics"), - ) - .label_font_size(self.fonts.cyri.scale(14)) - .label_color(TEXT_COLOR) - .label_font_id(self.fonts.cyri.conrod_id) - .label_y(Relative::Scalar(2.0)) - .set(state.ids.reset_graphics_button, ui) - .was_clicked() - { - events.push(GraphicsChange::ResetGraphicsSettings); - } - events } } diff --git a/voxygen/src/render/mod.rs b/voxygen/src/render/mod.rs index 7ad00203eb..6ed5d44831 100644 --- a/voxygen/src/render/mod.rs +++ b/voxygen/src/render/mod.rs @@ -199,7 +199,7 @@ pub enum ReflectionMode { } impl Default for ReflectionMode { - fn default() -> Self { ReflectionMode::Medium } + fn default() -> Self { ReflectionMode::High } } /// Lighting modes diff --git a/voxygen/src/session/settings_change.rs b/voxygen/src/session/settings_change.rs index 7c3afcde43..356580215f 100644 --- a/voxygen/src/session/settings_change.rs +++ b/voxygen/src/session/settings_change.rs @@ -15,6 +15,7 @@ use crate::{ GlobalState, }; use i18n::{LanguageMetadata, LocalizationHandle}; +use std::rc::Rc; #[derive(Clone)] pub enum Audio { @@ -98,6 +99,7 @@ pub enum Graphics { AdjustWindowSize([u16; 2]), ResetGraphicsSettings, + ChangeGraphicsSettings(Rc GraphicsSettings>), } #[derive(Clone)] pub enum Interface { @@ -410,6 +412,8 @@ impl SettingsChange { } }, SettingsChange::Graphics(graphics_change) => { + let mut change_all = false; + match graphics_change { Graphics::AdjustTerrainViewDistance(terrain_vd) => { adjust_terrain_view_distance(terrain_vd, settings, session_state) @@ -486,28 +490,41 @@ impl SettingsChange { }, Graphics::ResetGraphicsSettings => { settings.graphics = GraphicsSettings::default(); - let graphics = &settings.graphics; - // View distance - client_set_view_distance(settings, session_state); - // FOV - session_state.scene.camera_mut().set_fov_deg(graphics.fov); - session_state - .scene - .camera_mut() - .compute_dependents(&session_state.client.borrow().state().terrain()); - // LoD - session_state.scene.lod.set_detail(graphics.lod_detail); - // Render mode - global_state - .window - .renderer_mut() - .set_render_mode(graphics.render_mode.clone()) - .unwrap(); - // Fullscreen mode - global_state.window.set_fullscreen_mode(graphics.fullscreen); - // Window size - global_state.window.set_size(graphics.window_size.into()); + change_all = true; }, + Graphics::ChangeGraphicsSettings(f) => { + settings.graphics = f(settings.graphics.clone()); + change_all = true; + }, + } + + if change_all { + let graphics = &settings.graphics; + // View distance + client_set_view_distance(settings, session_state); + // FOV + session_state.scene.camera_mut().set_fov_deg(graphics.fov); + session_state + .scene + .camera_mut() + .compute_dependents(&session_state.client.borrow().state().terrain()); + // LoD + session_state.scene.lod.set_detail(graphics.lod_detail); + // LoD distance + session_state + .client + .borrow_mut() + .set_lod_distance(graphics.lod_distance); + // Render mode + global_state + .window + .renderer_mut() + .set_render_mode(graphics.render_mode.clone()) + .unwrap(); + // Fullscreen mode + global_state.window.set_fullscreen_mode(graphics.fullscreen); + // Window size + global_state.window.set_size(graphics.window_size.into()); } }, SettingsChange::Interface(interface_change) => { diff --git a/voxygen/src/settings/graphics.rs b/voxygen/src/settings/graphics.rs index c8919a5a76..904b8815e2 100644 --- a/voxygen/src/settings/graphics.rs +++ b/voxygen/src/settings/graphics.rs @@ -71,3 +71,144 @@ impl Default for GraphicsSettings { } } } + +impl GraphicsSettings { + pub fn into_minimal(self) -> Self { + use crate::render::*; + Self { + terrain_view_distance: 4, + entity_view_distance: 4, + lod_distance: 0, + sprite_render_distance: 80, + figure_lod_render_distance: 100, + lod_detail: 80, + render_mode: RenderMode { + aa: AaMode::FxUpscale, + cloud: CloudMode::Minimal, + reflection: ReflectionMode::Low, + fluid: FluidMode::Low, + lighting: LightingMode::Lambertian, + shadow: ShadowMode::None, + rain_occlusion: ShadowMapMode { resolution: 0.25 }, + bloom: BloomMode::Off, + point_glow: 0.0, + upscale_mode: UpscaleMode { factor: 0.35 }, + ..self.render_mode + }, + ..self + } + } + + pub fn into_low(self) -> Self { + use crate::render::*; + Self { + terrain_view_distance: 7, + entity_view_distance: 7, + lod_distance: 75, + sprite_render_distance: 125, + figure_lod_render_distance: 200, + lod_detail: 200, + render_mode: RenderMode { + aa: AaMode::FxUpscale, + cloud: CloudMode::Low, + reflection: ReflectionMode::Medium, + fluid: FluidMode::Low, + lighting: LightingMode::Lambertian, + shadow: ShadowMode::Cheap, + rain_occlusion: ShadowMapMode { resolution: 0.25 }, + bloom: BloomMode::Off, + point_glow: 0.35, + upscale_mode: UpscaleMode { factor: 0.65 }, + ..self.render_mode + }, + ..self + } + } + + pub fn into_medium(self) -> Self { + use crate::render::*; + Self { + terrain_view_distance: 10, + entity_view_distance: 10, + lod_distance: 150, + sprite_render_distance: 250, + figure_lod_render_distance: 350, + lod_detail: 300, + render_mode: RenderMode { + aa: AaMode::Fxaa, + cloud: CloudMode::Medium, + reflection: ReflectionMode::High, + fluid: FluidMode::Medium, + lighting: LightingMode::BlinnPhong, + shadow: ShadowMode::Map(ShadowMapMode { resolution: 0.75 }), + rain_occlusion: ShadowMapMode { resolution: 0.25 }, + bloom: BloomMode::On(BloomConfig { + factor: BloomFactor::Medium, + uniform_blur: false, + }), + point_glow: 0.35, + upscale_mode: UpscaleMode { factor: 0.85 }, + ..self.render_mode + }, + ..self + } + } + + pub fn into_high(self) -> Self { + use crate::render::*; + Self { + terrain_view_distance: 16, + entity_view_distance: 16, + lod_distance: 200, + sprite_render_distance: 350, + figure_lod_render_distance: 450, + lod_detail: 375, + render_mode: RenderMode { + aa: AaMode::Fxaa, + cloud: CloudMode::Medium, + reflection: ReflectionMode::High, + fluid: FluidMode::Medium, + lighting: LightingMode::Ashikhmin, + shadow: ShadowMode::Map(ShadowMapMode { resolution: 1.0 }), + rain_occlusion: ShadowMapMode { resolution: 0.5 }, + bloom: BloomMode::On(BloomConfig { + factor: BloomFactor::Medium, + uniform_blur: true, + }), + point_glow: 0.35, + upscale_mode: UpscaleMode { factor: 1.0 }, + ..self.render_mode + }, + ..self + } + } + + pub fn into_ultra(self) -> Self { + use crate::render::*; + Self { + terrain_view_distance: 16, + entity_view_distance: 16, + lod_distance: 450, + sprite_render_distance: 800, + figure_lod_render_distance: 600, + lod_detail: 500, + render_mode: RenderMode { + aa: AaMode::Fxaa, + cloud: CloudMode::High, + reflection: ReflectionMode::High, + fluid: FluidMode::High, + lighting: LightingMode::Ashikhmin, + shadow: ShadowMode::Map(ShadowMapMode { resolution: 1.75 }), + rain_occlusion: ShadowMapMode { resolution: 0.5 }, + bloom: BloomMode::On(BloomConfig { + factor: BloomFactor::Medium, + uniform_blur: true, + }), + point_glow: 0.35, + upscale_mode: UpscaleMode { factor: 1.25 }, + ..self.render_mode + }, + ..self + } + } +}