Added ice to cold water

This commit is contained in:
Joshua Barretto 2021-12-08 00:47:08 +00:00
parent 78f76dde83
commit a2a3a20aad
5 changed files with 89 additions and 48 deletions

View File

@ -299,6 +299,11 @@ pub struct MapConfig<'a> {
///
/// Defaults to true.
pub is_water: bool,
/// When `is_water` is true, controls whether an ice layer should appear on
/// that water.
///
/// Defaults to true.
pub is_ice: bool,
/// If true, 3D lighting and shading are turned on. Otherwise, a plain
/// altitude map is used.
///
@ -403,6 +408,7 @@ impl<'a> MapConfig<'a> {
is_basement: false,
is_water: true,
is_ice: true,
is_shaded: true,
is_temperature: false,
is_humidity: false,
@ -581,13 +587,16 @@ impl<'a> MapConfig<'a> {
let g_water = 32.0 * water_color_factor;
let b_water = 64.0 * water_color_factor;
if has_river {
let water_rgb = Rgb::new(0, ((g_water) * 1.0) as u8, ((b_water) * 1.0) as u8)
.map(|e| e as f64 / 255.0);
rgb = water_rgb;
k_s = Rgb::new(1.0, 1.0, 1.0);
k_d = water_rgb;
k_a = water_rgb;
alpha = 0.255;
// Rudimentary ice check
if !rgb.map(|e| e > 0.6).reduce_and() {
let water_rgb = Rgb::new(0, ((g_water) * 1.0) as u8, ((b_water) * 1.0) as u8)
.map(|e| e as f64 / 255.0);
rgb = water_rgb;
k_s = Rgb::new(1.0, 1.0, 1.0);
k_d = water_rgb;
k_a = water_rgb;
alpha = 0.255;
}
}
let downhill_alt = sample_wpos(downhill_wpos);

View File

@ -177,6 +177,7 @@ fn main() {
is_basement,
is_water,
is_ice: true,
is_shaded,
is_temperature,
is_humidity,

View File

@ -54,7 +54,7 @@ impl<'a> BlockGen<'a> {
// Main sample
let sample = column_gen.get((wpos, index, calendar))?;
Some(ZCache { sample })
Some(ZCache { sample, calendar })
}
pub fn get_with_z_cache(&mut self, wpos: Vec3<i32>, z_cache: Option<&ZCache>) -> Option<Block> {
@ -74,8 +74,9 @@ impl<'a> BlockGen<'a> {
//tree_density,
//forest_kind,
//close_structures,
// marble,
// marble_small,
marble,
marble_mid,
marble_small,
rock,
// temp,
// humidity,
@ -83,6 +84,8 @@ impl<'a> BlockGen<'a> {
snow_cover,
cliff_offset,
cliff_height,
// water_vel,
ice_depth,
..
} = sample;
@ -204,8 +207,12 @@ impl<'a> BlockGen<'a> {
}
})
.or_else(|| {
let over_water = height < water_height;
// Water
if (wposf.z as f32) < water_height {
if over_water && (wposf.z as f32 - water_height).abs() < ice_depth {
// TODO: Ice block
Some(Block::new(BlockKind::WeakRock, Rgb::new(200, 225, 255)))
} else if (wposf.z as f32) < water_height {
// Ocean
Some(water)
} else {
@ -217,6 +224,7 @@ impl<'a> BlockGen<'a> {
pub struct ZCache<'a> {
pub sample: ColumnSample<'a>,
pub calendar: Option<&'a Calendar>,
}
impl<'a> ZCache<'a> {
@ -232,7 +240,7 @@ impl<'a> ZCache<'a> {
let ground_max = self.sample.alt + warp + rocks + 2.0;
let max = ground_max.max(self.sample.water_level + 2.0);
let max = ground_max.max(self.sample.water_level + 2.0 + self.sample.ice_depth);
(min, max)
}

View File

@ -91,6 +91,7 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
wpos,
|chunk| if chunk.river.near_water() { 1.0 } else { 0.0 },
)?;
let water_vel = sim.get_interpolated(wpos, |chunk| chunk.river.velocity)?;
let alt = sim.get_interpolated_monotone(wpos, |chunk| chunk.alt)?;
let surface_veg = sim.get_interpolated_monotone(wpos, |chunk| chunk.surface_veg)?;
let sim_chunk = sim.get(chunk_pos)?;
@ -1081,7 +1082,7 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
// Snow covering
let thematic_snow = calendar.map_or(false, |c| c.is_event(CalendarEvent::Christmas));
let snow_cover = temp
let snow_factor = temp
.sub(if thematic_snow {
CONFIG.tropical_temp
} else {
@ -1092,17 +1093,17 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
.add(((marble - 0.5) / 0.5) * 0.5)
.add(((marble_mid - 0.5) / 0.5) * 0.25)
.add(((marble_small - 0.5) / 0.5) * 0.175);
let (alt, ground, sub_surface_color) = if snow_cover <= 0.0 && alt > water_level {
let (alt, ground, sub_surface_color) = if snow_factor <= 0.0 && alt > water_level {
// Allow snow cover.
(
alt + 1.0 - snow_cover.max(0.0),
Rgb::lerp(snow, ground, snow_cover),
alt + 1.0 - snow_factor.max(0.0),
Rgb::lerp(snow, ground, snow_factor),
Lerp::lerp(sub_surface_color, ground, alt.sub(basement).mul(0.15)),
)
} else {
(alt, ground, sub_surface_color)
};
let snow_cover = snow_cover <= 0.0;
let snow_cover = snow_factor <= 0.0;
// Make river banks not have grass
let ground = water_dist
@ -1116,6 +1117,16 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
let path = sim.get_nearest_path(wpos);
let cave = sim.get_nearest_cave(wpos);
let ice_depth = if snow_factor < -0.25
&& water_vel.magnitude_squared() < (0.1f32 + marble_mid * 0.2).powi(2)
{
((1.0 - Lerp::lerp(marble, Lerp::lerp(marble_mid, marble_small, 0.25), 0.5)) * 5.0
- 1.5)
.max(0.0)
} else {
0.0
};
Some(ColumnSample {
alt,
riverless_alt,
@ -1149,6 +1160,7 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
},
forest_kind: sim_chunk.forest_kind,
marble,
marble_mid,
marble_small,
rock,
temp,
@ -1162,6 +1174,8 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
snow_cover,
cliff_offset,
cliff_height,
water_vel,
ice_depth,
chunk: sim_chunk,
})
@ -1181,6 +1195,7 @@ pub struct ColumnSample<'a> {
pub tree_density: f32,
pub forest_kind: ForestKind,
pub marble: f32,
pub marble_mid: f32,
pub marble_small: f32,
pub rock: f32,
pub temp: f32,
@ -1194,6 +1209,8 @@ pub struct ColumnSample<'a> {
pub snow_cover: bool,
pub cliff_offset: f32,
pub cliff_height: f32,
pub water_vel: Vec3<f32>,
pub ice_depth: f32,
pub chunk: &'a SimChunk,
}

View File

@ -81,6 +81,7 @@ pub fn sample_pos(
is_basement,
is_water,
is_ice,
is_shaded,
is_temperature,
is_humidity,
@ -133,7 +134,7 @@ pub fn sample_pos(
let humidity = humidity.min(1.0).max(0.0);
let temperature = temperature.min(1.0).max(-1.0) * 0.5 + 0.5;
let wpos = pos * TerrainChunkSize::RECT_SIZE.map(|e| e as i32);
let column_rgb_alt = samples
let column_data = samples
.and_then(|samples| {
chunk_idx
.and_then(|chunk_idx| samples.get(chunk_idx))
@ -162,14 +163,14 @@ pub fn sample_pos(
.map(|e| e as f64)
};
(rgb, alt)
(rgb, alt, sample.ice_depth)
});
let downhill_wpos = downhill.unwrap_or(wpos + TerrainChunkSize::RECT_SIZE.map(|e| e as i32));
let alt = if is_basement {
basement
} else {
column_rgb_alt.map_or(alt, |(_, alt)| alt)
column_data.map_or(alt, |(_, alt, _)| alt)
};
let true_water_alt = (alt.max(water_alt) as f64 - focus.z) / gain as f64;
@ -189,7 +190,7 @@ pub fn sample_pos(
if is_shaded { 1.0 } else { alt },
if is_shaded || is_humidity { 1.0 } else { 0.0 },
);
let column_rgb = column_rgb_alt.map(|(rgb, _)| rgb).unwrap_or(default_rgb);
let column_rgb = column_data.map(|(rgb, _, _)| rgb).unwrap_or(default_rgb);
let mut connections = [None; 8];
let mut has_connections = false;
// TODO: Support non-river connections.
@ -213,33 +214,38 @@ pub fn sample_pos(
});
});
};
let rgb = match (river_kind, (is_water, true_alt >= true_sea_level)) {
(_, (false, _)) | (None, (_, true)) | (Some(RiverKind::River { .. }), _) => {
let (r, g, b) = (
(column_rgb.r
* if is_temperature {
temperature as f64
} else {
column_rgb.r
})
.sqrt(),
column_rgb.g,
(column_rgb.b
* if is_humidity {
humidity as f64
} else {
column_rgb.b
})
.sqrt(),
);
Rgb::new((r * 255.0) as u8, (g * 255.0) as u8, (b * 255.0) as u8)
},
(None | Some(RiverKind::Lake { .. } | RiverKind::Ocean), _) => Rgb::new(
0,
((g_water - water_depth * g_water) * 1.0) as u8,
((b_water - water_depth * b_water) * 1.0) as u8,
),
};
let rgb =
if is_water && is_ice && column_data.map_or(false, |(_, _, ice_depth)| ice_depth > 0.0) {
Rgb::new(200, 225, 255)
} else {
match (river_kind, (is_water, true_alt >= true_sea_level)) {
(_, (false, _)) | (None, (_, true)) | (Some(RiverKind::River { .. }), _) => {
let (r, g, b) = (
(column_rgb.r
* if is_temperature {
temperature as f64
} else {
column_rgb.r
})
.sqrt(),
column_rgb.g,
(column_rgb.b
* if is_humidity {
humidity as f64
} else {
column_rgb.b
})
.sqrt(),
);
Rgb::new((r * 255.0) as u8, (g * 255.0) as u8, (b * 255.0) as u8)
},
(None | Some(RiverKind::Lake { .. } | RiverKind::Ocean), _) => Rgb::new(
0,
((g_water - water_depth * g_water) * 1.0) as u8,
((b_water - water_depth * b_water) * 1.0) as u8,
),
}
};
// TODO: Make principled.
let rgb = if is_path {
Rgb::new(0x37, 0x29, 0x23)