mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Better humidity, better snow trees
This commit is contained in:
parent
3f02aa5134
commit
71718d9c98
@ -34,6 +34,7 @@ make_case_elim!(
|
||||
WeakRock = 0x11, // Explodable
|
||||
// 0x12 <= x < 0x20 is reserved for future rocks
|
||||
Grass = 0x20, // Note: *not* the same as grass sprites
|
||||
Snow = 0x21,
|
||||
// 0x21 <= x < 0x30 is reserved for future grasses
|
||||
Earth = 0x30,
|
||||
Sand = 0x31,
|
||||
|
@ -4,6 +4,6 @@ pub enum ForestKind {
|
||||
Savannah,
|
||||
Oak,
|
||||
Pine,
|
||||
SnowPine,
|
||||
// SnowPine,
|
||||
Mangrove,
|
||||
}
|
||||
|
@ -733,7 +733,7 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
|
||||
);
|
||||
// Columns near water get a humidity boost
|
||||
let humidity = Lerp::lerp(
|
||||
Lerp::lerp(humidity, 1.0, 0.1),
|
||||
Lerp::lerp(humidity, 1.0, 0.25),
|
||||
humidity,
|
||||
water_dist
|
||||
.map(|water_dist| water_dist / 20.0)
|
||||
@ -879,7 +879,7 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
|
||||
humidity
|
||||
.sub(CONFIG.desert_hum)
|
||||
.div(CONFIG.forest_hum.sub(CONFIG.desert_hum))
|
||||
.mul(1.0),
|
||||
.mul(1.25),
|
||||
);
|
||||
// From forest to jungle humidity, we go from snow to dark grass to grass to
|
||||
// tropics to sand depending on temperature.
|
||||
@ -947,15 +947,17 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
|
||||
.max(-humidity.sub(CONFIG.desert_hum))
|
||||
.mul(16.0)
|
||||
.add((marble_small - 0.5) * 0.5);
|
||||
let (alt, ground, sub_surface_color) = if snow_cover <= 0.5 && alt > water_level {
|
||||
let (alt, ground, sub_surface_color, snow_cover) = if snow_cover <= 0.5 && alt > water_level
|
||||
{
|
||||
// Allow snow cover.
|
||||
(
|
||||
alt + 1.0 - snow_cover.max(0.0),
|
||||
Rgb::lerp(snow, ground, snow_cover),
|
||||
Lerp::lerp(sub_surface_color, ground, alt.sub(basement).mul(0.15)),
|
||||
true,
|
||||
)
|
||||
} else {
|
||||
(alt, ground, sub_surface_color)
|
||||
(alt, ground, sub_surface_color, false)
|
||||
};
|
||||
|
||||
// Make river banks not have grass
|
||||
@ -1024,6 +1026,7 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
|
||||
water_dist,
|
||||
path,
|
||||
cave,
|
||||
snow_cover,
|
||||
|
||||
chunk: sim_chunk,
|
||||
})
|
||||
@ -1052,6 +1055,7 @@ pub struct ColumnSample<'a> {
|
||||
pub water_dist: Option<f32>,
|
||||
pub path: Option<(f32, Vec2<f32>, Path, Vec2<f32>)>,
|
||||
pub cave: Option<(f32, Vec2<f32>, Cave, Vec2<f32>)>,
|
||||
pub snow_cover: bool,
|
||||
|
||||
pub chunk: &'a SimChunk,
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ pub const CONFIG: Config = Config {
|
||||
desert_temp: 0.8,
|
||||
desert_hum: 0.15,
|
||||
forest_hum: 0.5,
|
||||
jungle_hum: 0.85,
|
||||
jungle_hum: 0.75,
|
||||
rainfall_chunk_rate: 1.0 / (512.0 * 32.0 * 32.0),
|
||||
river_roughness: 0.06125,
|
||||
river_max_width: 2.0,
|
||||
|
@ -6,7 +6,7 @@ use crate::{
|
||||
Canvas, CONFIG,
|
||||
};
|
||||
use common::{
|
||||
terrain::{structure::Structure, Block},
|
||||
terrain::{structure::Structure, Block, BlockKind},
|
||||
vol::ReadVol,
|
||||
};
|
||||
use lazy_static::lazy_static;
|
||||
@ -18,7 +18,7 @@ lazy_static! {
|
||||
pub static ref OAK_STUMPS: Vec<Arc<Structure>> = Structure::load_group("oak_stumps");
|
||||
pub static ref PINES: Vec<Arc<Structure>> = Structure::load_group("pines");
|
||||
pub static ref PALMS: Vec<Arc<Structure>> = Structure::load_group("palms");
|
||||
pub static ref SNOW_PINES: Vec<Arc<Structure>> = Structure::load_group("snow_pines");
|
||||
// pub static ref SNOW_PINES: Vec<Arc<Structure>> = Structure::load_group("snow_pines");
|
||||
pub static ref ACACIAS: Vec<Arc<Structure>> = Structure::load_group("acacias");
|
||||
pub static ref FRUIT_TREES: Vec<Arc<Structure>> = Structure::load_group("fruit_trees");
|
||||
pub static ref BIRCHES: Vec<Arc<Structure>> = Structure::load_group("birch");
|
||||
@ -77,7 +77,7 @@ pub fn apply_trees_to(canvas: &mut Canvas) {
|
||||
ForestKind::Oak if QUIRKY_RAND.get(seed) % 14 == 7 => &BIRCHES,
|
||||
ForestKind::Oak => &OAKS,
|
||||
ForestKind::Pine => &PINES,
|
||||
ForestKind::SnowPine => &SNOW_PINES,
|
||||
// ForestKind::SnowPine => &SNOW_PINES,
|
||||
ForestKind::Mangrove => &MANGROVE_TREES,
|
||||
}
|
||||
};
|
||||
@ -96,7 +96,8 @@ pub fn apply_trees_to(canvas: &mut Canvas) {
|
||||
};
|
||||
|
||||
let bounds = tree.model.get_bounds();
|
||||
for z in bounds.min.z..bounds.max.z {
|
||||
let mut is_top = true;
|
||||
for z in (bounds.min.z..bounds.max.z).rev() {
|
||||
let wpos = Vec3::new(wpos2d.x, wpos2d.y, tree.pos.z + z);
|
||||
let model_pos = Vec3::from(
|
||||
(wpos - tree.pos)
|
||||
@ -121,7 +122,19 @@ pub fn apply_trees_to(canvas: &mut Canvas) {
|
||||
col,
|
||||
Block::air,
|
||||
)
|
||||
.map(|block| canvas.set(wpos, block));
|
||||
.map(|block| {
|
||||
if is_top && col.snow_cover && block.kind() == BlockKind::Leaves {
|
||||
canvas.set(
|
||||
wpos + Vec3::unit_z(),
|
||||
Block::new(BlockKind::Snow, Rgb::new(210, 210, 255)),
|
||||
);
|
||||
}
|
||||
canvas.set(wpos, block);
|
||||
is_top = false;
|
||||
})
|
||||
.unwrap_or_else(|| {
|
||||
is_top = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -2056,11 +2056,6 @@ impl SimChunk {
|
||||
// Even less granular--if this matters we can make the sign affect the quantity slightly.
|
||||
let abs_lat_uniform = latitude_uniform.abs(); */
|
||||
|
||||
// Take the weighted average of our randomly generated base humidity, and the
|
||||
// calculated water flux over this point in order to compute humidity.
|
||||
const HUMID_WEIGHTS: [f32; 2] = [2.0, 1.0];
|
||||
let humidity = cdf_irwin_hall(&HUMID_WEIGHTS, [humid_uniform, flux_uniform]);
|
||||
|
||||
// We also correlate temperature negatively with altitude and absolute latitude,
|
||||
// using different weighting than we use for humidity.
|
||||
const TEMP_WEIGHTS: [f32; 2] = [/* 1.5, */ 1.0, 2.0];
|
||||
@ -2075,6 +2070,18 @@ impl SimChunk {
|
||||
.sub(0.5)
|
||||
.mul(2.0);
|
||||
|
||||
// Take the weighted average of our randomly generated base humidity, and the
|
||||
// calculated water flux over this point in order to compute humidity.
|
||||
const HUMID_WEIGHTS: [f32; 3] = [1.0, 1.0, 0.75];
|
||||
let humidity = cdf_irwin_hall(&HUMID_WEIGHTS, [humid_uniform, flux_uniform, 1.0]);
|
||||
// Moisture evaporates more in hot places
|
||||
let humidity = humidity
|
||||
* (1.0
|
||||
- (temp - CONFIG.tropical_temp)
|
||||
.max(0.0)
|
||||
.div(1.0 - CONFIG.tropical_temp))
|
||||
.max(0.0);
|
||||
|
||||
let mut alt = CONFIG.sea_level.add(alt_pre);
|
||||
let basement = CONFIG.sea_level.add(basement_pre);
|
||||
let water_alt = CONFIG.sea_level.add(water_alt_pre);
|
||||
@ -2138,7 +2145,6 @@ impl SimChunk {
|
||||
.mul(1.5)
|
||||
.add(1.0)
|
||||
.mul(0.5)
|
||||
.mul(1.2 - chaos as f64 * 0.95)
|
||||
.add(0.05)
|
||||
.max(0.0)
|
||||
.min(1.0);
|
||||
@ -2149,14 +2155,17 @@ impl SimChunk {
|
||||
1.0
|
||||
} else {
|
||||
// Weighted logit sum.
|
||||
logistic_cdf(logit(humidity as f64) + 0.5 * logit(tree_density))
|
||||
logistic_cdf(logit(tree_density))
|
||||
}
|
||||
// rescale to (-0.95, 0.95)
|
||||
.sub(0.5)
|
||||
.mul(0.95)
|
||||
.add(0.5)
|
||||
* (1.0 - temp as f64)
|
||||
} as f32;
|
||||
const MIN_TREE_HUM: f32 = 0.05;
|
||||
// Tree density increases exponentially with humidity...
|
||||
let tree_density = (tree_density * (humidity - MIN_TREE_HUM).max(0.0).mul(1.0 + MIN_TREE_HUM) / temp.max(0.75))
|
||||
// ...but is ultimately limited by available sunlight (and our tree generation system)
|
||||
.min(1.0);
|
||||
|
||||
// Sand dunes (formed over a short period of time)
|
||||
let alt = alt
|
||||
@ -2191,23 +2200,74 @@ impl SimChunk {
|
||||
0.0
|
||||
},
|
||||
tree_density,
|
||||
forest_kind: if temp > CONFIG.temperate_temp {
|
||||
if temp > CONFIG.desert_temp {
|
||||
if humidity > CONFIG.jungle_hum {
|
||||
forest_kind: {
|
||||
// Whittaker diagram
|
||||
let candidates = [
|
||||
// A smaller prevalence means that the range of values this tree appears in
|
||||
// will shrink compared to neighbouring trees in the
|
||||
// topology of the Whittaker diagram.
|
||||
// Humidity, temperature, near_water, each with prevalence
|
||||
(
|
||||
ForestKind::Palm,
|
||||
(CONFIG.desert_hum, 1.5),
|
||||
(CONFIG.tropical_temp, 0.5),
|
||||
(1.0, 2.0),
|
||||
),
|
||||
(
|
||||
ForestKind::Savannah,
|
||||
(CONFIG.desert_hum, 1.5),
|
||||
(CONFIG.tropical_temp, 1.0),
|
||||
(0.0, 1.0),
|
||||
),
|
||||
(
|
||||
ForestKind::Oak,
|
||||
(CONFIG.forest_hum, 1.5),
|
||||
(CONFIG.temperate_temp, 1.5),
|
||||
(0.0, 1.0),
|
||||
),
|
||||
(
|
||||
ForestKind::Mangrove,
|
||||
(CONFIG.jungle_hum, 0.5),
|
||||
(CONFIG.tropical_temp, 0.5),
|
||||
(0.0, 1.0),
|
||||
),
|
||||
(
|
||||
ForestKind::Pine,
|
||||
(CONFIG.desert_hum, 2.0),
|
||||
(CONFIG.snow_temp, 2.5),
|
||||
(0.0, 1.0),
|
||||
),
|
||||
];
|
||||
|
||||
candidates
|
||||
.iter()
|
||||
.min_by_key(|(_, (h, h_prev), (t, t_prev), (w, w_prev))| {
|
||||
(Vec3::new(
|
||||
(*h - humidity) / *h_prev,
|
||||
(*t - temp) / *t_prev,
|
||||
(*w - if river.near_water() { 1.0 } else { 0.0 }) / *w_prev,
|
||||
)
|
||||
.map(|e| e * e)
|
||||
.sum()
|
||||
* 10000.0) as i32
|
||||
})
|
||||
.map(|c| c.0)
|
||||
.unwrap() // Can't fail
|
||||
},
|
||||
/*
|
||||
if temp > CONFIG.temperate_temp {
|
||||
if temp > CONFIG.tropical_temp {
|
||||
if humidity > CONFIG.desert_hum && river.near_water() {
|
||||
// Forests in desert temperatures with extremely high humidity
|
||||
// should probably be different from palm trees, but we use them
|
||||
// for now.
|
||||
ForestKind::Palm
|
||||
} else if humidity > CONFIG.forest_hum {
|
||||
ForestKind::Palm
|
||||
} else if humidity > CONFIG.desert_hum {
|
||||
} else {
|
||||
// Low but not desert humidity, so we should really have some other
|
||||
// terrain...
|
||||
ForestKind::Savannah
|
||||
} else {
|
||||
ForestKind::Savannah
|
||||
}
|
||||
} else if temp > CONFIG.tropical_temp {
|
||||
} else if temp > CONFIG.forest_hum {
|
||||
if humidity > CONFIG.jungle_hum {
|
||||
if tree_density > 0.0 {
|
||||
// println!("Mangrove: {:?}", wposf);
|
||||
@ -2250,6 +2310,7 @@ impl SimChunk {
|
||||
ForestKind::Pine
|
||||
}
|
||||
},
|
||||
*/
|
||||
spawn_rate: 1.0,
|
||||
river,
|
||||
warp_factor: 1.0,
|
||||
|
Loading…
Reference in New Issue
Block a user