From fa6825f13bb340873e2318b8e4518d65d4e866de Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Thu, 15 Aug 2019 02:35:56 +0100 Subject: [PATCH] Better fluid meshing, disabled fluid backface culling and depth buffer writing --- assets/voxygen/shaders/fluid-frag.glsl | 3 +- assets/voxygen/shaders/fluid-vert.glsl | 2 +- assets/voxygen/shaders/include/random.glsl | 13 +++++ assets/voxygen/shaders/include/sky.glsl | 8 +-- voxygen/src/mesh/segment.rs | 1 + voxygen/src/mesh/terrain.rs | 4 +- voxygen/src/mesh/vol.rs | 64 ++++++++++++++++++---- voxygen/src/render/pipelines/fluid.rs | 4 +- voxygen/src/render/renderer.rs | 13 ++++- world/src/column/mod.rs | 4 +- 10 files changed, 94 insertions(+), 22 deletions(-) create mode 100644 assets/voxygen/shaders/include/random.glsl diff --git a/assets/voxygen/shaders/fluid-frag.glsl b/assets/voxygen/shaders/fluid-frag.glsl index 5583c72df2..b354cb0e58 100644 --- a/assets/voxygen/shaders/fluid-frag.glsl +++ b/assets/voxygen/shaders/fluid-frag.glsl @@ -1,6 +1,7 @@ #version 330 core #include +#include in vec3 f_pos; flat in vec3 f_norm; @@ -25,7 +26,7 @@ void main() { float fog_level = fog(f_pos.xy, focus_pos.xy); vec3 fog_color = get_sky_color(normalize(f_pos - cam_pos.xyz), time_of_day.x); - vec3 warped_norm = normalize(f_norm + (sin(f_pos.xyz + tick.x + 13.7) + sin(f_pos.zxy + tick.x + 19.3)) * 0.3); + vec3 warped_norm = normalize(f_norm + smooth_rand(floor(f_pos), tick.x) * 0.5); vec3 reflect_color = get_sky_color(reflect(normalize(f_pos - cam_pos.xyz), warped_norm), time_of_day.x); vec3 color = mix(surf_color + reflect_color * 0.5, fog_color, fog_level); diff --git a/assets/voxygen/shaders/fluid-vert.glsl b/assets/voxygen/shaders/fluid-vert.glsl index 71b14ea98e..43da1243c8 100644 --- a/assets/voxygen/shaders/fluid-vert.glsl +++ b/assets/voxygen/shaders/fluid-vert.glsl @@ -43,7 +43,7 @@ void main() { f_light = float(v_col_light & 0xFFu) / 255.0; - f_opac = 0.1; + f_opac = 0.3; gl_Position = proj_mat * diff --git a/assets/voxygen/shaders/include/random.glsl b/assets/voxygen/shaders/include/random.glsl new file mode 100644 index 0000000000..6c606a9677 --- /dev/null +++ b/assets/voxygen/shaders/include/random.glsl @@ -0,0 +1,13 @@ +vec3 rand_perm_3(vec3 pos) { + return sin(pos * vec3(1473.7 * pos.z + 472.3, 8891.1 * pos.x + 723.1, 3813.3 * pos.y + 982.5)); +} + +vec4 rand_perm_4(vec4 pos) { + return sin(473.3 * pos * vec4(317.3 * pos.w + 917.7, 1473.7 * pos.z + 472.3, 8891.1 * pos.x + 723.1, 3813.3 * pos.y + 982.5) / pos.yxwz); +} + +vec3 smooth_rand(vec3 pos, float lerp_axis) { + vec3 r0 = rand_perm_3(vec3(pos.x, pos.y, pos.z) + floor(lerp_axis)); + vec3 r1 = rand_perm_3(vec3(pos.x, pos.y, pos.z) + floor(lerp_axis + 1.0)); + return r0 + (r1 - r0) * fract(lerp_axis); +} diff --git a/assets/voxygen/shaders/include/sky.glsl b/assets/voxygen/shaders/include/sky.glsl index ef47282f16..25c1fba993 100644 --- a/assets/voxygen/shaders/include/sky.glsl +++ b/assets/voxygen/shaders/include/sky.glsl @@ -1,3 +1,5 @@ +#include + const float PI = 3.141592; const vec3 SKY_DAY_TOP = vec3(0.1, 0.2, 0.9); @@ -54,10 +56,6 @@ vec3 get_sun_diffuse(vec3 norm, float time_of_day) { return diffuse_light; } -vec3 rand_offs(vec3 pos) { - return sin(pos * vec3(1473.7 * pos.z + 472.3, 8891.1 * pos.x + 723.1, 3813.3 * pos.y + 982.5)); -} - // This has been extracted into a function to allow quick exit when detecting a star. float is_star_at(vec3 dir) { float star_scale = 30.0; @@ -69,7 +67,7 @@ float is_star_at(vec3 dir) { vec3 pos = (floor(dir * star_scale) + vec3(i, j, k) - vec3(0.5)) / star_scale; // Noisy offsets - pos += (3.0 / star_scale) * rand_offs(pos); + pos += (3.0 / star_scale) * rand_perm_3(pos); // Find distance to fragment float dist = length(normalize(pos) - dir); diff --git a/voxygen/src/mesh/segment.rs b/voxygen/src/mesh/segment.rs index 1aac195d16..e0b77ac31e 100644 --- a/voxygen/src/mesh/segment.rs +++ b/voxygen/src/mesh/segment.rs @@ -43,6 +43,7 @@ impl Meshable for Segment { true, &[[[1.0; 3]; 3]; 3], |vox| vox.is_empty(), + |vox| !vox.is_empty(), ); } } diff --git a/voxygen/src/mesh/terrain.rs b/voxygen/src/mesh/terrain.rs index 588a7130f0..f8c30ea446 100644 --- a/voxygen/src/mesh/terrain.rs +++ b/voxygen/src/mesh/terrain.rs @@ -18,7 +18,7 @@ fn block_shadow_density(kind: BlockKind) -> Option { BlockKind::Air => None, BlockKind::Normal => Some(0.85), BlockKind::Dense => Some(3.0), - BlockKind::Water => Some(0.01), + BlockKind::Water => Some(0.8), } } @@ -63,6 +63,7 @@ impl + ReadVol + Debug, S: VolSize + Clone> Meshable for false, &neighbour_light, |vox| !vox.is_opaque(), + |vox| vox.is_opaque(), ); } else if let Some(col) = block .filter(|vox| vox.is_fluid()) @@ -82,6 +83,7 @@ impl + ReadVol + Debug, S: VolSize + Clone> Meshable for false, &neighbour_light, |vox| vox.is_air(), + |vox| vox.is_opaque(), ); } diff --git a/voxygen/src/mesh/vol.rs b/voxygen/src/mesh/vol.rs index 1d8a6d4d9e..cf683be658 100644 --- a/voxygen/src/mesh/vol.rs +++ b/voxygen/src/mesh/vol.rs @@ -1,6 +1,6 @@ use vek::*; -use common::vol::{ReadVol, Vox}; +use common::vol::ReadVol; use crate::render::{ mesh::{Mesh, Quad}, @@ -16,15 +16,16 @@ fn get_ao_quad( shift: Vec3, dirs: &[Vec3], darknesses: &[[[f32; 3]; 3]; 3], + is_opaque: impl Fn(&V::Vox) -> bool, ) -> Vec4<(f32, f32)> { dirs.windows(2) .map(|offs| { let (s1, s2) = ( vol.get(pos + shift + offs[0]) - .map(|v| !v.is_empty()) + .map(&is_opaque) .unwrap_or(false), vol.get(pos + shift + offs[1]) - .map(|v| !v.is_empty()) + .map(&is_opaque) .unwrap_or(false), ); @@ -42,7 +43,7 @@ fn get_ao_quad( } else { let corner = vol .get(pos + shift + offs[0] + offs[1]) - .map(|v| !v.is_empty()) + .map(&is_opaque) .unwrap_or(false); // Map both 1 and 2 neighbors to 0.5 occlusion. if s1 || s2 || corner { @@ -98,6 +99,7 @@ pub fn push_vox_verts( error_makes_face: bool, darknesses: &[[[f32; 3]; 3]; 3], should_add: impl Fn(&V::Vox) -> bool, + is_opaque: impl Fn(&V::Vox) -> bool, ) { let (x, y, z) = (Vec3::unit_x(), Vec3::unit_y(), Vec3::unit_z()); @@ -113,7 +115,14 @@ pub fn push_vox_verts( Vec3::unit_y(), -Vec3::unit_x(), col, - get_ao_quad(vol, pos, -Vec3::unit_x(), &[-z, -y, z, y, -z], darknesses), + get_ao_quad( + vol, + pos, + -Vec3::unit_x(), + &[-z, -y, z, y, -z], + darknesses, + &is_opaque, + ), &vcons, )); } @@ -129,7 +138,14 @@ pub fn push_vox_verts( Vec3::unit_z(), Vec3::unit_x(), col, - get_ao_quad(vol, pos, Vec3::unit_x(), &[-y, -z, y, z, -y], darknesses), + get_ao_quad( + vol, + pos, + Vec3::unit_x(), + &[-y, -z, y, z, -y], + darknesses, + &is_opaque, + ), &vcons, )); } @@ -145,7 +161,14 @@ pub fn push_vox_verts( Vec3::unit_z(), -Vec3::unit_y(), col, - get_ao_quad(vol, pos, -Vec3::unit_y(), &[-x, -z, x, z, -x], darknesses), + get_ao_quad( + vol, + pos, + -Vec3::unit_y(), + &[-x, -z, x, z, -x], + darknesses, + &is_opaque, + ), &vcons, )); } @@ -161,7 +184,14 @@ pub fn push_vox_verts( Vec3::unit_x(), Vec3::unit_y(), col, - get_ao_quad(vol, pos, Vec3::unit_y(), &[-z, -x, z, x, -z], darknesses), + get_ao_quad( + vol, + pos, + Vec3::unit_y(), + &[-z, -x, z, x, -z], + darknesses, + &is_opaque, + ), &vcons, )); } @@ -177,7 +207,14 @@ pub fn push_vox_verts( Vec3::unit_x(), -Vec3::unit_z(), col, - get_ao_quad(vol, pos, -Vec3::unit_z(), &[-y, -x, y, x, -y], darknesses), + get_ao_quad( + vol, + pos, + -Vec3::unit_z(), + &[-y, -x, y, x, -y], + darknesses, + &is_opaque, + ), &vcons, )); } @@ -193,7 +230,14 @@ pub fn push_vox_verts( Vec3::unit_y(), Vec3::unit_z(), col, - get_ao_quad(vol, pos, Vec3::unit_z(), &[-x, -y, x, y, -x], darknesses), + get_ao_quad( + vol, + pos, + Vec3::unit_z(), + &[-x, -y, x, y, -x], + darknesses, + &is_opaque, + ), &vcons, )); } diff --git a/voxygen/src/render/pipelines/fluid.rs b/voxygen/src/render/pipelines/fluid.rs index c88dc6f454..e4c040c644 100644 --- a/voxygen/src/render/pipelines/fluid.rs +++ b/voxygen/src/render/pipelines/fluid.rs @@ -29,12 +29,12 @@ gfx_defines! { lights: gfx::ConstantBuffer = "u_lights", tgt_color: gfx::BlendTarget = ("tgt_color", ColorMask::all(), gfx::preset::blend::ALPHA), - tgt_depth: gfx::DepthTarget = gfx::preset::depth::LESS_EQUAL_WRITE, + tgt_depth: gfx::DepthTarget = gfx::preset::depth::LESS_EQUAL_TEST, } } impl Vertex { - pub fn new(pos: Vec3, norm: Vec3, col: Rgb, light: f32, opac: f32) -> Self { + pub fn new(pos: Vec3, norm: Vec3, col: Rgb, light: f32, _opac: f32) -> Self { let (norm_axis, norm_dir) = norm .as_slice() .into_iter() diff --git a/voxygen/src/render/renderer.rs b/voxygen/src/render/renderer.rs index 91e76032f5..a445dea895 100644 --- a/voxygen/src/render/renderer.rs +++ b/voxygen/src/render/renderer.rs @@ -506,12 +506,16 @@ fn create_pipelines( let srgb = assets::load_watched::("voxygen.shaders.include.srgb", shader_reload_indicator) .unwrap(); + let random = + assets::load_watched::("voxygen.shaders.include.random", shader_reload_indicator) + .unwrap(); let mut include_ctx = IncludeContext::new(); include_ctx.include("globals.glsl", &globals); include_ctx.include("sky.glsl", &sky); include_ctx.include("light.glsl", &light); include_ctx.include("srgb.glsl", &srgb); + include_ctx.include("random.glsl", &random); // Construct a pipeline for rendering skyboxes let skybox_pipeline = create_pipeline( @@ -522,6 +526,7 @@ fn create_pipelines( &assets::load_watched::("voxygen.shaders.skybox-frag", shader_reload_indicator) .unwrap(), &include_ctx, + gfx::state::CullFace::Back, )?; // Construct a pipeline for rendering figures @@ -533,6 +538,7 @@ fn create_pipelines( &assets::load_watched::("voxygen.shaders.figure-frag", shader_reload_indicator) .unwrap(), &include_ctx, + gfx::state::CullFace::Back, )?; // Construct a pipeline for rendering terrain @@ -544,6 +550,7 @@ fn create_pipelines( &assets::load_watched::("voxygen.shaders.terrain-frag", shader_reload_indicator) .unwrap(), &include_ctx, + gfx::state::CullFace::Back, )?; // Construct a pipeline for rendering fluids @@ -555,6 +562,7 @@ fn create_pipelines( &assets::load_watched::("voxygen.shaders.fluid-frag", shader_reload_indicator) .unwrap(), &include_ctx, + gfx::state::CullFace::Nothing, )?; // Construct a pipeline for rendering UI elements @@ -566,6 +574,7 @@ fn create_pipelines( &assets::load_watched::("voxygen.shaders.ui-frag", shader_reload_indicator) .unwrap(), &include_ctx, + gfx::state::CullFace::Back, )?; // Construct a pipeline for rendering our post-processing @@ -583,6 +592,7 @@ fn create_pipelines( ) .unwrap(), &include_ctx, + gfx::state::CullFace::Back, )?; Ok(( @@ -602,6 +612,7 @@ fn create_pipeline<'a, P: gfx::pso::PipelineInit>( vs: &str, fs: &str, ctx: &IncludeContext, + cull_face: gfx::state::CullFace, ) -> Result, RenderError> { let vs = ctx.expand(vs).map_err(RenderError::IncludeError)?; let fs = ctx.expand(fs).map_err(RenderError::IncludeError)?; @@ -617,7 +628,7 @@ fn create_pipeline<'a, P: gfx::pso::PipelineInit>( gfx::Primitive::TriangleList, gfx::state::Rasterizer { front_face: gfx::state::FrontFace::CounterClockwise, - cull_face: gfx::state::CullFace::Back, + cull_face, method: gfx::state::RasterMethod::Fill, offset: None, samples: Some(gfx::state::MultiSample), diff --git a/world/src/column/mod.rs b/world/src/column/mod.rs index 3408f146f1..0958e810ab 100644 --- a/world/src/column/mod.rs +++ b/world/src/column/mod.rs @@ -335,7 +335,9 @@ impl<'a> Sampler for ColumnGen<'a> { / 100.0, ), // Beach - ((alt - CONFIG.sea_level - 1.0) / 2.0).min(1.0 - river * 2.0), + ((alt - CONFIG.sea_level - 1.0) / 2.0) + .min(1.0 - river * 2.0) + .max(0.0), ), sub_surface_color: dirt, tree_density,