Added dynamic fog growth

This commit is contained in:
Joshua Barretto 2019-06-05 17:32:33 +01:00
parent 9da2d82197
commit 76dca0b0cf
4 changed files with 39 additions and 16 deletions

View File

@ -46,6 +46,7 @@ pub struct Client {
state: State,
entity: EcsEntity,
view_distance: Option<u32>,
loaded_distance: Option<u32>,
pending_chunks: HashMap<Vec2<i32>, Instant>,
}
@ -96,6 +97,7 @@ impl Client {
state,
entity,
view_distance,
loaded_distance: None,
pending_chunks: HashMap::new(),
})
@ -144,6 +146,10 @@ impl Client {
self.view_distance
}
pub fn loaded_distance(&self) -> Option<u32> {
self.loaded_distance
}
/// Send a chat message to the server.
#[allow(dead_code)]
pub fn send_chat(&mut self, msg: String) {
@ -253,7 +259,7 @@ impl Client {
if (Vec2::from(chunk_pos) - Vec2::from(key))
.map(|e: i32| e.abs() as u32)
.reduce_max()
> view_distance
> view_distance + 1
{
chunks_to_remove.push(key);
}
@ -264,23 +270,30 @@ impl Client {
// Request chunks from the server.
// TODO: This is really inefficient.
let mut all_loaded = true;
'outer: for dist in 0..=view_distance as i32 {
for i in chunk_pos.x - dist..=chunk_pos.x + dist {
for j in chunk_pos.y - dist..=chunk_pos.y + dist {
for i in chunk_pos.x - dist..=chunk_pos.x + 1 + dist {
for j in chunk_pos.y - dist..=chunk_pos.y + 1 + dist {
let key = Vec2::new(i, j);
if self.state.terrain().get_key(key).is_none()
&& !self.pending_chunks.contains_key(&key)
{
if self.pending_chunks.len() < 4 {
self.postbox
.send_message(ClientMsg::TerrainChunkRequest { key });
self.pending_chunks.insert(key, Instant::now());
} else {
break 'outer;
if self.state.terrain().get_key(key).is_none() {
if !self.pending_chunks.contains_key(&key) {
if self.pending_chunks.len() < 4 {
self.postbox
.send_message(ClientMsg::TerrainChunkRequest { key });
self.pending_chunks.insert(key, Instant::now());
} else {
break 'outer;
}
}
all_loaded = false;
}
}
}
if all_loaded {
self.loaded_distance = Some((dist - 1).max(0) as u32);
}
}
// If chunks are taking too long, assume they're no longer pending.

View File

@ -312,7 +312,7 @@ impl Server {
.map(|e: i32| e.abs())
.reduce_max() as u32;
if dist <= view_distance {
if dist <= view_distance + 1 {
self.clients.notify(
entity,
ServerMsg::TerrainChunkUpdate {
@ -344,7 +344,11 @@ impl Server {
.map(|e: i32| e.abs() as u32)
.reduce_max();
if player.view_distance.map(|vd| dist <= vd).unwrap_or(false) {
if player
.view_distance
.map(|vd| dist <= vd + 1)
.unwrap_or(false)
{
should_drop = false;
break;
}

View File

@ -22,7 +22,7 @@ vec3 get_sky_color(vec3 dir, float time_of_day) {
float fog(vec2 f_pos, vec2 cam_pos) {
float dist = distance(f_pos, cam_pos) / view_distance.x;
float min_fog = 0.5;
float max_fog = 0.95;
float max_fog = 1.0;
return clamp((dist - min_fog) / (max_fog - min_fog), 0.0, 1.0);
}

View File

@ -40,6 +40,7 @@ pub struct Scene {
skybox: Skybox,
postprocess: PostProcess,
terrain: Terrain,
loaded_distance: f32,
figure_mgr: FigureMgr,
}
@ -64,6 +65,7 @@ impl Scene {
.unwrap(),
},
terrain: Terrain::new(),
loaded_distance: 0.0,
figure_mgr: FigureMgr::new(),
}
}
@ -127,6 +129,10 @@ impl Scene {
// Compute camera matrices.
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(1) as f32 * 32.0;
self.loaded_distance = 0.98 * self.loaded_distance + 0.02 * loaded_distance;
// Update global constants.
renderer
.update_consts(
@ -136,7 +142,7 @@ impl Scene {
proj_mat,
cam_pos,
self.camera.get_focus_pos(),
client.view_distance().unwrap_or(0) as f32 * 32.0, // TODO: No magic numbers
self.loaded_distance,
client.state().get_time_of_day(),
client.state().get_time(),
renderer.get_resolution(),