From bc7cee18460267a872f9f6eb8d3249c6e56dc18e Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Tue, 18 Jun 2019 12:33:18 +0100 Subject: [PATCH] Lighting fixes --- voxygen/shaders/terrain.frag | 4 +-- voxygen/src/mesh/segment.rs | 7 ++--- voxygen/src/mesh/terrain.rs | 58 ++++++++++++++++++++--------------- voxygen/src/mesh/vol.rs | 59 ++++++++++++++++++++++-------------- world/src/column/mod.rs | 11 ++++--- 5 files changed, 80 insertions(+), 59 deletions(-) diff --git a/voxygen/shaders/terrain.frag b/voxygen/shaders/terrain.frag index 3678ec803d..e3d350f924 100644 --- a/voxygen/shaders/terrain.frag +++ b/voxygen/shaders/terrain.frag @@ -30,11 +30,11 @@ void main() { float glob_ambience = 0.0005; - float sun_ambience = 0.8; + float sun_ambience = 0.3; vec3 sun_dir = normalize(vec3(0.7, 1.3, 2.1)); - float sun_diffuse = dot(sun_dir, f_norm); + float sun_diffuse = max(dot(sun_dir, f_norm), 0.0); float sun_light = sun_ambience + sun_diffuse; float static_light = glob_ambience + min(sun_light, f_light); diff --git a/voxygen/src/mesh/segment.rs b/voxygen/src/mesh/segment.rs index ad01b2f054..3ef53159f5 100644 --- a/voxygen/src/mesh/segment.rs +++ b/voxygen/src/mesh/segment.rs @@ -10,10 +10,6 @@ use vek::*; type FigureVertex = ::Vertex; -fn create_vertex(origin: Vec3, norm: Vec3, col: Rgb) -> FigureVertex { - FigureVertex::new(origin, norm, col, 0) -} - impl Meshable for Segment { type Pipeline = FigurePipeline; type Supplement = Vec3; @@ -31,8 +27,9 @@ impl Meshable for Segment { pos, offs + pos.map(|e| e as f32), col, - create_vertex, + |origin, norm, col, light| FigureVertex::new(origin, norm, col * light, 0), true, + &[[[1.0; 3]; 3]; 3], ); } } diff --git a/voxygen/src/mesh/terrain.rs b/voxygen/src/mesh/terrain.rs index 868a2d9498..e299f9635f 100644 --- a/voxygen/src/mesh/terrain.rs +++ b/voxygen/src/mesh/terrain.rs @@ -51,19 +51,48 @@ impl + ReadVol + Debug, S: VolSize + Clone> Meshable for for x in range.min.x + 1..range.max.x - 1 { for y in range.min.y + 1..range.max.y - 1 { - let mut neighbour_light = [[(1.0f32, 0.0); 3]; 3]; + let mut neighbour_light = [[[1.0f32; 3]; 3]; 3]; for z in (range.min.z..range.max.z).rev() { let pos = Vec3::new(x, y, z); + // Shift lighting + neighbour_light[2] = neighbour_light[1]; + neighbour_light[1] = neighbour_light[0]; + + // Accumulate shade under opaque blocks + for i in 0..3 { + for j in 0..3 { + neighbour_light[0][i][j] = if let Some(opacity) = self + .get(pos + Vec3::new(i as i32 - 1, j as i32 - 1, -1)) + .ok() + .and_then(|vox| vox.get_opacity()) + { + (neighbour_light[0][i][j] * (1.0 - opacity * 0.2)).max(1.0 - opacity * 1.0) + } else { + (neighbour_light[0][i][j] * 1.035).min(1.0) + }; + } + } + + // Spread light + neighbour_light[0] = [[neighbour_light[0] + .iter() + .map(|col| col.iter()) + .flatten() + .copied() + .fold(0.0, |a, x| a + x) / 9.0; 3]; 3]; + // Create mesh polygons if let Some(col) = self.get(pos).ok().and_then(|vox| vox.get_color()) { let avg_light = neighbour_light .iter() + .map(|row| row.iter()) + .flatten() .map(|col| col.iter()) .flatten() - .fold(0.0, |a, (x, _)| a + x) - / 9.0; + .fold(0.0, |a, x| a + x) + / 27.0; let light = avg_light; let col = col.map(|e| e as f32 / 255.0); @@ -77,30 +106,11 @@ impl + ReadVol + Debug, S: VolSize + Clone> Meshable for pos, offs, col, - |pos, norm, col| TerrainVertex::new(pos, norm, col, light), + |pos, norm, col, light| TerrainVertex::new(pos, norm, col, light), false, + &neighbour_light, ); } - - // Accumulate shade under opaque blocks - for i in 0..3 { - for j in 0..3 { - let max_opacity = neighbour_light[i][j].1; - neighbour_light[i][j] = if let Some(opacity) = self - .get(pos + Vec3::new(i as i32 - 1, j as i32 - 1, 0)) - .ok() - .and_then(|vox| vox.get_opacity()) - { - ( - (neighbour_light[i][j].0 * (1.0 - max_opacity * 0.3)) - .max(1.0 - max_opacity * 0.999), - max_opacity.max(opacity), - ) - } else { - ((neighbour_light[i][j].0 * 1.02).min(1.0), max_opacity) - }; - } - } } } } diff --git a/voxygen/src/mesh/vol.rs b/voxygen/src/mesh/vol.rs index 7223a46af7..50d66a9135 100644 --- a/voxygen/src/mesh/vol.rs +++ b/voxygen/src/mesh/vol.rs @@ -10,23 +10,33 @@ use crate::render::{ /// Given volume, position, and cardinal directions, compute each vertex's AO value. /// `dirs` should be a slice of length 5 so that the sliding window of size 2 over the slice /// yields each vertex' adjacent positions. -fn get_ao_quad(vol: &V, pos: Vec3, dirs: &[Vec3]) -> Vec4 { +fn get_ao_quad(vol: &V, pos: Vec3, shift: Vec3, dirs: &[Vec3], corners: &[[usize; 3]; 4], darknesses: &[[[f32; 3]; 3]; 3]) -> Vec4 { dirs.windows(2) - .map(|offs| { + .enumerate() + .map(|(i, offs)| { let (s1, s2) = ( - vol.get(pos + offs[0]) + vol.get(pos + shift + offs[0]) .map(|v| !v.is_empty()) .unwrap_or(false), - vol.get(pos + offs[1]) + vol.get(pos + shift + offs[1]) .map(|v| !v.is_empty()) .unwrap_or(false), ); - if s1 && s2 { + let darkness = darknesses[corners[i][0]][corners[i][1]][corners[i][2]]; + + let darkness = darknesses + .iter() + .map(|x| x.iter().map(|y| y.iter())) + .flatten() + .flatten() + .fold(0.0, |a: f32, x| a.max(*x)); + + darkness * if s1 && s2 { 0.0 } else { let corner = vol - .get(pos + offs[0] + offs[1]) + .get(pos + shift + offs[0] + offs[1]) .map(|v| !v.is_empty()) .unwrap_or(false); // Map both 1 and 2 neighbors to 0.5 occlusion. @@ -41,7 +51,7 @@ fn get_ao_quad(vol: &V, pos: Vec3, dirs: &[Vec3]) -> Vec4< } // Utility function -fn create_quad, Vec3, Rgb) -> P::Vertex>( +fn create_quad, Vec3, Rgb, f32) -> P::Vertex>( origin: Vec3, unit_x: Vec3, unit_y: Vec3, @@ -53,29 +63,31 @@ fn create_quad, Vec3, Rgb) -> P::Vertex>( let ao_scale = 0.95; let dark = col * (1.0 - ao_scale); - let ao_map = ao.map(|e| 0.15 + e.powf(2.0) * 0.85); + let ao_map = ao;//ao.map(|e| 0.2 + e.powf(1.0) * 0.8); if ao[0].min(ao[2]) < ao[1].min(ao[3]) { Quad::new( - vcons(origin + unit_y, norm, Rgb::lerp(dark, col, ao_map[3])), - vcons(origin, norm, Rgb::lerp(dark, col, ao_map[0])), - vcons(origin + unit_x, norm, Rgb::lerp(dark, col, ao_map[1])), + vcons(origin + unit_y, norm, col, ao_map[3]), + vcons(origin, norm, col, ao_map[0]), + vcons(origin + unit_x, norm, col, ao_map[1]), vcons( origin + unit_x + unit_y, norm, - Rgb::lerp(dark, col, ao_map[2]), + col, + ao_map[2], ), ) } else { Quad::new( - vcons(origin, norm, Rgb::lerp(dark, col, ao_map[0])), - vcons(origin + unit_x, norm, Rgb::lerp(dark, col, ao_map[1])), + vcons(origin, norm, col, ao_map[0]), + vcons(origin + unit_x, norm, col, ao_map[1]), vcons( origin + unit_x + unit_y, norm, - Rgb::lerp(dark, col, ao_map[2]), + col, + ao_map[2], ), - vcons(origin + unit_y, norm, Rgb::lerp(dark, col, ao_map[3])), + vcons(origin + unit_y, norm, col, ao_map[3]), ) } } @@ -83,7 +95,7 @@ fn create_quad, Vec3, Rgb) -> P::Vertex>( pub fn push_vox_verts< V: ReadVol, P: Pipeline, - F: Fn(Vec3, Vec3, Rgb) -> P::Vertex, + F: Fn(Vec3, Vec3, Rgb, f32) -> P::Vertex, >( mesh: &mut Mesh

, vol: &V, @@ -92,6 +104,7 @@ pub fn push_vox_verts< col: Rgb, vcons: F, error_makes_face: bool, + darknesses: &[[[f32; 3]; 3]; 3], ) { let (x, y, z) = (Vec3::unit_x(), Vec3::unit_y(), Vec3::unit_z()); @@ -107,7 +120,7 @@ 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]), + get_ao_quad(vol, pos, -Vec3::unit_x(), &[-z, -y, z, y, -z], &[[0; 3]; 4], darknesses), &vcons, )); } @@ -123,7 +136,7 @@ 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]), + get_ao_quad(vol, pos, Vec3::unit_x(), &[-y, -z, y, z, -y], &[[0; 3]; 4], darknesses), &vcons, )); } @@ -139,7 +152,7 @@ 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]), + get_ao_quad(vol, pos, -Vec3::unit_y(), &[-x, -z, x, z, -x], &[[0; 3]; 4], darknesses), &vcons, )); } @@ -155,7 +168,7 @@ 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]), + get_ao_quad(vol, pos, Vec3::unit_y(), &[-z, -x, z, x, -z], &[[0; 3]; 4], darknesses), &vcons, )); } @@ -171,7 +184,7 @@ 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]), + get_ao_quad(vol, pos, -Vec3::unit_z(), &[-y, -x, y, x, -y], &[[0; 3]; 4], darknesses), &vcons, )); } @@ -187,7 +200,7 @@ 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]), + get_ao_quad(vol, pos, Vec3::unit_z(), &[-x, -y, x, y, -x], &[[0, 0, 1], [1, 0, 1], [1, 1, 1], [0, 1, 1]], darknesses), &vcons, )); } diff --git a/world/src/column/mod.rs b/world/src/column/mod.rs index 0783aa4dd5..551267964c 100644 --- a/world/src/column/mod.rs +++ b/world/src/column/mod.rs @@ -39,9 +39,10 @@ impl<'a> Sampler for ColumnGen<'a> { let forest_kind = sim.get(chunk_pos)?.forest_kind; let alt = sim.get_interpolated(wpos, |chunk| chunk.alt)? - + sim.gen_ctx.small_nz.get((wposf.div(256.0)).into_array()) as f32 - * chaos.max(0.2) - * 64.0; + + (sim.gen_ctx.small_nz.get((wposf.div(256.0)).into_array()) as f32) + .abs() + .mul(chaos.max(0.2)) + .mul(64.0); let rock = (sim.gen_ctx.small_nz.get( Vec3::new(wposf.x, wposf.y, alt as f64) @@ -62,8 +63,8 @@ impl<'a> Sampler for ColumnGen<'a> { .mul(0.5); // Colours - let cold_grass = Rgb::new(0.0, 0.3, 0.1); - let warm_grass = Rgb::new(0.35, 1.0, 0.05); + let cold_grass = Rgb::new(0.0, 0.3, 0.15); + let warm_grass = Rgb::new(0.2, 0.8, 0.05); let cold_stone = Rgb::new(0.55, 0.7, 0.75); let warm_stone = Rgb::new(0.65, 0.65, 0.35); let beach_sand = Rgb::new(0.93, 0.84, 0.4);