mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Upscaling support
This commit is contained in:
parent
7ffb3b91fa
commit
171ef1d7b9
@ -35,6 +35,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Saving of the last selected character in the character selection screen
|
||||
- Autoselecting the newly created character
|
||||
- Deselecting when the selected character is deleted
|
||||
- Upscaling support
|
||||
|
||||
### Changed
|
||||
|
||||
|
@ -337,6 +337,7 @@ magically infused items?"#,
|
||||
"hud.settings.gamma": "Gamma",
|
||||
"hud.settings.ambiance": "Ambiance Brightness",
|
||||
"hud.settings.antialiasing_mode": "AntiAliasing Mode",
|
||||
"hud.settings.upscale_factor": "Upscale Factor",
|
||||
"hud.settings.cloud_rendering_mode": "Cloud Rendering Mode",
|
||||
"hud.settings.fluid_rendering_mode": "Fluid Rendering Mode",
|
||||
"hud.settings.fluid_rendering_mode.cheap": "Cheap",
|
||||
|
74
assets/voxygen/shaders/clouds-frag.glsl
Normal file
74
assets/voxygen/shaders/clouds-frag.glsl
Normal file
@ -0,0 +1,74 @@
|
||||
#version 330 core
|
||||
|
||||
#include <constants.glsl>
|
||||
|
||||
#define LIGHTING_TYPE (LIGHTING_TYPE_TRANSMISSION | LIGHTING_TYPE_REFLECTION)
|
||||
|
||||
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_SPECULAR
|
||||
|
||||
#if (FLUID_MODE == FLUID_MODE_CHEAP)
|
||||
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
|
||||
#elif (FLUID_MODE == FLUID_MODE_SHINY)
|
||||
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
|
||||
#endif
|
||||
|
||||
#define LIGHTING_DISTRIBUTION_SCHEME LIGHTING_DISTRIBUTION_SCHEME_MICROFACET
|
||||
|
||||
#define LIGHTING_DISTRIBUTION LIGHTING_DISTRIBUTION_BECKMANN
|
||||
|
||||
#include <globals.glsl>
|
||||
// Note: The sampler uniform is declared here because it differs for MSAA
|
||||
#include <anti-aliasing.glsl>
|
||||
#include <srgb.glsl>
|
||||
#include <cloud.glsl>
|
||||
|
||||
uniform sampler2D src_depth;
|
||||
|
||||
in vec2 f_pos;
|
||||
|
||||
layout (std140)
|
||||
uniform u_locals {
|
||||
mat4 proj_mat_inv;
|
||||
mat4 view_mat_inv;
|
||||
};
|
||||
|
||||
out vec4 tgt_color;
|
||||
|
||||
float depth_at(vec2 uv) {
|
||||
float buf_depth = texture(src_depth, uv).x;
|
||||
vec4 clip_space = vec4(uv * 2.0 - 1.0, buf_depth, 1.0);
|
||||
vec4 view_space = proj_mat_inv * clip_space;
|
||||
view_space /= view_space.w;
|
||||
return -view_space.z;
|
||||
}
|
||||
|
||||
vec3 wpos_at(vec2 uv) {
|
||||
float buf_depth = texture(src_depth, uv).x * 2.0 - 1.0;
|
||||
mat4 inv = view_mat_inv * proj_mat_inv;//inverse(all_mat);
|
||||
vec4 clip_space = vec4(uv * 2.0 - 1.0, buf_depth, 1.0);
|
||||
vec4 view_space = inv * clip_space;
|
||||
view_space /= view_space.w;
|
||||
if (buf_depth == 1.0) {
|
||||
vec3 direction = normalize(view_space.xyz);
|
||||
return direction.xyz * 100000.0 + cam_pos.xyz;
|
||||
} else {
|
||||
return view_space.xyz;
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 uv = (f_pos + 1.0) * 0.5;
|
||||
|
||||
vec4 color = texture(src_color, uv);
|
||||
|
||||
// Apply clouds to `aa_color`
|
||||
#if (CLOUD_MODE != CLOUD_MODE_NONE)
|
||||
vec3 wpos = wpos_at(uv);
|
||||
float dist = distance(wpos, cam_pos.xyz);
|
||||
vec3 dir = (wpos - cam_pos.xyz) / dist;
|
||||
|
||||
color.rgb = get_cloud_color(color.rgb, dir, cam_pos.xyz, time_of_day.x, dist, 1.0);
|
||||
#endif
|
||||
|
||||
tgt_color = vec4(color.rgb, 1);
|
||||
}
|
29
assets/voxygen/shaders/clouds-vert.glsl
Normal file
29
assets/voxygen/shaders/clouds-vert.glsl
Normal file
@ -0,0 +1,29 @@
|
||||
#version 330 core
|
||||
|
||||
#include <constants.glsl>
|
||||
|
||||
#define LIGHTING_TYPE (LIGHTING_TYPE_TRANSMISSION | LIGHTING_TYPE_REFLECTION)
|
||||
|
||||
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_SPECULAR
|
||||
|
||||
#if (FLUID_MODE == FLUID_MODE_CHEAP)
|
||||
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
|
||||
#elif (FLUID_MODE == FLUID_MODE_SHINY)
|
||||
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
|
||||
#endif
|
||||
|
||||
#define LIGHTING_DISTRIBUTION_SCHEME LIGHTING_DISTRIBUTION_SCHEME_MICROFACET
|
||||
|
||||
#define LIGHTING_DISTRIBUTION LIGHTING_DISTRIBUTION_BECKMANN
|
||||
|
||||
#include <globals.glsl>
|
||||
|
||||
in vec2 v_pos;
|
||||
|
||||
out vec2 f_pos;
|
||||
|
||||
void main() {
|
||||
f_pos = v_pos;
|
||||
|
||||
gl_Position = vec4(v_pos, -1.0, 1.0);
|
||||
}
|
@ -22,7 +22,7 @@
|
||||
#include <srgb.glsl>
|
||||
#include <cloud.glsl>
|
||||
|
||||
uniform sampler2D src_depth;
|
||||
//uniform sampler2D src_depth;
|
||||
|
||||
in vec2 f_pos;
|
||||
|
||||
@ -145,6 +145,7 @@ vec3 _illuminate(float max_light, vec3 view_dir, /*vec3 max_light, */vec3 emitte
|
||||
// return /*srgb_to_linear*/(/*0.5*//*0.125 * */vec3(pow(color.x, gamma), pow(color.y, gamma), pow(color.z, gamma)));
|
||||
}
|
||||
|
||||
/*
|
||||
float depth_at(vec2 uv) {
|
||||
float buf_depth = texture(src_depth, uv).x;
|
||||
vec4 clip_space = vec4(uv * 2.0 - 1.0, buf_depth, 1.0);
|
||||
@ -166,6 +167,7 @@ vec3 wpos_at(vec2 uv) {
|
||||
return view_space.xyz;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void main() {
|
||||
vec2 uv = (f_pos + 1.0) * 0.5;
|
||||
@ -202,6 +204,7 @@ void main() {
|
||||
|
||||
vec4 aa_color = aa_apply(src_color, uv * screen_res.xy, screen_res.xy);
|
||||
|
||||
/*
|
||||
// Apply clouds to `aa_color`
|
||||
#if (CLOUD_MODE != CLOUD_MODE_NONE)
|
||||
vec3 wpos = wpos_at(uv);
|
||||
@ -210,6 +213,7 @@ void main() {
|
||||
|
||||
aa_color.rgb = get_cloud_color(aa_color.rgb, dir, cam_pos.xyz, time_of_day.x, dist, 1.0);
|
||||
#endif
|
||||
*/
|
||||
|
||||
// aa_color.rgb = (wpos + focus_off.xyz) / vec3(32768, 32768, /*view_distance.w*/2048);
|
||||
// aa_color.rgb = mod((wpos + focus_off.xyz), vec3(32768, 32768, view_distance.w)) / vec3(32768, 32768, view_distance.w);// / vec3(32768, 32768, view_distance.w);
|
||||
|
@ -6,7 +6,10 @@ use super::{
|
||||
use crate::{
|
||||
hud::BuffPosition,
|
||||
i18n::{list_localizations, LanguageMetadata, Localization},
|
||||
render::{AaMode, CloudMode, FluidMode, LightingMode, RenderMode, ShadowMapMode, ShadowMode},
|
||||
render::{
|
||||
AaMode, CloudMode, FluidMode, LightingMode, RenderMode, ShadowMapMode, ShadowMode,
|
||||
UpscaleMode,
|
||||
},
|
||||
ui::{fonts::Fonts, ImageSlider, ScaleMode, ToggleButton},
|
||||
window::{FullScreenSettings, FullscreenMode, GameInput},
|
||||
GlobalState,
|
||||
@ -126,6 +129,8 @@ widget_ids! {
|
||||
ambiance_value,
|
||||
aa_mode_text,
|
||||
aa_mode_list,
|
||||
upscale_factor_text,
|
||||
upscale_factor_list,
|
||||
cloud_mode_text,
|
||||
cloud_mode_list,
|
||||
fluid_mode_text,
|
||||
@ -2060,13 +2065,55 @@ impl<'a> Widget for SettingsWindow<'a> {
|
||||
})));
|
||||
}
|
||||
|
||||
// Upscaling factor
|
||||
Text::new(&self.localized_strings.get("hud.settings.upscale_factor"))
|
||||
.down_from(state.ids.aa_mode_list, 8.0)
|
||||
.font_size(self.fonts.cyri.scale(14))
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.color(TEXT_COLOR)
|
||||
.set(state.ids.upscale_factor_text, ui);
|
||||
|
||||
let upscale_factors = [
|
||||
// Upscaling
|
||||
0.15, 0.2, 0.25, 0.35, 0.5, 0.65, 0.75, 0.85, 1.0,
|
||||
// Downscaling (equivalent to SSAA)
|
||||
1.25, 1.5, 1.75, 2.0,
|
||||
];
|
||||
|
||||
// Get which upscale factor is currently active
|
||||
let selected = upscale_factors
|
||||
.iter()
|
||||
.position(|factor| (*factor - render_mode.upscale_mode.factor).abs() < 0.001);
|
||||
|
||||
if let Some(clicked) = DropDownList::new(
|
||||
&upscale_factors
|
||||
.iter()
|
||||
.map(|factor| format!("{n:.*}", 2, n = factor))
|
||||
.collect::<Vec<String>>(),
|
||||
selected,
|
||||
)
|
||||
.w_h(400.0, 22.0)
|
||||
.color(MENU_BG)
|
||||
.label_color(TEXT_COLOR)
|
||||
.label_font_id(self.fonts.cyri.conrod_id)
|
||||
.down_from(state.ids.upscale_factor_text, 8.0)
|
||||
.set(state.ids.upscale_factor_list, ui)
|
||||
{
|
||||
events.push(Event::ChangeRenderMode(Box::new(RenderMode {
|
||||
upscale_mode: UpscaleMode {
|
||||
factor: upscale_factors[clicked],
|
||||
},
|
||||
..render_mode.clone()
|
||||
})));
|
||||
}
|
||||
|
||||
// CloudMode
|
||||
Text::new(
|
||||
&self
|
||||
.localized_strings
|
||||
.get("hud.settings.cloud_rendering_mode"),
|
||||
)
|
||||
.down_from(state.ids.aa_mode_list, 8.0)
|
||||
.down_from(state.ids.upscale_factor_list, 8.0)
|
||||
.font_size(self.fonts.cyri.scale(14))
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.color(TEXT_COLOR)
|
||||
|
@ -16,6 +16,7 @@ pub use self::{
|
||||
mesh::{Mesh, Quad, Tri},
|
||||
model::{DynamicModel, Model},
|
||||
pipelines::{
|
||||
clouds::{create_mesh as create_clouds_mesh, CloudsPipeline, Locals as CloudsLocals},
|
||||
figure::{
|
||||
BoneData as FigureBoneData, BoneMeshes, FigureModel, FigurePipeline,
|
||||
Locals as FigureLocals,
|
||||
@ -257,6 +258,17 @@ impl ShadowMode {
|
||||
pub fn is_map(&self) -> bool { matches!(self, Self::Map(_)) }
|
||||
}
|
||||
|
||||
/// Upscale mode settings.
|
||||
#[derive(PartialEq, Clone, Copy, Debug, Serialize, Deserialize)]
|
||||
pub struct UpscaleMode {
|
||||
// Determines non-UI graphics upscaling. 0.25 to 2.0.
|
||||
pub factor: f32,
|
||||
}
|
||||
|
||||
impl Default for UpscaleMode {
|
||||
fn default() -> Self { Self { factor: 1.0 } }
|
||||
}
|
||||
|
||||
/// Render modes
|
||||
#[derive(PartialEq, Clone, Debug, Default, Serialize, Deserialize)]
|
||||
#[serde(default)]
|
||||
@ -266,4 +278,5 @@ pub struct RenderMode {
|
||||
pub fluid: FluidMode,
|
||||
pub lighting: LightingMode,
|
||||
pub shadow: ShadowMode,
|
||||
pub upscale_mode: UpscaleMode,
|
||||
}
|
||||
|
77
voxygen/src/render/pipelines/clouds.rs
Normal file
77
voxygen/src/render/pipelines/clouds.rs
Normal file
@ -0,0 +1,77 @@
|
||||
use super::{
|
||||
super::{Mesh, Pipeline, TgtColorFmt, TgtDepthStencilFmt, Tri},
|
||||
Globals,
|
||||
};
|
||||
use gfx::{
|
||||
self, gfx_constant_struct_meta, gfx_defines, gfx_impl_struct_meta, gfx_pipeline,
|
||||
gfx_pipeline_inner, gfx_vertex_struct_meta,
|
||||
};
|
||||
use vek::*;
|
||||
|
||||
gfx_defines! {
|
||||
vertex Vertex {
|
||||
pos: [f32; 2] = "v_pos",
|
||||
}
|
||||
|
||||
constant Locals {
|
||||
proj_mat_inv: [[f32; 4]; 4] = "proj_mat_inv",
|
||||
view_mat_inv: [[f32; 4]; 4] = "view_mat_inv",
|
||||
}
|
||||
|
||||
pipeline pipe {
|
||||
vbuf: gfx::VertexBuffer<Vertex> = (),
|
||||
|
||||
locals: gfx::ConstantBuffer<Locals> = "u_locals",
|
||||
globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
||||
|
||||
map: gfx::TextureSampler<[f32; 4]> = "t_map",
|
||||
alt: gfx::TextureSampler<[f32; 2]> = "t_alt",
|
||||
horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon",
|
||||
|
||||
color_sampler: gfx::TextureSampler<<TgtColorFmt as gfx::format::Formatted>::View> = "src_color",
|
||||
depth_sampler: gfx::TextureSampler<<TgtDepthStencilFmt as gfx::format::Formatted>::View> = "src_depth",
|
||||
|
||||
noise: gfx::TextureSampler<f32> = "t_noise",
|
||||
|
||||
tgt_color: gfx::RenderTarget<TgtColorFmt> = "tgt_color",
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Locals {
|
||||
fn default() -> Self { Self::new(Mat4::identity(), Mat4::identity()) }
|
||||
}
|
||||
|
||||
impl Locals {
|
||||
pub fn new(proj_mat_inv: Mat4<f32>, view_mat_inv: Mat4<f32>) -> Self {
|
||||
Self {
|
||||
proj_mat_inv: proj_mat_inv.into_col_arrays(),
|
||||
view_mat_inv: view_mat_inv.into_col_arrays(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CloudsPipeline;
|
||||
|
||||
impl Pipeline for CloudsPipeline {
|
||||
type Vertex = Vertex;
|
||||
}
|
||||
|
||||
pub fn create_mesh() -> Mesh<CloudsPipeline> {
|
||||
let mut mesh = Mesh::new();
|
||||
|
||||
#[rustfmt::skip]
|
||||
mesh.push_tri(Tri::new(
|
||||
Vertex { pos: [ 1.0, -1.0] },
|
||||
Vertex { pos: [-1.0, 1.0] },
|
||||
Vertex { pos: [-1.0, -1.0] },
|
||||
));
|
||||
|
||||
#[rustfmt::skip]
|
||||
mesh.push_tri(Tri::new(
|
||||
Vertex { pos: [1.0, -1.0] },
|
||||
Vertex { pos: [1.0, 1.0] },
|
||||
Vertex { pos: [-1.0, 1.0] },
|
||||
));
|
||||
|
||||
mesh
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
pub mod clouds;
|
||||
pub mod figure;
|
||||
pub mod fluid;
|
||||
pub mod lod_terrain;
|
||||
|
@ -5,8 +5,8 @@ use super::{
|
||||
mesh::Mesh,
|
||||
model::{DynamicModel, Model},
|
||||
pipelines::{
|
||||
figure, fluid, lod_terrain, particle, postprocess, shadow, skybox, sprite, terrain, ui,
|
||||
GlobalModel, Globals,
|
||||
clouds, figure, fluid, lod_terrain, particle, postprocess, shadow, skybox, sprite, terrain,
|
||||
ui, GlobalModel, Globals,
|
||||
},
|
||||
texture::Texture,
|
||||
AaMode, CloudMode, FilterMethod, FluidMode, LightingMode, Pipeline, RenderError, RenderMode,
|
||||
@ -148,9 +148,11 @@ pub struct Renderer {
|
||||
|
||||
tgt_color_view: TgtColorView,
|
||||
tgt_depth_stencil_view: TgtDepthStencilView,
|
||||
tgt_color_view_pp: TgtColorView,
|
||||
|
||||
tgt_color_res: TgtColorRes,
|
||||
tgt_depth_res: TgtDepthRes,
|
||||
tgt_color_res_pp: TgtColorRes,
|
||||
|
||||
sampler: Sampler<gfx_backend::Resources>,
|
||||
|
||||
@ -164,6 +166,7 @@ pub struct Renderer {
|
||||
particle_pipeline: GfxPipeline<particle::pipe::Init<'static>>,
|
||||
ui_pipeline: GfxPipeline<ui::pipe::Init<'static>>,
|
||||
lod_terrain_pipeline: GfxPipeline<lod_terrain::pipe::Init<'static>>,
|
||||
clouds_pipeline: GfxPipeline<clouds::pipe::Init<'static>>,
|
||||
postprocess_pipeline: GfxPipeline<postprocess::pipe::Init<'static>>,
|
||||
player_shadow_pipeline: GfxPipeline<figure::pipe::Init<'static>>,
|
||||
|
||||
@ -213,6 +216,7 @@ impl Renderer {
|
||||
particle_pipeline,
|
||||
ui_pipeline,
|
||||
lod_terrain_pipeline,
|
||||
clouds_pipeline,
|
||||
postprocess_pipeline,
|
||||
player_shadow_pipeline,
|
||||
point_shadow_pipeline,
|
||||
@ -225,8 +229,14 @@ impl Renderer {
|
||||
&mut shader_reload_indicator,
|
||||
)?;
|
||||
|
||||
let (tgt_color_view, tgt_depth_stencil_view, tgt_color_res, tgt_depth_res) =
|
||||
Self::create_rt_views(&mut factory, (dims.0, dims.1), &mode)?;
|
||||
let (
|
||||
tgt_color_view,
|
||||
tgt_depth_stencil_view,
|
||||
tgt_color_view_pp,
|
||||
tgt_color_res,
|
||||
tgt_depth_res,
|
||||
tgt_color_res_pp,
|
||||
) = Self::create_rt_views(&mut factory, (dims.0, dims.1), &mode)?;
|
||||
|
||||
let shadow_map = if let (
|
||||
Some(point_pipeline),
|
||||
@ -266,7 +276,10 @@ impl Renderer {
|
||||
None
|
||||
};
|
||||
|
||||
let sampler = factory.create_sampler_linear();
|
||||
let sampler = factory.create_sampler(gfx::texture::SamplerInfo::new(
|
||||
gfx::texture::FilterMethod::Bilinear,
|
||||
gfx::texture::WrapMode::Clamp,
|
||||
));
|
||||
|
||||
let noise_tex = Texture::new(
|
||||
&mut factory,
|
||||
@ -286,9 +299,11 @@ impl Renderer {
|
||||
|
||||
tgt_color_view,
|
||||
tgt_depth_stencil_view,
|
||||
tgt_color_view_pp,
|
||||
|
||||
tgt_color_res,
|
||||
tgt_depth_res,
|
||||
tgt_color_res_pp,
|
||||
|
||||
sampler,
|
||||
|
||||
@ -302,6 +317,7 @@ impl Renderer {
|
||||
particle_pipeline,
|
||||
ui_pipeline,
|
||||
lod_terrain_pipeline,
|
||||
clouds_pipeline,
|
||||
postprocess_pipeline,
|
||||
player_shadow_pipeline,
|
||||
|
||||
@ -363,12 +379,20 @@ impl Renderer {
|
||||
|
||||
// Avoid panics when creating texture with w,h of 0,0.
|
||||
if dims.0 != 0 && dims.1 != 0 {
|
||||
let (tgt_color_view, tgt_depth_stencil_view, tgt_color_res, tgt_depth_res) =
|
||||
Self::create_rt_views(&mut self.factory, (dims.0, dims.1), &self.mode)?;
|
||||
let (
|
||||
tgt_color_view,
|
||||
tgt_depth_stencil_view,
|
||||
tgt_color_view_pp,
|
||||
tgt_color_res,
|
||||
tgt_depth_res,
|
||||
tgt_color_res_pp,
|
||||
) = Self::create_rt_views(&mut self.factory, (dims.0, dims.1), &self.mode)?;
|
||||
self.tgt_color_res = tgt_color_res;
|
||||
self.tgt_depth_res = tgt_depth_res;
|
||||
self.tgt_color_res_pp = tgt_color_res_pp;
|
||||
self.tgt_color_view = tgt_color_view;
|
||||
self.tgt_depth_stencil_view = tgt_depth_stencil_view;
|
||||
self.tgt_color_view_pp = tgt_color_view_pp;
|
||||
if let (Some(shadow_map), ShadowMode::Map(mode)) =
|
||||
(self.shadow_map.as_mut(), self.mode.shadow)
|
||||
{
|
||||
@ -403,42 +427,66 @@ impl Renderer {
|
||||
factory: &mut gfx_device_gl::Factory,
|
||||
size: (u16, u16),
|
||||
mode: &RenderMode,
|
||||
) -> Result<(TgtColorView, TgtDepthStencilView, TgtColorRes, TgtDepthRes), RenderError> {
|
||||
) -> Result<
|
||||
(
|
||||
TgtColorView,
|
||||
TgtDepthStencilView,
|
||||
TgtColorView,
|
||||
TgtColorRes,
|
||||
TgtDepthRes,
|
||||
TgtColorRes,
|
||||
),
|
||||
RenderError,
|
||||
> {
|
||||
let upscaled = Vec2::from(size)
|
||||
.map(|e: u16| (e as f32 * mode.upscale_mode.factor) as u16)
|
||||
.into_tuple();
|
||||
let kind = match mode.aa {
|
||||
AaMode::None | AaMode::Fxaa => {
|
||||
gfx::texture::Kind::D2(size.0, size.1, gfx::texture::AaMode::Single)
|
||||
gfx::texture::Kind::D2(upscaled.0, upscaled.1, gfx::texture::AaMode::Single)
|
||||
},
|
||||
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
||||
AaMode::SsaaX4 => {
|
||||
// TODO: Figure out how to do upscaling correctly with SSAA
|
||||
gfx::texture::Kind::D2(size.0 * 2, size.1 * 2, gfx::texture::AaMode::Single)
|
||||
},
|
||||
AaMode::MsaaX4 => {
|
||||
gfx::texture::Kind::D2(size.0, size.1, gfx::texture::AaMode::Multi(4))
|
||||
gfx::texture::Kind::D2(upscaled.0, upscaled.1, gfx::texture::AaMode::Multi(4))
|
||||
},
|
||||
AaMode::MsaaX8 => {
|
||||
gfx::texture::Kind::D2(size.0, size.1, gfx::texture::AaMode::Multi(8))
|
||||
gfx::texture::Kind::D2(upscaled.0, upscaled.1, gfx::texture::AaMode::Multi(8))
|
||||
},
|
||||
AaMode::MsaaX16 => {
|
||||
gfx::texture::Kind::D2(size.0, size.1, gfx::texture::AaMode::Multi(16))
|
||||
gfx::texture::Kind::D2(upscaled.0, upscaled.1, gfx::texture::AaMode::Multi(16))
|
||||
},
|
||||
};
|
||||
let levels = 1;
|
||||
|
||||
let color_cty = <<TgtColorFmt as gfx::format::Formatted>::Channel as gfx::format::ChannelTyped
|
||||
>::get_channel_type();
|
||||
let tgt_color_tex = factory.create_texture(
|
||||
let mut color_tex = || {
|
||||
factory.create_texture(
|
||||
kind,
|
||||
levels,
|
||||
gfx::memory::Bind::SHADER_RESOURCE | gfx::memory::Bind::RENDER_TARGET,
|
||||
gfx::memory::Usage::Data,
|
||||
Some(color_cty),
|
||||
)?;
|
||||
let tgt_color_res = factory.view_texture_as_shader_resource::<TgtColorFmt>(
|
||||
&tgt_color_tex,
|
||||
)
|
||||
};
|
||||
let tgt_color_tex = color_tex()?;
|
||||
let tgt_color_tex_pp = color_tex()?;
|
||||
let mut color_res = |tex| {
|
||||
factory.view_texture_as_shader_resource::<TgtColorFmt>(
|
||||
tex,
|
||||
(0, levels - 1),
|
||||
gfx::format::Swizzle::new(),
|
||||
)?;
|
||||
)
|
||||
};
|
||||
let tgt_color_res = color_res(&tgt_color_tex)?;
|
||||
let tgt_color_res_pp = color_res(&tgt_color_tex_pp)?;
|
||||
let tgt_color_view = factory.view_texture_as_render_target(&tgt_color_tex, 0, None)?;
|
||||
let tgt_color_view_pp =
|
||||
factory.view_texture_as_render_target(&tgt_color_tex_pp, 0, None)?;
|
||||
|
||||
let depth_stencil_cty = <<TgtDepthStencilFmt as gfx::format::Formatted>::Channel as gfx::format::ChannelTyped>::get_channel_type();
|
||||
let tgt_depth_stencil_tex = factory.create_texture(
|
||||
@ -459,8 +507,10 @@ impl Renderer {
|
||||
Ok((
|
||||
tgt_color_view,
|
||||
tgt_depth_stencil_view,
|
||||
tgt_color_view_pp,
|
||||
tgt_color_res,
|
||||
tgt_depth_res,
|
||||
tgt_color_res_pp,
|
||||
))
|
||||
}
|
||||
|
||||
@ -763,6 +813,7 @@ impl Renderer {
|
||||
particle_pipeline,
|
||||
ui_pipeline,
|
||||
lod_terrain_pipeline,
|
||||
clouds_pipeline,
|
||||
postprocess_pipeline,
|
||||
player_shadow_pipeline,
|
||||
point_shadow_pipeline,
|
||||
@ -777,6 +828,7 @@ impl Renderer {
|
||||
self.particle_pipeline = particle_pipeline;
|
||||
self.ui_pipeline = ui_pipeline;
|
||||
self.lod_terrain_pipeline = lod_terrain_pipeline;
|
||||
self.clouds_pipeline = clouds_pipeline;
|
||||
self.postprocess_pipeline = postprocess_pipeline;
|
||||
self.player_shadow_pipeline = player_shadow_pipeline;
|
||||
if let (
|
||||
@ -1645,6 +1697,37 @@ impl Renderer {
|
||||
);
|
||||
}
|
||||
|
||||
pub fn render_clouds(
|
||||
&mut self,
|
||||
model: &Model<clouds::CloudsPipeline>,
|
||||
globals: &Consts<Globals>,
|
||||
locals: &Consts<clouds::Locals>,
|
||||
lod: &lod_terrain::LodData,
|
||||
) {
|
||||
self.encoder.draw(
|
||||
&gfx::Slice {
|
||||
start: model.vertex_range().start,
|
||||
end: model.vertex_range().end,
|
||||
base_vertex: 0,
|
||||
instances: None,
|
||||
buffer: gfx::IndexBuffer::Auto,
|
||||
},
|
||||
&self.clouds_pipeline.pso,
|
||||
&clouds::pipe::Data {
|
||||
vbuf: model.vbuf.clone(),
|
||||
locals: locals.buf.clone(),
|
||||
globals: globals.buf.clone(),
|
||||
map: (lod.map.srv.clone(), lod.map.sampler.clone()),
|
||||
alt: (lod.alt.srv.clone(), lod.alt.sampler.clone()),
|
||||
horizon: (lod.horizon.srv.clone(), lod.horizon.sampler.clone()),
|
||||
color_sampler: (self.tgt_color_res.clone(), self.sampler.clone()),
|
||||
depth_sampler: (self.tgt_depth_res.clone(), self.sampler.clone()),
|
||||
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||
tgt_color: self.tgt_color_view_pp.clone(),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
pub fn render_post_process(
|
||||
&mut self,
|
||||
model: &Model<postprocess::PostProcessPipeline>,
|
||||
@ -1668,7 +1751,7 @@ impl Renderer {
|
||||
map: (lod.map.srv.clone(), lod.map.sampler.clone()),
|
||||
alt: (lod.alt.srv.clone(), lod.alt.sampler.clone()),
|
||||
horizon: (lod.horizon.srv.clone(), lod.horizon.sampler.clone()),
|
||||
color_sampler: (self.tgt_color_res.clone(), self.sampler.clone()),
|
||||
color_sampler: (self.tgt_color_res_pp.clone(), self.sampler.clone()),
|
||||
depth_sampler: (self.tgt_depth_res.clone(), self.sampler.clone()),
|
||||
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||
tgt_color: self.win_color_view.clone(),
|
||||
@ -1698,6 +1781,7 @@ fn create_pipelines(
|
||||
GfxPipeline<particle::pipe::Init<'static>>,
|
||||
GfxPipeline<ui::pipe::Init<'static>>,
|
||||
GfxPipeline<lod_terrain::pipe::Init<'static>>,
|
||||
GfxPipeline<clouds::pipe::Init<'static>>,
|
||||
GfxPipeline<postprocess::pipe::Init<'static>>,
|
||||
GfxPipeline<figure::pipe::Init<'static>>,
|
||||
Option<GfxPipeline<shadow::pipe::Init<'static>>>,
|
||||
@ -1908,6 +1992,16 @@ fn create_pipelines(
|
||||
gfx::state::CullFace::Back,
|
||||
)?;
|
||||
|
||||
// Construct a pipeline for rendering our clouds (a kind of post-processing)
|
||||
let clouds_pipeline = create_pipeline(
|
||||
factory,
|
||||
clouds::pipe::new(),
|
||||
&Glsl::load_watched("voxygen.shaders.clouds-vert", shader_reload_indicator).unwrap(),
|
||||
&Glsl::load_watched("voxygen.shaders.clouds-frag", shader_reload_indicator).unwrap(),
|
||||
&include_ctx,
|
||||
gfx::state::CullFace::Back,
|
||||
)?;
|
||||
|
||||
// Construct a pipeline for rendering our post-processing
|
||||
let postprocess_pipeline = create_pipeline(
|
||||
factory,
|
||||
@ -2019,6 +2113,7 @@ fn create_pipelines(
|
||||
particle_pipeline,
|
||||
ui_pipeline,
|
||||
lod_terrain_pipeline,
|
||||
clouds_pipeline,
|
||||
postprocess_pipeline,
|
||||
player_shadow_pipeline,
|
||||
point_shadow_pipeline,
|
||||
|
@ -16,9 +16,9 @@ pub use self::{
|
||||
use crate::{
|
||||
audio::{music::MusicMgr, sfx::SfxMgr, AudioFrontend},
|
||||
render::{
|
||||
create_pp_mesh, create_skybox_mesh, Consts, GlobalModel, Globals, Light, LodData, Model,
|
||||
PostProcessLocals, PostProcessPipeline, Renderer, Shadow, ShadowLocals, SkyboxLocals,
|
||||
SkyboxPipeline,
|
||||
create_clouds_mesh, create_pp_mesh, create_skybox_mesh, CloudsLocals, CloudsPipeline,
|
||||
Consts, GlobalModel, Globals, Light, LodData, Model, PostProcessLocals,
|
||||
PostProcessPipeline, Renderer, Shadow, ShadowLocals, SkyboxLocals, SkyboxPipeline,
|
||||
},
|
||||
settings::Settings,
|
||||
window::{AnalogGameInput, Event},
|
||||
@ -71,6 +71,11 @@ struct Skybox {
|
||||
locals: Consts<SkyboxLocals>,
|
||||
}
|
||||
|
||||
struct Clouds {
|
||||
model: Model<CloudsPipeline>,
|
||||
locals: Consts<CloudsLocals>,
|
||||
}
|
||||
|
||||
struct PostProcess {
|
||||
model: Model<PostProcessPipeline>,
|
||||
locals: Consts<PostProcessLocals>,
|
||||
@ -83,6 +88,7 @@ pub struct Scene {
|
||||
event_lights: Vec<EventLight>,
|
||||
|
||||
skybox: Skybox,
|
||||
clouds: Clouds,
|
||||
postprocess: PostProcess,
|
||||
terrain: Terrain<TerrainChunk>,
|
||||
pub lod: Lod,
|
||||
@ -283,6 +289,10 @@ impl Scene {
|
||||
model: renderer.create_model(&create_skybox_mesh()).unwrap(),
|
||||
locals: renderer.create_consts(&[SkyboxLocals::default()]).unwrap(),
|
||||
},
|
||||
clouds: Clouds {
|
||||
model: renderer.create_model(&create_clouds_mesh()).unwrap(),
|
||||
locals: renderer.create_consts(&[CloudsLocals::default()]).unwrap(),
|
||||
},
|
||||
postprocess: PostProcess {
|
||||
model: renderer.create_model(&create_pp_mesh()).unwrap(),
|
||||
locals: renderer
|
||||
@ -664,6 +674,12 @@ impl Scene {
|
||||
scene_data.sprite_render_distance as f32 - 20.0,
|
||||
)])
|
||||
.expect("Failed to update global constants");
|
||||
renderer
|
||||
.update_consts(&mut self.clouds.locals, &[CloudsLocals::new(
|
||||
proj_mat_inv,
|
||||
view_mat_inv,
|
||||
)])
|
||||
.expect("Failed to update cloud locals");
|
||||
renderer
|
||||
.update_consts(&mut self.postprocess.locals, &[PostProcessLocals::new(
|
||||
proj_mat_inv,
|
||||
@ -1075,6 +1091,14 @@ impl Scene {
|
||||
// Render particle effects.
|
||||
self.particle_mgr.render(renderer, scene_data, global, lod);
|
||||
|
||||
// Render clouds (a post-processing effect)
|
||||
renderer.render_clouds(
|
||||
&self.clouds.model,
|
||||
&global.globals,
|
||||
&self.clouds.locals,
|
||||
self.lod.get_data(),
|
||||
);
|
||||
|
||||
renderer.render_post_process(
|
||||
&self.postprocess.model,
|
||||
&global.globals,
|
||||
|
@ -1,9 +1,10 @@
|
||||
use crate::{
|
||||
mesh::{greedy::GreedyMesh, Meshable},
|
||||
render::{
|
||||
create_pp_mesh, create_skybox_mesh, BoneMeshes, Consts, FigureModel, FigurePipeline,
|
||||
GlobalModel, Globals, Light, Mesh, Model, PostProcessLocals, PostProcessPipeline, Renderer,
|
||||
Shadow, ShadowLocals, SkyboxLocals, SkyboxPipeline, TerrainPipeline,
|
||||
create_clouds_mesh, create_pp_mesh, create_skybox_mesh, BoneMeshes, CloudsLocals,
|
||||
CloudsPipeline, Consts, FigureModel, FigurePipeline, GlobalModel, Globals, Light, Mesh,
|
||||
Model, PostProcessLocals, PostProcessPipeline, Renderer, Shadow, ShadowLocals,
|
||||
SkyboxLocals, SkyboxPipeline, TerrainPipeline,
|
||||
},
|
||||
scene::{
|
||||
camera::{self, Camera, CameraMode},
|
||||
@ -61,11 +62,17 @@ struct PostProcess {
|
||||
locals: Consts<PostProcessLocals>,
|
||||
}
|
||||
|
||||
struct Clouds {
|
||||
model: Model<CloudsPipeline>,
|
||||
locals: Consts<CloudsLocals>,
|
||||
}
|
||||
|
||||
pub struct Scene {
|
||||
data: GlobalModel,
|
||||
camera: Camera,
|
||||
|
||||
skybox: Skybox,
|
||||
clouds: Clouds,
|
||||
postprocess: PostProcess,
|
||||
lod: LodData,
|
||||
map_bounds: Vec2<f32>,
|
||||
@ -123,6 +130,10 @@ impl Scene {
|
||||
model: renderer.create_model(&create_skybox_mesh()).unwrap(),
|
||||
locals: renderer.create_consts(&[SkyboxLocals::default()]).unwrap(),
|
||||
},
|
||||
clouds: Clouds {
|
||||
model: renderer.create_model(&create_clouds_mesh()).unwrap(),
|
||||
locals: renderer.create_consts(&[CloudsLocals::default()]).unwrap(),
|
||||
},
|
||||
postprocess: PostProcess {
|
||||
model: renderer.create_model(&create_pp_mesh()).unwrap(),
|
||||
locals: renderer
|
||||
@ -377,6 +388,13 @@ impl Scene {
|
||||
);
|
||||
}
|
||||
|
||||
renderer.render_clouds(
|
||||
&self.clouds.model,
|
||||
&self.data.globals,
|
||||
&self.clouds.locals,
|
||||
&self.lod,
|
||||
);
|
||||
|
||||
renderer.render_post_process(
|
||||
&self.postprocess.model,
|
||||
&self.data.globals,
|
||||
|
Loading…
Reference in New Issue
Block a user