improvement: fog doesn't go back and forth anymore

This commit is contained in:
timokoesters 2020-01-12 12:09:37 +01:00 committed by Imbris
parent b3cdde3ce9
commit ae1fa5e4c4
3 changed files with 25 additions and 15 deletions

View File

@ -69,7 +69,7 @@ pub struct Client {
entity: EcsEntity,
view_distance: Option<u32>,
loaded_distance: Option<u32>,
loaded_distance: f32,
pending_chunks: HashMap<Vec2<i32>, Instant>,
}
@ -153,7 +153,7 @@ impl Client {
state,
entity,
view_distance,
loaded_distance: None,
loaded_distance: 0.0,
pending_chunks: HashMap::new(),
})
@ -260,7 +260,7 @@ impl Client {
self.view_distance
}
pub fn loaded_distance(&self) -> Option<u32> {
pub fn loaded_distance(&self) -> f32 {
self.loaded_distance
}
@ -410,8 +410,9 @@ impl Client {
}
// Request chunks from the server.
let mut all_loaded = true;
'outer: for dist in 0..(view_distance as i32) + 1 {
self.loaded_distance = ((view_distance * TerrainChunkSize::RECT_SIZE.x) as f32).powi(2);
// +1 so we can find a chunk that's outside the vd for better fog
for dist in 0..view_distance as i32 + 1 {
// Only iterate through chunks that need to be loaded for circular vd
// The (dist - 2) explained:
// -0.5 because a chunk is visible if its corner is within the view distance
@ -428,6 +429,7 @@ impl Client {
dist
};
let mut skip_mode = false;
for i in -top..top + 1 {
let keys = [
chunk_pos + Vec2::new(dist, i),
@ -438,25 +440,32 @@ impl Client {
for key in keys.iter() {
if self.state.terrain().get_key(*key).is_none() {
if !self.pending_chunks.contains_key(key) {
if !skip_mode && !self.pending_chunks.contains_key(key) {
if self.pending_chunks.len() < 4 {
self.postbox
.send_message(ClientMsg::TerrainChunkRequest { key: *key });
self.pending_chunks.insert(*key, Instant::now());
} else {
break 'outer;
skip_mode = true;
}
}
all_loaded = false;
let dist_to_player =
(self.state.terrain().key_pos(*key).map(|x| x as f32)
+ TerrainChunkSize::RECT_SIZE.map(|x| x as f32) / 2.0)
.distance_squared(pos.0.into());
if dist_to_player < self.loaded_distance {
self.loaded_distance = dist_to_player;
}
}
}
}
if all_loaded {
self.loaded_distance = Some((dist - 1).max(0) as u32);
}
}
self.loaded_distance = self.loaded_distance.sqrt()
- ((TerrainChunkSize::RECT_SIZE.x as f32 / 2.0).powi(2)
+ (TerrainChunkSize::RECT_SIZE.y as f32 / 2.0).powi(2))
.sqrt();
// If chunks are taking too long, assume they're no longer pending.
let now = Instant::now();

View File

@ -1433,8 +1433,9 @@ impl Hud {
.set(self.ids.velocity, ui_widgets);
// Loaded distance
Text::new(&format!(
"View distance: {} chunks",
client.loaded_distance().unwrap_or(0)
"View distance: {:.2} blocks ({:.2} chunks)",
client.loaded_distance(),
client.loaded_distance() / TerrainChunk::RECT_SIZE.x as f32,
))
.color(TEXT_COLOR)
.down_from(self.ids.velocity, 5.0)

View File

@ -208,7 +208,7 @@ impl Scene {
let (view_mat, proj_mat, cam_pos) = self.camera.compute_dependents(client);
// Update chunk loaded distance smoothly for nice shader fog
let loaded_distance = client.loaded_distance().unwrap_or(0) as f32 * 32.0; // TODO: No magic!
let loaded_distance = client.loaded_distance();
self.loaded_distance = (0.98 * self.loaded_distance + 0.02 * loaded_distance).max(0.01);
// Update light constants