Making jungles work.

This commit is contained in:
Joshua Yanovski 2019-08-19 01:52:26 +02:00
parent 680b81a5e6
commit d8c864cf3a
7 changed files with 123 additions and 35 deletions
assets/world/tree/mangroves
world/src

BIN
assets/world/tree/mangroves/4.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/world/tree/mangroves/5.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/world/tree/mangroves/6.vox (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -424,14 +424,23 @@ lazy_static! {
pub static ref MANGROVE_TREES: Vec<Arc<Structure>> = vec![
// oak stumps
assets::load_map("world.tree.mangrove.1", |s: Structure| s
.with_center(Vec3::new(15, 18, 10)))
assets::load_map("world.tree.mangroves.1", |s: Structure| s
.with_center(Vec3::new(18, 18, 8)))
.unwrap(),
assets::load_map("world.tree.mangrove.2", |s: Structure| s
.with_center(Vec3::new(15, 18, 10)))
assets::load_map("world.tree.mangroves.2", |s: Structure| s
.with_center(Vec3::new(16, 17, 7)))
.unwrap(),
assets::load_map("world.tree.mangrove.3", |s: Structure| s
.with_center(Vec3::new(15, 188888888, 10)))
assets::load_map("world.tree.mangroves.3", |s: Structure| s
.with_center(Vec3::new(18, 18, 8)))
.unwrap(),
assets::load_map("world.tree.mangroves.4", |s: Structure| s
.with_center(Vec3::new(18, 16, 8)))
.unwrap(),
assets::load_map("world.tree.mangroves.5", |s: Structure| s
.with_center(Vec3::new(16, 17, 8)))
.unwrap(),
assets::load_map("world.tree.mangroves.6", |s: Structure| s
.with_center(Vec3::new(18, 18, 8)))
.unwrap(),
];

View File

@ -139,6 +139,8 @@ impl<'a> Sampler for ColumnGen<'a> {
let chaos = sim.get_interpolated(wpos, |chunk| chunk.chaos)?;
let temp = sim.get_interpolated(wpos, |chunk| chunk.temp)?;
let dryness = sim.get_interpolated(wpos, |chunk| chunk.dryness)?;
let humidity = sim.get_interpolated(wpos, |chunk| chunk.humidity)?;
let humidity = if temp > CONFIG.desert_temp { CONFIG.desert_hum } else { humidity };
let rockiness = sim.get_interpolated(wpos, |chunk| chunk.rockiness)?;
let tree_density = sim.get_interpolated(wpos, |chunk| chunk.tree_density)?;
let spawn_rate = sim.get_interpolated(wpos, |chunk| chunk.spawn_rate)?;
@ -204,6 +206,7 @@ impl<'a> Sampler for ColumnGen<'a> {
// Colours
let cold_grass = Rgb::new(0.0, 0.49, 0.42);
let warm_grass = Rgb::new(0.03, 0.8, 0.0);
let dark_grass = Rgb::new(0.03, 0.4, 0.0);
let cold_stone = Rgb::new(0.57, 0.67, 0.8);
let warm_stone = Rgb::new(0.77, 0.77, 0.64);
let beach_sand = Rgb::new(0.89, 0.87, 0.64);
@ -218,6 +221,7 @@ impl<'a> Sampler for ColumnGen<'a> {
let cliff = Rgb::lerp(cold_stone, warm_stone, marble);
let grass = Rgb::lerp(cold_grass, warm_grass, marble.powf(1.5));
let moss = Rgb::lerp(warm_grass, dark_grass, marble.powf(1.5));
let sand = Rgb::lerp(beach_sand, desert_sand, marble);
let tropical = Rgb::lerp(
@ -226,7 +230,56 @@ impl<'a> Sampler for ColumnGen<'a> {
marble_small.sub(0.5).mul(0.2).add(0.75).powf(0.667),
);
// Case matrix (for now):
// snow temp, desert humidity => rock
// snow temp, forest humidity => dirt
// snow temp, jungle humidity => snow
// tropical temp, desert humidity => sand
// tropical temp, forest humidity => grass
// tropical temp, jungle humidity => tropical
// desert temp, low altitude, desert humidity => sand
// desert temp, high altitude, desert humidity => rock
// desert temp, low altitude, forest humidity => moss
// desert temp, high altitude, forest humidity => dirt
// desert temp, low altitude, jungle humidity => dark grass
// desert temp, high altitude, jungle humidity => mossy / maybe hot springs / dark grass
// For desert humidity, we are always sand or rock, depending on altitude.
let ground = Rgb::lerp(sand, cliff, alt.sub(CONFIG.mountain_scale * 0.25));
// At forest humidity, we go from dirt to grass to moss depending on temperature.
let ground = Rgb::lerp(
ground,
Rgb::lerp(
Rgb::lerp(
dirt,
grass,
temp.sub(CONFIG.snow_temp)
.sub((marble - 0.5) * 0.05)
.mul(256.0)
),
moss,
temp.sub(CONFIG.tropical_temp).mul(32.0),
),
humidity.sub(CONFIG.desert_hum).mul(16.0)
);
// At jungle humidity, we go from snow to tropical to moss.
let ground = Rgb::lerp(
ground,
Rgb::lerp(
Rgb::lerp(
snow,
tropical,
temp.sub(CONFIG.snow_temp)
.sub((marble - 0.5) * 0.05)
.mul(256.0)
),
moss,
temp.sub(CONFIG.tropical_temp).mul(32.0),
),
humidity.sub(CONFIG.forest_hum)
);
/* let ground = Rgb::lerp(
Rgb::lerp(
snow,
grass,
@ -234,9 +287,9 @@ impl<'a> Sampler for ColumnGen<'a> {
.sub((marble - 0.5) * 0.05)
.mul(256.0),
),
Rgb::lerp(tropical, sand, temp.sub(CONFIG.desert_temp).mul(32.0)),
temp.sub(CONFIG.tropical_temp).mul(16.0),
);
Rgb::lerp(tropical, sand, temp.sub(CONFIG.desert_hum).mul(32.0)),
humidity.sub(CONFIG.desert_temp).mul(16.0),
); */
// Work out if we're on a path or near a town
let dist_to_path = match &sim_chunk.location {

View File

@ -15,7 +15,7 @@ pub const CONFIG: Config = Config {
snow_temp: -0.4,
tropical_temp: 0.25,
desert_temp: 0.45,
desert_hum: 0.1,
desert_hum: 0.3,
forest_hum: 0.4,
jungle_hum: 0.7,
jungle_hum: 0.5,
};

View File

@ -78,7 +78,6 @@ impl WorldSim {
.set_seed(gen_seed()),
temp_nz: SuperSimplex::new().set_seed(gen_seed()),
dry_nz: BasicMulti::new().set_seed(gen_seed()),
humid_nz: Billow::new().set_seed(gen_seed()),
small_nz: BasicMulti::new().set_octaves(2).set_seed(gen_seed()),
rock_nz: HybridMulti::new().set_persistence(0.3).set_seed(gen_seed()),
cliff_nz: HybridMulti::new().set_persistence(0.3).set_seed(gen_seed()),
@ -93,6 +92,10 @@ impl WorldSim {
structure_gen: StructureGen2d::new(gen_seed(), 32, 24),
region_gen: StructureGen2d::new(gen_seed(), 400, 96),
cliff_gen: StructureGen2d::new(gen_seed(), 80, 56),
humid_nz: Billow::new()
// .set_octaves(6)
// .set_persistence(0.5)
.set_seed(gen_seed()),
};
let mut chunks = Vec::new();
@ -404,8 +407,7 @@ impl SimChunk {
.max(0.0)
.min(1.0);
let alt_pre = alt_base
+ (0.0
let alt_pre = (0.0
+ alt_main
+ (gen_ctx.small_nz.get((wposf.div(300.0)).into_array()) as f32)
.mul(alt_main.max(0.25))
@ -414,7 +416,7 @@ impl SimChunk {
.mul(0.5)
.mul(chaos);
let alt = (CONFIG.sea_level + alt_pre.mul(CONFIG.mountain_scale)) * map_edge_factor;
let alt = (CONFIG.sea_level + alt_base + alt_pre.mul(CONFIG.mountain_scale)) * map_edge_factor;
// 0 to 1, hopefully.
let humid_base =
@ -432,14 +434,15 @@ impl SimChunk {
// 1/2 + 1/2 * tanh((x - μ) / (2s))
//
// where x is the random variable (altitude relative to sea level without mountain
// scaling), μ is the altitude where humidity should be at its midpoint (currently set to 1),
// scaling), μ is the altitude where humidity should be at its midpoint (currently set to 0.125),
// and s is the scale parameter proportional to the standard deviation σ of the humidity
// function of altitude (s = √3/π * σ). Currently we also set σ to -1, so we get ~ 68% of
// the variation due to altitude between sea level and 2 * mountain_scale (it is negative
// to make the distribution higher when the altitude is lower).
let humid_alt_sigma = -1.0;
// function of altitude (s = √3/π * σ). Currently we set σ to -0.125, so we get ~ 68% of
// the variation due to altitude between sea level and
// 0.25 * mountain_scale (it is negative to make the distribution higher when the altitude is
// lower).
let humid_alt_sigma = -0.125;
let humid_alt_2s = 3.0f32.sqrt().mul(f32::consts::FRAC_2_PI).mul(humid_alt_sigma);
let humid_alt_mu = 1.0;
let humid_alt_mu = 0.125;
let humid_alt = alt_pre
.sub(humid_alt_mu)
.div(humid_alt_2s)
@ -449,7 +452,7 @@ impl SimChunk {
// Now we just take a (currently) unweighted average of our randomly generated base humidity
// (from scaled to be from 0 to 1) and our randomly generated "base" humidity. We can
// adjust this weighting factor as desired.
let humid_weight = 1.0;
let humid_weight = 3.0;
let humid_alt_weight = 1.0;
let humidity =
humid_base.mul(humid_weight)
@ -458,6 +461,27 @@ impl SimChunk {
let cliff = gen_ctx.cliff_nz.get((wposf.div(2048.0)).into_array()) as f32 + chaos * 0.2;
let tree_density =
(gen_ctx.tree_nz.get((wposf.div(1024.0)).into_array()) as f32)
.mul(1.5)
.add(1.0)
.mul(0.5)
.mul(1.2 - chaos * 0.95)
.add(0.05)
.max(0.0)
.min(1.0)
.mul(0.5)
// Tree density should go (by a lot) with humidity.
.add(humidity.mul(0.5))
// No trees in the ocean (currently), no trees in true deserts.
.mul(if alt > CONFIG.sea_level + 5.0 && humidity > CONFIG.desert_hum {
1.0
} else {
0.0
})
.max(0.0);
Self {
chaos,
alt_base,
@ -474,21 +498,10 @@ impl SimChunk {
&& alt > CONFIG.sea_level + 5.0
&& dryness.abs() > 0.075,
near_cliffs: cliff > 0.25,
tree_density: (gen_ctx.tree_nz.get((wposf.div(1024.0)).into_array()) as f32)
.mul(1.5)
.add(1.0)
.mul(0.5)
.mul(1.2 - chaos * 0.95)
.add(0.05)
// No trees in the ocean (currently), no trees in true deserts.
.mul(if alt > CONFIG.sea_level + 5.0 && humidity > CONFIG.desert_hum {
1.0
} else {
0.0
})
.max(0.0),
tree_density,
forest_kind: if temp > 0.0 {
if temp > CONFIG.desert_temp {
// println!("Any desert: {:?}, altitude: {:?}, humidity: {:?}, tmeperature: {:?}, density: {:?}", wposf, alt, humidity, temp, tree_density);
if humidity > CONFIG.jungle_hum {
// Forests in desert temperatures with extremely high humidity
// should probably be different from palm trees, but we use them
@ -499,10 +512,14 @@ impl SimChunk {
} else {
// Low but not desert humidity, so we should really have some other
// terrain...
if humidity < CONFIG.desert_hum {
// println!("True desert: {:?}, altitude: {:?}, humidity: {:?}, tmeperature: {:?}, density: {:?}", wposf, alt, humidity, temp, tree_density);
}
ForestKind::Savannah
}
} else if temp > CONFIG.tropical_temp {
if humidity > CONFIG.jungle_hum {
// println!("Mangroves: {:?}, altitude: {:?}, humidity: {:?}, tmeperature: {:?}, density: {:?}", wposf, alt, humidity, temp, tree_density);
ForestKind::Mangrove
} else if humidity > CONFIG.forest_hum {
// NOTE: Probably the wrong kind of tree for this climtae.