From 4bcc55ad344811f15c570ca7a4bb0c46ab1e4f7f Mon Sep 17 00:00:00 2001 From: Imbris Date: Thu, 24 Oct 2019 20:02:29 -0400 Subject: [PATCH] improvement: roughly ~20% speedup of terrain meshing by eliminating redundant lookups of terrain blocks --- voxygen/src/mesh/segment.rs | 34 ++++++++++++++----- voxygen/src/mesh/terrain.rs | 67 ++++++++++++++++++++++++------------- voxygen/src/mesh/vol.rs | 45 +++++-------------------- 3 files changed, 78 insertions(+), 68 deletions(-) diff --git a/voxygen/src/mesh/segment.rs b/voxygen/src/mesh/segment.rs index a588c33b3d..32094fd0f9 100644 --- a/voxygen/src/mesh/segment.rs +++ b/voxygen/src/mesh/segment.rs @@ -27,8 +27,7 @@ impl Meshable for Segment { if let Some(col) = vox.get_color() { vol::push_vox_verts( &mut mesh, - self, - pos, + faces_to_make(self, pos, true, |vox| vox.is_empty()), offs + pos.map(|e| e as f32), &[[[Rgba::from_opaque(col); 3]; 3]; 3], |origin, norm, col, ao, light| { @@ -39,7 +38,6 @@ impl Meshable for Segment { 0, ) }, - true, &{ let mut ls = [[[0.0; 3]; 3]; 3]; for x in 0..3 { @@ -59,7 +57,6 @@ impl Meshable for Segment { } ls }, - |vox| vox.is_empty(), ); } } @@ -83,8 +80,7 @@ impl Meshable for Segment { if let Some(col) = vox.get_color() { vol::push_vox_verts( &mut mesh, - self, - pos, + faces_to_make(self, pos, true, |vox| vox.is_empty()), offs + pos.map(|e| e as f32), &[[[Rgba::from_opaque(col); 3]; 3]; 3], |origin, norm, col, ao, light| { @@ -94,9 +90,7 @@ impl Meshable for Segment { linear_to_srgb(srgb_to_linear(col) * ao * light), ) }, - true, &[[[1.0; 3]; 3]; 3], - |vox| vox.is_empty(), ); } } @@ -104,3 +98,27 @@ impl Meshable for Segment { (mesh, Mesh::new()) } } + +/// Use the 6 voxels/blocks surrounding the one at the specified position +/// to detemine which faces should be drawn +fn faces_to_make( + seg: &V, + pos: Vec3, + error_makes_face: bool, + should_add: impl Fn(&V::Vox) -> bool, +) -> [bool; 6] { + let (x, y, z) = (Vec3::unit_x(), Vec3::unit_y(), Vec3::unit_z()); + let make_face = |offset| { + seg.get(pos + offset) + .map(|v| should_add(v)) + .unwrap_or(error_makes_face) + }; + [ + make_face(-x), + make_face(x), + make_face(-y), + make_face(y), + make_face(-z), + make_face(z), + ] +} diff --git a/voxygen/src/mesh/terrain.rs b/voxygen/src/mesh/terrain.rs index fec89fb225..fc557a5ffd 100644 --- a/voxygen/src/mesh/terrain.rs +++ b/voxygen/src/mesh/terrain.rs @@ -180,19 +180,21 @@ impl + ReadVol + Debug> Meshable + ReadVol + Debug> Meshable + ReadVol + Debug> Meshable + ReadVol + Debug> Meshable; 3]; 3]; 3], + error_makes_face: bool, + should_add: impl Fn(Block) -> bool, +) -> [bool; 6] { + // Faces to draw + let make_face = |opt_v: Option| opt_v.map(|v| should_add(v)).unwrap_or(error_makes_face); + [ + make_face(blocks[1][1][0]), + make_face(blocks[1][1][2]), + make_face(blocks[1][0][1]), + make_face(blocks[1][2][1]), + make_face(blocks[0][1][1]), + make_face(blocks[2][1][1]), + ] +} + /* impl + ReadVol + Debug> Meshable for VolGrid3d { type Pipeline = TerrainPipeline; diff --git a/voxygen/src/mesh/vol.rs b/voxygen/src/mesh/vol.rs index 8b342661c3..04014b3b28 100644 --- a/voxygen/src/mesh/vol.rs +++ b/voxygen/src/mesh/vol.rs @@ -1,7 +1,5 @@ use vek::*; -use common::vol::ReadVol; - use crate::render::{ mesh::{Mesh, Quad}, Pipeline, @@ -151,25 +149,18 @@ fn create_quad, Vec3, Rgb, f32, f32) -> P } } -pub fn push_vox_verts( +pub fn push_vox_verts( mesh: &mut Mesh

, - vol: &V, - pos: Vec3, + faces: [bool; 6], offs: Vec3, cols: &[[[Rgba; 3]; 3]; 3], vcons: impl Fn(Vec3, Vec3, Rgb, f32, f32) -> P::Vertex, - error_makes_face: bool, darknesses: &[[[f32; 3]; 3]; 3], - should_add: impl Fn(&V::Vox) -> bool, ) { let (x, y, z) = (Vec3::unit_x(), Vec3::unit_y(), Vec3::unit_z()); // -x - if vol - .get(pos - Vec3::unit_x()) - .map(|v| should_add(v)) - .unwrap_or(error_makes_face) - { + if faces[0] { mesh.push_quad(create_quad( offs, Vec3::unit_z(), @@ -181,11 +172,7 @@ pub fn push_vox_verts( )); } // +x - if vol - .get(pos + Vec3::unit_x()) - .map(|v| should_add(v)) - .unwrap_or(error_makes_face) - { + if faces[1] { mesh.push_quad(create_quad( offs + Vec3::unit_x(), Vec3::unit_y(), @@ -197,11 +184,7 @@ pub fn push_vox_verts( )); } // -y - if vol - .get(pos - Vec3::unit_y()) - .map(|v| should_add(v)) - .unwrap_or(error_makes_face) - { + if faces[2] { mesh.push_quad(create_quad( offs, Vec3::unit_x(), @@ -213,11 +196,7 @@ pub fn push_vox_verts( )); } // +y - if vol - .get(pos + Vec3::unit_y()) - .map(|v| should_add(v)) - .unwrap_or(error_makes_face) - { + if faces[3] { mesh.push_quad(create_quad( offs + Vec3::unit_y(), Vec3::unit_z(), @@ -229,11 +208,7 @@ pub fn push_vox_verts( )); } // -z - if vol - .get(pos - Vec3::unit_z()) - .map(|v| should_add(v)) - .unwrap_or(error_makes_face) - { + if faces[4] { mesh.push_quad(create_quad( offs, Vec3::unit_y(), @@ -245,11 +220,7 @@ pub fn push_vox_verts( )); } // +z - if vol - .get(pos + Vec3::unit_z()) - .map(|v| should_add(v)) - .unwrap_or(error_makes_face) - { + if faces[5] { mesh.push_quad(create_quad( offs + Vec3::unit_z(), Vec3::unit_x(),