From 0a5e257b775b7d846a053dc5cbce59b3ca411abc Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Sat, 22 Oct 2022 13:24:43 +0100 Subject: [PATCH] Remove close-up camera jitter --- voxygen/src/mesh/terrain.rs | 19 +++++++++++---- voxygen/src/render/pipelines/fluid.rs | 4 +++- voxygen/src/scene/camera.rs | 33 +++++++++++++++------------ voxygen/src/scene/terrain.rs | 3 ++- 4 files changed, 38 insertions(+), 21 deletions(-) diff --git a/voxygen/src/mesh/terrain.rs b/voxygen/src/mesh/terrain.rs index 13dc804f79..4f4e6410f9 100644 --- a/voxygen/src/mesh/terrain.rs +++ b/voxygen/src/mesh/terrain.rs @@ -392,11 +392,20 @@ pub fn generate_mesh<'a>( |atlas_pos, pos, norm, meta| TerrainVertex::new(atlas_pos, pos + mesh_delta, norm, meta); let create_transparent = |_atlas_pos, pos: Vec3, norm| { let key = vol.pos_key(range.min + pos.as_()); - let v00 = vol.get_key(key + Vec2::new(0, 0)).map_or(Vec3::zero(), |c| c.meta().river_velocity()); - let v10 = vol.get_key(key + Vec2::new(1, 0)).map_or(Vec3::zero(), |c| c.meta().river_velocity()); - let v01 = vol.get_key(key + Vec2::new(0, 1)).map_or(Vec3::zero(), |c| c.meta().river_velocity()); - let v11 = vol.get_key(key + Vec2::new(1, 1)).map_or(Vec3::zero(), |c| c.meta().river_velocity()); - let factor = (range.min + pos.as_()).map(|e| e as f32) / TerrainChunk::RECT_SIZE.map(|e| e as f32); + let v00 = vol + .get_key(key + Vec2::new(0, 0)) + .map_or(Vec3::zero(), |c| c.meta().river_velocity()); + let v10 = vol + .get_key(key + Vec2::new(1, 0)) + .map_or(Vec3::zero(), |c| c.meta().river_velocity()); + let v01 = vol + .get_key(key + Vec2::new(0, 1)) + .map_or(Vec3::zero(), |c| c.meta().river_velocity()); + let v11 = vol + .get_key(key + Vec2::new(1, 1)) + .map_or(Vec3::zero(), |c| c.meta().river_velocity()); + let factor = + (range.min + pos.as_()).map(|e| e as f32) / TerrainChunk::RECT_SIZE.map(|e| e as f32); let vel = Lerp::lerp( Lerp::lerp(v00, v10, factor.x.rem_euclid(1.0)), Lerp::lerp(v01, v11, factor.x.rem_euclid(1.0)), diff --git a/voxygen/src/render/pipelines/fluid.rs b/voxygen/src/render/pipelines/fluid.rs index a7fcccaf58..aea36bbfd5 100644 --- a/voxygen/src/render/pipelines/fluid.rs +++ b/voxygen/src/render/pipelines/fluid.rs @@ -29,7 +29,9 @@ impl Vertex { | (((pos.z + EXTRA_NEG_Z).max(0.0).min((1 << 17) as f32) as u32) & 0x1FFFF) << 12 | (norm_bits & 0x7) << 29, vel: river_velocity - .map2(Vec2::new(0, 16), |e, off| (((e * 1000.0 + 32768.9) as u16 as u32) << off)) + .map2(Vec2::new(0, 16), |e, off| { + (((e * 1000.0 + 32768.9) as u16 as u32) << off) + }) .reduce_bitor(), } } diff --git a/voxygen/src/scene/camera.rs b/voxygen/src/scene/camera.rs index 26ed0a74a7..6cef70a274 100644 --- a/voxygen/src/scene/camera.rs +++ b/voxygen/src/scene/camera.rs @@ -1,6 +1,6 @@ use common::{terrain::TerrainGrid, vol::ReadVol}; use common_base::span; -use core::{f32::consts::PI, fmt::Debug}; +use core::{f32::consts::PI, fmt::Debug, ops::Range}; use num::traits::{real::Real, FloatConst}; use treeculler::Frustum; use vek::*; @@ -12,7 +12,7 @@ const FIRST_PERSON_INTERP_TIME: f32 = 0.1; const THIRD_PERSON_INTERP_TIME: f32 = 0.1; const FREEFLY_INTERP_TIME: f32 = 0.0; const LERP_ORI_RATE: f32 = 15.0; -const CLIPPING_MODE_DISTANCE: f32 = 20.0; +const CLIPPING_MODE_DISTANCE: Range = 2.0..20.0; pub const MIN_ZOOM: f32 = 0.1; // Possible TODO: Add more modes @@ -368,7 +368,7 @@ impl Camera { ) { span!(_guard, "compute_dependents", "Camera::compute_dependents"); // TODO: More intelligent function to decide on which strategy to use - if self.tgt_dist < CLIPPING_MODE_DISTANCE { + if self.tgt_dist < CLIPPING_MODE_DISTANCE.end { self.compute_dependents_near(terrain, is_transparent) } else { self.compute_dependents_far(terrain, is_transparent) @@ -425,18 +425,23 @@ impl Camera { .unwrap_or(0.0) }; - if self.dist >= dist { - self.dist = dist; - } - - // Recompute only if needed - if (dist - self.tgt_dist).abs() > f32::EPSILON { - let dependents = self.compute_dependents_helper(dist); - self.frustum = self.compute_frustum(&dependents); - self.dependents = dependents; + // If the camera ends up being too close to the focus point, switch policies. + if dist < CLIPPING_MODE_DISTANCE.start { + self.compute_dependents_far(terrain, is_transparent); } else { - self.dependents = local_dependents; - self.frustum = frustum; + if self.dist >= dist { + self.dist = dist; + } + + // Recompute only if needed + if (dist - self.tgt_dist).abs() > f32::EPSILON { + let dependents = self.compute_dependents_helper(dist); + self.frustum = self.compute_frustum(&dependents); + self.dependents = dependents; + } else { + self.dependents = local_dependents; + self.frustum = frustum; + } } } diff --git a/voxygen/src/scene/terrain.rs b/voxygen/src/scene/terrain.rs index cf23c3bc6a..bbbb9c1111 100644 --- a/voxygen/src/scene/terrain.rs +++ b/voxygen/src/scene/terrain.rs @@ -278,7 +278,8 @@ fn mesh_worker( for y in 0..TerrainChunk::RECT_SIZE.y as i32 { for z in z_bounds.0 as i32..z_bounds.1 as i32 + 1 { let rel_pos = Vec3::new(x, y, z); - let wpos = Vec3::from(pos * TerrainChunk::RECT_SIZE.map(|e: u32| e as i32)) + rel_pos; + let wpos = Vec3::from(pos * TerrainChunk::RECT_SIZE.map(|e: u32| e as i32)) + + rel_pos; let block = if let Ok(block) = volume.get(wpos) { block