Better rivers, rewrote cliffs

This commit is contained in:
Joshua Barretto 2019-06-21 01:53:11 +01:00
parent 1642988615
commit fffef7c739
4 changed files with 78 additions and 32 deletions

View File

@ -66,7 +66,7 @@ vec3 get_sky_color(vec3 dir, float time_of_day) {
vec3 sun_dir = get_sun_dir(time_of_day);
float sky_brightness = get_sun_brightness(sun_dir);
vec3 sun_halo = pow(max(dot(dir, -sun_dir) + 0.1, 0.0), 8.0) * SUN_HALO_COLOR;
vec3 sun_halo = pow(max(dot(dir, -sun_dir) + 0.5, 0.0), 8.0) * SUN_HALO_COLOR;
vec3 sun_surf = pow(max(dot(dir, -sun_dir) - 0.0045, 0.0), 1000.0) * SUN_SURF_COLOR;
vec3 sun_light = sun_halo + sun_surf;

View File

@ -10,12 +10,15 @@ use common::{
vol::{ReadVol, Vox},
};
use noise::NoiseFn;
use std::ops::{Add, Div, Mul, Neg, Sub};
use std::{
cell::RefCell,
ops::{Add, Div, Mul, Neg, Sub},
};
use vek::*;
pub struct BlockGen<'a> {
world: &'a World,
column_cache: HashCache<Vec2<i32>, Option<ColumnSample<'a>>>,
column_cache: RefCell<HashCache<Vec2<i32>, Option<ColumnSample<'a>>>>,
column_gen: ColumnGen<'a>,
}
@ -23,17 +26,38 @@ impl<'a> BlockGen<'a> {
pub fn new(world: &'a World, column_gen: ColumnGen<'a>) -> Self {
Self {
world,
column_cache: HashCache::with_capacity(1024),
column_cache: RefCell::new(HashCache::with_capacity(1024)),
column_gen,
}
}
fn sample_column(&mut self, wpos: Vec2<i32>) -> Option<ColumnSample> {
let column_gen = &mut self.column_gen;
fn sample_column(&self, wpos: Vec2<i32>) -> Option<ColumnSample> {
let column_gen = &self.column_gen;
self.column_cache
.borrow_mut()
.get(Vec2::from(wpos), |wpos| column_gen.get(wpos))
.clone()
}
fn get_cliff_height(&self, wpos: Vec2<i32>, close_cliffs: &[(Vec2<i32>, u32); 9], cliff_hill: f32) -> f32 {
close_cliffs
.iter()
.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)) {
Some(cliff_sample) => max_height.max(if cliff_sample.cliffs && 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
}),
None => max_height,
}
})
}
}
impl<'a> SamplerMut for BlockGen<'a> {
@ -53,7 +77,9 @@ impl<'a> SamplerMut for BlockGen<'a> {
cave_xy,
cave_alt,
rock,
cliff,
cliffs,
cliff_hill,
close_cliffs,
temp,
..
} = self.sample_column(Vec2::from(wpos))?;
@ -72,6 +98,15 @@ impl<'a> SamplerMut for BlockGen<'a> {
.mul((chaos - 0.1).max(0.0))
.mul(115.0);
let turb = Vec2::new(
self.world.sim().gen_ctx.turb_x_nz.get((wposf.div(48.0)).into_array()) as f32,
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);
let cliff_height = self.get_cliff_height(wpos_turb, &close_cliffs, cliff_hill);
/*
let is_cliff = if cliff > 0.0 {
(self
.world
@ -107,8 +142,9 @@ impl<'a> SamplerMut for BlockGen<'a> {
} else {
0.0
};
*/
let height = alt + warp + cliff;
let height = (alt + warp).max(cliff_height);
let water_height = water_level + warp;
// Sample blocks
@ -239,8 +275,9 @@ impl<'a> SamplerMut for BlockGen<'a> {
> 0.5 + (*tree_seed as f32 / 1000.0).fract() * 0.2
&& tree_sample.alt > tree_sample.water_level =>
{
let tree_pos3d =
Vec3::new(tree_pos.x, tree_pos.y, tree_sample.alt as i32);
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

View File

@ -38,7 +38,6 @@ impl<'a> Sampler for ColumnGen<'a> {
let temp = sim.get_interpolated(wpos, |chunk| chunk.temp)?;
let dryness = sim.get_interpolated(wpos, |chunk| chunk.dryness)?;
let rockiness = sim.get_interpolated(wpos, |chunk| chunk.rockiness)?;
let cliffiness = sim.get_interpolated(wpos, |chunk| chunk.cliffiness)?;
let tree_density = sim.get_interpolated(wpos, |chunk| chunk.tree_density)?;
let sim_chunk = sim.get(chunk_pos)?;
@ -53,12 +52,17 @@ impl<'a> Sampler for ColumnGen<'a> {
.max(0.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)
.mul(12.0);
let riverless_alt = sim.get_interpolated(wpos, |chunk| chunk.alt)?
+ (sim.gen_ctx.small_nz.get((wposf.div(256.0)).into_array()) as f32)
.abs()
.mul(chaos.max(0.2))
.mul(64.0);
let cliffs = sim_chunk.cliffs;
let alt = riverless_alt
- (1.0 - river)
.mul(f32::consts::PI)
@ -125,7 +129,7 @@ impl<'a> Sampler for ColumnGen<'a> {
.mul((1.15 - chaos).min(1.0))
};
let cave_xy = cave_at(wposf);
let cave_alt = alt - 32.0
let cave_alt = alt - 16.0
+ (sim
.gen_ctx
.cave_1_nz
@ -161,7 +165,7 @@ impl<'a> Sampler for ColumnGen<'a> {
- marble * 24.0)
/ 12.0,
),
(alt - CONFIG.sea_level - 0.2 * CONFIG.mountain_scale) / 180.0,
(alt - CONFIG.sea_level - 0.2 * CONFIG.mountain_scale + marble * 48.0) / 100.0,
),
// Beach
((alt - CONFIG.sea_level - 2.0) / 5.0).min(1.0 - river * 2.0),
@ -172,7 +176,9 @@ impl<'a> Sampler for ColumnGen<'a> {
cave_xy,
cave_alt,
rock,
cliff: cliffiness,
cliffs,
cliff_hill,
close_cliffs: sim.gen_ctx.cliff_gen.get(wpos),
temp,
location: sim_chunk.location.as_ref(),
})
@ -192,7 +198,9 @@ pub struct ColumnSample<'a> {
pub cave_xy: f32,
pub cave_alt: f32,
pub rock: f32,
pub cliff: f32,
pub cliffs: bool,
pub cliff_hill: f32,
pub close_cliffs: [(Vec2<i32>, u32); 9],
pub temp: f32,
pub location: Option<&'a Arc<Location>>,
}

View File

@ -19,8 +19,8 @@ use vek::*;
pub const WORLD_SIZE: Vec2<usize> = Vec2 { x: 1024, y: 1024 };
pub(crate) struct GenCtx {
pub turb_x_nz: BasicMulti,
pub turb_y_nz: BasicMulti,
pub turb_x_nz: SuperSimplex,
pub turb_y_nz: SuperSimplex,
pub chaos_nz: RidgedMulti,
pub alt_nz: HybridMulti,
pub hill_nz: SuperSimplex,
@ -36,6 +36,7 @@ pub(crate) struct GenCtx {
pub cave_1_nz: SuperSimplex,
pub tree_gen: StructureGen2d,
pub cliff_gen: StructureGen2d,
}
pub struct WorldSim {
@ -48,8 +49,8 @@ pub struct WorldSim {
impl WorldSim {
pub fn generate(seed: u32) -> Self {
let mut gen_ctx = GenCtx {
turb_x_nz: BasicMulti::new().set_seed(seed + 0),
turb_y_nz: BasicMulti::new().set_seed(seed + 1),
turb_x_nz: SuperSimplex::new().set_seed(seed + 0),
turb_y_nz: SuperSimplex::new().set_seed(seed + 1),
chaos_nz: RidgedMulti::new().set_octaves(7).set_seed(seed + 2),
hill_nz: SuperSimplex::new().set_seed(seed + 3),
alt_nz: HybridMulti::new()
@ -70,6 +71,7 @@ impl WorldSim {
cave_1_nz: SuperSimplex::new().set_seed(seed + 14),
tree_gen: StructureGen2d::new(seed, 32, 24),
cliff_gen: StructureGen2d::new(seed, 80, 64),
};
let mut chunks = Vec::new();
@ -104,7 +106,7 @@ impl WorldSim {
};
this.seed_elements();
this.simulate(200);
this.simulate(0);
this
}
@ -227,7 +229,7 @@ impl WorldSim {
}
}
const Z_TOLERANCE: (f32, f32) = (128.0, 96.0);
const Z_TOLERANCE: (f32, f32) = (64.0, 128.0);
pub struct SimChunk {
pub chaos: f32,
@ -236,7 +238,8 @@ pub struct SimChunk {
pub temp: f32,
pub dryness: f32,
pub rockiness: f32,
pub cliffiness: f32,
pub cliffs: bool,
pub near_cliffs: bool,
pub tree_density: f32,
pub forest_kind: ForestKind,
pub location: Option<Arc<Location>>,
@ -275,7 +278,7 @@ impl SimChunk {
.add(1.0)
.mul(0.5)
.mul(
(gen_ctx.chaos_nz.get((wposf.div(8_000.0)).into_array()) as f32)
(gen_ctx.chaos_nz.get((wposf.div(6_000.0)).into_array()) as f32)
.powf(2.0)
.add(0.5)
.min(1.0),
@ -291,7 +294,7 @@ impl SimChunk {
.add(alt_base.mul(128.0).sin().mul(0.005))
.mul(400.0);
let alt_main = (gen_ctx.alt_nz.get((wposf.div(1_000.0)).into_array()) as f32)
let alt_main = (gen_ctx.alt_nz.get((wposf.div(2_000.0)).into_array()) as f32)
.abs()
.powf(1.7);
@ -310,6 +313,8 @@ impl SimChunk {
let temp = (gen_ctx.temp_nz.get((wposf.div(8192.0)).into_array()) as f32);
let cliff = gen_ctx.cliff_nz.get((wposf.div(2048.0)).into_array()) as f32 + chaos * 0.2;
Self {
chaos,
alt_base,
@ -320,16 +325,12 @@ impl SimChunk {
.sub(0.1)
.mul(1.3)
.max(0.0),
cliffiness: (gen_ctx.cliff_nz.get((wposf.div(2048.0)).into_array()) as f32)
.sub(0.15)
.mul(3.0)
.mul(1.1 - chaos)
.max(0.0)
.min(1.0),
cliffs: cliff > 0.5,
near_cliffs: cliff > 0.4,
tree_density: (gen_ctx.tree_nz.get((wposf.div(1024.0)).into_array()) as f32)
.add(1.0)
.mul(0.5)
.mul(1.2 - chaos * 0.85)
.mul(1.2 - chaos * 0.95)
.add(0.1)
.mul(if alt > CONFIG.sea_level + 5.0 {
1.0
@ -362,7 +363,7 @@ impl SimChunk {
}
pub fn get_max_z(&self) -> f32 {
(self.alt + Z_TOLERANCE.1).max(CONFIG.sea_level + 1.0)
(self.alt + Z_TOLERANCE.1 * if self.near_cliffs { 1.0 } else { 0.5 }).max(CONFIG.sea_level + 2.0)
}
pub fn get_name(&self) -> Option<String> {