Worldgen performance improvements, better sun

This commit is contained in:
Joshua Barretto 2019-06-21 13:32:38 +01:00
parent 9279611d6d
commit d0b38e9875
7 changed files with 100 additions and 85 deletions

View File

@ -27,7 +27,7 @@ impl Block {
pub fn get_opacity(&self) -> Option<f32> { pub fn get_opacity(&self) -> Option<f32> {
match self.kind { match self.kind {
0 => None, 0 => None,
1 => Some(0.85), 1 => Some(0.6),
_ => Some(1.0), _ => Some(1.0),
} }
} }

View File

@ -36,7 +36,7 @@ vec3 get_sun_dir(float time_of_day) {
} }
float get_sun_brightness(vec3 sun_dir) { float get_sun_brightness(vec3 sun_dir) {
return max(-sun_dir.z, 0.0); return pow(max(-sun_dir.z + 0.3, 0.0), 0.5);
} }
const float PERSISTENT_AMBIANCE = 0.015; const float PERSISTENT_AMBIANCE = 0.015;

View File

@ -83,8 +83,8 @@ impl<V: BaseVol<Vox = Block> + ReadVol + Debug, S: VolSize + Clone> Meshable for
TerrainVertex::new( TerrainVertex::new(
pos, pos,
norm, norm,
Lerp::lerp(Rgb::zero(), col, ao), Lerp::lerp(Rgb::zero(), col, 1.0),
light, light * ao,
) )
}, },
false, false,
@ -104,10 +104,10 @@ impl<V: BaseVol<Vox = Block> + ReadVol + Debug, S: VolSize + Clone> Meshable for
.ok() .ok()
.and_then(|vox| vox.get_opacity()) .and_then(|vox| vox.get_opacity())
{ {
(neighbour_light[0][i][j] * (1.0 - opacity * 0.2)) (neighbour_light[0][i][j] * (1.0 - opacity * 0.4))
.max(1.0 - opacity * 1.0) .max(1.0 - opacity)
} else { } else {
(neighbour_light[0][i][j] * 1.035).min(1.0) (neighbour_light[0][i][j] * 1.025).min(1.0)
}; };
} }
} }

View File

@ -43,18 +43,20 @@ impl<'a> BlockGen<'a> {
close_cliffs close_cliffs
.iter() .iter()
.fold(0.0f32, |max_height, (cliff_pos, seed)| { .fold(0.0f32, |max_height, (cliff_pos, seed)| {
let cliff_pos3d = Vec3::from(*cliff_pos);
let height = RandomField::new(seed + 1).get(cliff_pos3d) % 48;
let radius = RandomField::new(seed + 2).get(cliff_pos3d) % 48 + 8;
match self.sample_column(Vec2::from(*cliff_pos)) { match self.sample_column(Vec2::from(*cliff_pos)) {
Some(cliff_sample) => max_height.max(if cliff_sample.cliffs && cliff_pos.distance_squared(wpos) < (radius * radius) as i32 { Some(cliff_sample) if cliff_sample.cliffs => {
cliff_sample.alt + height as f32 * (1.0 - cliff_sample.chaos) + cliff_hill let cliff_pos3d = Vec3::from(*cliff_pos);
} else {
0.0 let height = RandomField::new(seed + 1).get(cliff_pos3d) % 48;
}), let radius = RandomField::new(seed + 2).get(cliff_pos3d) % 48 + 8;
None => max_height,
max_height.max(if cliff_pos.distance_squared(wpos) < (radius * radius) as i32 {
cliff_sample.alt + height as f32 * (1.0 - cliff_sample.chaos) + cliff_hill
} else {
0.0
})
},
_ => max_height,
} }
}) })
} }
@ -86,28 +88,38 @@ impl<'a> SamplerMut for BlockGen<'a> {
let wposf = wpos.map(|e| e as f64); let wposf = wpos.map(|e| e as f64);
// Apply warping let (definitely_underground, height, water_height) = if (wposf.z as f32) < alt - 64.0 * chaos {
// Shortcut warping
(true, alt, water_level)
} else {
// Apply warping
let warp = (self
.world
.sim()
.gen_ctx
.warp_nz
.get((wposf.div(Vec3::new(150.0, 150.0, 150.0))).into_array())
as f32)
.mul((chaos - 0.1).max(0.0))
.mul(115.0);
let warp = (self let height = if (wposf.z as f32) < alt + warp - 10.0 {
.world // Shortcut cliffs
.sim() alt + warp
.gen_ctx } else {
.warp_nz let turb = Vec2::new(
.get((wposf.div(Vec3::new(150.0, 150.0, 150.0))).into_array()) self.world.sim().gen_ctx.turb_x_nz.get((wposf.div(64.0)).into_array()) as f32,
as f32) self.world.sim().gen_ctx.turb_y_nz.get((wposf.div(64.0)).into_array()) as f32,
.mul((chaos - 0.1).max(0.0)) ) * 16.0;
.mul(115.0);
let turb = Vec2::new( let wpos_turb = Vec2::from(wpos) + turb.map(|e| e as i32);
self.world.sim().gen_ctx.turb_x_nz.get((wposf.div(48.0)).into_array()) as f32, let cliff_height = self.get_cliff_height(wpos_turb, &close_cliffs, cliff_hill);
self.world.sim().gen_ctx.turb_y_nz.get((wposf.div(48.0)).into_array()) as f32,
) * 12.0;
let wpos_turb = Vec2::from(wpos) + turb.map(|e| e as i32); (alt + warp).max(cliff_height)
let cliff_height = self.get_cliff_height(wpos_turb, &close_cliffs, cliff_hill); };
let height = (alt + warp).max(cliff_height); (false, height, water_level + warp)
let water_height = water_level + warp; };
// Sample blocks // Sample blocks
@ -172,7 +184,7 @@ impl<'a> SamplerMut for BlockGen<'a> {
let field2 = RandomField::new(self.world.sim().seed + 2); let field2 = RandomField::new(self.world.sim().seed + 2);
Some(Block::new( Some(Block::new(
2, 1,
stone_col stone_col
- Rgb::new( - Rgb::new(
field0.get(wpos) as u8 % 32, field0.get(wpos) as u8 % 32,
@ -226,40 +238,46 @@ impl<'a> SamplerMut for BlockGen<'a> {
} }
} }
let block = match block { let block = if definitely_underground {
Some(block) => block, block.unwrap_or(Block::empty())
None => (&close_trees) } else {
.iter() match block {
.fold(air, |block, (tree_pos, tree_seed)| { Some(block) => block,
match self.sample_column(Vec2::from(*tree_pos)) { None => (&close_trees)
Some(tree_sample) .iter()
if tree_sample.tree_density .fold(air, |block, (tree_pos, tree_seed)| if !block.is_empty() {
> 0.5 + (*tree_seed as f32 / 1000.0).fract() * 0.2 block
&& tree_sample.alt > tree_sample.water_level => } else {
{ match self.sample_column(Vec2::from(*tree_pos)) {
let cliff_height = self.get_cliff_height(*tree_pos, &tree_sample.close_cliffs, cliff_hill); Some(tree_sample)
let height = tree_sample.alt.max(cliff_height); if tree_sample.tree_density
let tree_pos3d = Vec3::new(tree_pos.x, tree_pos.y, height as i32); > 0.5 + (*tree_seed as f32 / 1000.0).fract() * 0.2
let rpos = wpos - tree_pos3d; && tree_sample.alt > tree_sample.water_level =>
{
let cliff_height = self.get_cliff_height(*tree_pos, &tree_sample.close_cliffs, cliff_hill);
let height = tree_sample.alt.max(cliff_height);
let tree_pos3d = Vec3::new(tree_pos.x, tree_pos.y, height as i32);
let rpos = wpos - tree_pos3d;
let trees = tree::kinds(tree_sample.forest_kind); // Choose tree kind let trees = tree::kinds(tree_sample.forest_kind); // Choose tree kind
block.or(trees[*tree_seed as usize % trees.len()] block.or(trees[*tree_seed as usize % trees.len()]
.get((rpos * 128) / 128) // Scaling .get((rpos * 128) / 128) // Scaling
.map(|b| { .map(|b| {
block_from_structure( block_from_structure(
*b, *b,
rpos, rpos,
*tree_pos, *tree_pos,
*tree_seed, *tree_seed,
&tree_sample, &tree_sample,
) )
}) })
.unwrap_or(Block::empty())) .unwrap_or(Block::empty()))
}
_ => block,
} }
_ => block, }),
} }
}),
}; };
Some(block) Some(block)

View File

@ -53,7 +53,7 @@ impl<'a> Sampler for ColumnGen<'a> {
.mul((1.0 - (chaos - 0.15) * 20.0).max(0.0).min(1.0)); .mul((1.0 - (chaos - 0.15) * 20.0).max(0.0).min(1.0));
let cliff_hill = (sim.gen_ctx.small_nz.get((wposf.div(128.0)).into_array()) as f32) let cliff_hill = (sim.gen_ctx.small_nz.get((wposf.div(128.0)).into_array()) as f32)
.mul(12.0); .mul(16.0);
let riverless_alt = sim.get_interpolated(wpos, |chunk| chunk.alt)? let riverless_alt = sim.get_interpolated(wpos, |chunk| chunk.alt)?
+ (sim.gen_ctx.small_nz.get((wposf.div(256.0)).into_array()) as f32) + (sim.gen_ctx.small_nz.get((wposf.div(256.0)).into_array()) as f32)
@ -129,7 +129,7 @@ impl<'a> Sampler for ColumnGen<'a> {
.mul((1.15 - chaos).min(1.0)) .mul((1.15 - chaos).min(1.0))
}; };
let cave_xy = cave_at(wposf); let cave_xy = cave_at(wposf);
let cave_alt = alt - 16.0 let cave_alt = alt - 24.0
+ (sim + (sim
.gen_ctx .gen_ctx
.cave_1_nz .cave_1_nz
@ -138,11 +138,11 @@ impl<'a> Sampler for ColumnGen<'a> {
+ (sim + (sim
.gen_ctx .gen_ctx
.cave_1_nz .cave_1_nz
.get(Vec2::new(wposf.x, wposf.y).div(300.0).into_array()) as f32) .get(Vec2::new(wposf.x, wposf.y).div(500.0).into_array()) as f32)
.add(1.0) .add(1.0)
.mul(0.5) .mul(0.5)
.powf(8.0) .powf(15.0)
.mul(256.0); .mul(150.0);
Some(ColumnSample { Some(ColumnSample {
alt, alt,

View File

@ -71,7 +71,7 @@ impl WorldSim {
cave_1_nz: SuperSimplex::new().set_seed(seed + 14), cave_1_nz: SuperSimplex::new().set_seed(seed + 14),
tree_gen: StructureGen2d::new(seed, 32, 24), tree_gen: StructureGen2d::new(seed, 32, 24),
cliff_gen: StructureGen2d::new(seed, 80, 64), cliff_gen: StructureGen2d::new(seed, 80, 56),
}; };
let mut chunks = Vec::new(); let mut chunks = Vec::new();
@ -229,7 +229,7 @@ impl WorldSim {
} }
} }
const Z_TOLERANCE: (f32, f32) = (64.0, 128.0); const Z_TOLERANCE: (f32, f32) = (100.0, 128.0);
pub struct SimChunk { pub struct SimChunk {
pub chaos: f32, pub chaos: f32,
@ -325,7 +325,7 @@ impl SimChunk {
.sub(0.1) .sub(0.1)
.mul(1.3) .mul(1.3)
.max(0.0), .max(0.0),
cliffs: cliff > 0.5, cliffs: cliff > 0.5 && dryness > 0.05,
near_cliffs: cliff > 0.4, near_cliffs: cliff > 0.4,
tree_density: (gen_ctx.tree_nz.get((wposf.div(1024.0)).into_array()) as f32) tree_density: (gen_ctx.tree_nz.get((wposf.div(1024.0)).into_array()) as f32)
.add(1.0) .add(1.0)

View File

@ -20,22 +20,19 @@ impl Sampler for RandomField {
let next = self.seed.wrapping_mul(0x168E3D1F).wrapping_add(0xDEADBEAD); let next = self.seed.wrapping_mul(0x168E3D1F).wrapping_add(0xDEADBEAD);
let next = next let next = next
.rotate_left(13)
.wrapping_mul(133227) .wrapping_mul(133227)
.wrapping_add(pos.x); .wrapping_add(pos.x);
let next = next.rotate_left(13).wrapping_mul(318912) ^ 0x42133742; let next = next.rotate_left(13).wrapping_add(318912) ^ 0x42133742;
let next = next let next = next
.rotate_left(13)
.wrapping_mul(938219) .wrapping_mul(938219)
.wrapping_add(pos.y); .wrapping_add(pos.y);
let next = next.rotate_left(13).wrapping_mul(318912) ^ 0x23341753; let next = next.rotate_left(13).wrapping_add(318912) ^ 0x23341753;
let next = next let next = next
.rotate_left(13)
.wrapping_mul(938219) .wrapping_mul(938219)
.wrapping_add(pos.z); .wrapping_add(pos.z);
let next = next.rotate_left(13).wrapping_mul(313322) ^ 0xDEADBEEF; let next = next.wrapping_add(313322) ^ 0xDEADBEEF;
let next = next.rotate_left(13).wrapping_mul(929009) ^ 0xFF329DE3; let next = next.wrapping_sub(929009) ^ 0xFF329DE3;
let next = next.rotate_left(13).wrapping_mul(422671) ^ 0x42892942; let next = next.wrapping_add(422671) ^ 0x42892942;
next next.rotate_left(13)
} }
} }