mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Fixed water light extinction
This commit is contained in:
parent
96e23ae2d4
commit
f13a8a643b
@ -204,7 +204,7 @@ void main() {
|
|||||||
const float R_s2s1 = pow((1.0 - 1.3325) / (1.0 + 1.3325), 2);
|
const float R_s2s1 = pow((1.0 - 1.3325) / (1.0 + 1.3325), 2);
|
||||||
const float R_s1s2 = pow((1.3325 - 1.0) / (1.3325 + 1.0), 2);
|
const float R_s1s2 = pow((1.3325 - 1.0) / (1.3325 + 1.0), 2);
|
||||||
// float faces_fluid = faces_fluid && f_pos.z <= floor(f_alt);
|
// float faces_fluid = faces_fluid && f_pos.z <= floor(f_alt);
|
||||||
float fluid_alt = max(f_pos.z + 1, floor(f_alt));
|
float fluid_alt = max(f_pos.z + 1, floor(f_alt + 1));
|
||||||
float R_s = /*(f_pos.z < f_alt)*/faces_fluid /*&& f_pos.z <= fluid_alt*/ ? mix(R_s2s1 * R_s1s0, R_s1s0, medium.x) : mix(R_s2s0, R_s1s2 * R_s2s0, medium.x);
|
float R_s = /*(f_pos.z < f_alt)*/faces_fluid /*&& f_pos.z <= fluid_alt*/ ? mix(R_s2s1 * R_s1s0, R_s1s0, medium.x) : mix(R_s2s0, R_s1s2 * R_s2s0, medium.x);
|
||||||
|
|
||||||
// vec3 surf_color = /*srgb_to_linear*/(f_col);
|
// vec3 surf_color = /*srgb_to_linear*/(f_col);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
all::ForestKind,
|
all::ForestKind,
|
||||||
sim::{local_cells, Cave, Path, RiverKind, SimChunk, WorldSim},
|
sim::{local_cells, Cave, Path, RiverKind, SimChunk, WorldSim},
|
||||||
util::Sampler,
|
util::{RandomField, Sampler},
|
||||||
IndexRef, CONFIG,
|
IndexRef, CONFIG,
|
||||||
};
|
};
|
||||||
use common::{
|
use common::{
|
||||||
@ -106,112 +106,171 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
|
|||||||
|
|
||||||
let gradient = sim.get_gradient_approx(chunk_pos);
|
let gradient = sim.get_gradient_approx(chunk_pos);
|
||||||
|
|
||||||
let lake_width = (TerrainChunkSize::RECT_SIZE.x as f64 * (2.0f64.sqrt())) + 5.0;
|
let lake_width = (TerrainChunkSize::RECT_SIZE.x as f64 * 2.0f64.sqrt()) + 6.0;
|
||||||
let neighbor_river_data = neighbor_river_data.map(|(posj, chunkj, river)| {
|
let neighbor_river_data = neighbor_river_data
|
||||||
let kind = match river.river_kind {
|
.map(|(posj, chunkj, river)| {
|
||||||
Some(kind) => kind,
|
let kind = match river.river_kind {
|
||||||
None => {
|
Some(kind) => kind,
|
||||||
return (posj, chunkj, river, None);
|
None => {
|
||||||
},
|
return (posj, chunkj, river, None);
|
||||||
};
|
},
|
||||||
let downhill_pos = if let Some(pos) = chunkj.downhill {
|
};
|
||||||
pos
|
let downhill_pos = if let Some(pos) = chunkj.downhill {
|
||||||
} else {
|
pos
|
||||||
match kind {
|
} else {
|
||||||
|
match kind {
|
||||||
|
RiverKind::River { .. } => {
|
||||||
|
error!(?river, ?posj, "What?");
|
||||||
|
panic!("How can a river have no downhill?");
|
||||||
|
},
|
||||||
|
RiverKind::Lake { .. } => {
|
||||||
|
return (posj, chunkj, river, None);
|
||||||
|
},
|
||||||
|
RiverKind::Ocean => posj,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let downhill_wpos = downhill_pos.map(|e| e as f64);
|
||||||
|
let downhill_pos = downhill_pos.map2(TerrainChunkSize::RECT_SIZE, |e, sz: u32| {
|
||||||
|
e.div_euclid(sz as i32)
|
||||||
|
});
|
||||||
|
let neighbor_wpos = posj.map(|e| e as f64) * neighbor_coef + neighbor_coef * 0.5;
|
||||||
|
let direction = neighbor_wpos - downhill_wpos;
|
||||||
|
let river_width_min = if let RiverKind::River { cross_section } = kind {
|
||||||
|
cross_section.x as f64
|
||||||
|
} else {
|
||||||
|
lake_width
|
||||||
|
};
|
||||||
|
let downhill_chunk = sim.get(downhill_pos).expect("How can this not work?");
|
||||||
|
let coeffs = river_spline_coeffs(
|
||||||
|
neighbor_wpos,
|
||||||
|
chunkj.river.spline_derivative,
|
||||||
|
downhill_wpos,
|
||||||
|
);
|
||||||
|
let (direction, coeffs, downhill_chunk, river_t, river_pos, river_dist) = match kind
|
||||||
|
{
|
||||||
RiverKind::River { .. } => {
|
RiverKind::River { .. } => {
|
||||||
error!(?river, ?posj, "What?");
|
if let Some((t, pt, dist)) = quadratic_nearest_point(
|
||||||
panic!("How can a river have no downhill?");
|
&coeffs,
|
||||||
},
|
wposf,
|
||||||
RiverKind::Lake { .. } => {
|
Vec2::new(neighbor_wpos, downhill_wpos),
|
||||||
return (posj, chunkj, river, None);
|
) {
|
||||||
},
|
let (t, pt, dist) = if dist > wposf.distance_squared(neighbor_wpos) {
|
||||||
RiverKind::Ocean => posj,
|
(0.0, neighbor_wpos, wposf.distance_squared(neighbor_wpos))
|
||||||
}
|
} else if dist > wposf.distance_squared(downhill_wpos) {
|
||||||
};
|
(1.0, downhill_wpos, wposf.distance_squared(downhill_wpos))
|
||||||
let downhill_wpos = downhill_pos.map(|e| e as f64);
|
} else {
|
||||||
let downhill_pos = downhill_pos.map2(TerrainChunkSize::RECT_SIZE, |e, sz: u32| {
|
(t, pt, dist)
|
||||||
e.div_euclid(sz as i32)
|
};
|
||||||
});
|
(direction, coeffs, downhill_chunk, t, pt, dist.sqrt())
|
||||||
let neighbor_wpos = posj.map(|e| e as f64) * neighbor_coef + neighbor_coef * 0.5;
|
|
||||||
let direction = neighbor_wpos - downhill_wpos;
|
|
||||||
let river_width_min = if let RiverKind::River { cross_section } = kind {
|
|
||||||
cross_section.x as f64
|
|
||||||
} else {
|
|
||||||
lake_width
|
|
||||||
};
|
|
||||||
let downhill_chunk = sim.get(downhill_pos).expect("How can this not work?");
|
|
||||||
let coeffs =
|
|
||||||
river_spline_coeffs(neighbor_wpos, chunkj.river.spline_derivative, downhill_wpos);
|
|
||||||
let (direction, coeffs, downhill_chunk, river_t, river_pos, river_dist) = match kind {
|
|
||||||
RiverKind::River { .. } => {
|
|
||||||
if let Some((t, pt, dist)) = quadratic_nearest_point(
|
|
||||||
&coeffs,
|
|
||||||
wposf,
|
|
||||||
Vec2::new(neighbor_wpos, downhill_wpos),
|
|
||||||
) {
|
|
||||||
let (t, pt, dist) = if dist > wposf.distance_squared(neighbor_wpos) {
|
|
||||||
(0.0, neighbor_wpos, wposf.distance_squared(neighbor_wpos))
|
|
||||||
} else if dist > wposf.distance_squared(downhill_wpos) {
|
|
||||||
(1.0, downhill_wpos, wposf.distance_squared(downhill_wpos))
|
|
||||||
} else {
|
} else {
|
||||||
(t, pt, dist)
|
let ndist = wposf.distance_squared(neighbor_wpos);
|
||||||
};
|
let ddist = wposf.distance_squared(downhill_wpos);
|
||||||
(direction, coeffs, downhill_chunk, t, pt, dist.sqrt())
|
let (closest_pos, closest_dist, closest_t) = if ndist <= ddist {
|
||||||
} else {
|
(neighbor_wpos, ndist, 0.0)
|
||||||
let ndist = wposf.distance_squared(neighbor_wpos);
|
} else {
|
||||||
let ddist = wposf.distance_squared(downhill_wpos);
|
(downhill_wpos, ddist, 1.0)
|
||||||
let (closest_pos, closest_dist, closest_t) = if ndist <= ddist {
|
};
|
||||||
(neighbor_wpos, ndist, 0.0)
|
(
|
||||||
|
direction,
|
||||||
|
coeffs,
|
||||||
|
downhill_chunk,
|
||||||
|
closest_t,
|
||||||
|
closest_pos,
|
||||||
|
closest_dist.sqrt(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
RiverKind::Lake { neighbor_pass_pos } => {
|
||||||
|
let pass_dist = neighbor_pass_pos
|
||||||
|
.map2(
|
||||||
|
neighbor_wpos
|
||||||
|
.map2(TerrainChunkSize::RECT_SIZE, |f, g| (f as i32, g as i32)),
|
||||||
|
|e, (f, g)| ((e - f) / g).abs(),
|
||||||
|
)
|
||||||
|
.reduce_partial_max();
|
||||||
|
let spline_derivative = river.spline_derivative;
|
||||||
|
let neighbor_pass_pos = if pass_dist <= 1 {
|
||||||
|
neighbor_pass_pos
|
||||||
} else {
|
} else {
|
||||||
(downhill_wpos, ddist, 1.0)
|
downhill_wpos.map(|e| e as i32)
|
||||||
};
|
};
|
||||||
(
|
let pass_dist = neighbor_pass_pos
|
||||||
direction,
|
.map2(
|
||||||
coeffs,
|
neighbor_wpos
|
||||||
downhill_chunk,
|
.map2(TerrainChunkSize::RECT_SIZE, |f, g| (f as i32, g as i32)),
|
||||||
closest_t,
|
|e, (f, g)| ((e - f) / g).abs(),
|
||||||
closest_pos,
|
)
|
||||||
closest_dist.sqrt(),
|
.reduce_partial_max();
|
||||||
)
|
if pass_dist > 1 {
|
||||||
}
|
return (posj, chunkj, river, None);
|
||||||
},
|
}
|
||||||
RiverKind::Lake { neighbor_pass_pos } => {
|
let neighbor_pass_wpos =
|
||||||
let pass_dist = neighbor_pass_pos
|
neighbor_pass_pos.map(|e| e as f64) + neighbor_coef * 0.5;
|
||||||
.map2(
|
let neighbor_pass_pos = neighbor_pass_pos
|
||||||
neighbor_wpos
|
.map2(TerrainChunkSize::RECT_SIZE, |e, sz: u32| e / sz as i32);
|
||||||
.map2(TerrainChunkSize::RECT_SIZE, |f, g| (f as i32, g as i32)),
|
let coeffs = river_spline_coeffs(
|
||||||
|e, (f, g)| ((e - f) / g).abs(),
|
neighbor_wpos,
|
||||||
)
|
spline_derivative,
|
||||||
.reduce_partial_max();
|
neighbor_pass_wpos,
|
||||||
let spline_derivative = river.spline_derivative;
|
);
|
||||||
let neighbor_pass_pos = if pass_dist <= 1 {
|
let direction = neighbor_wpos - neighbor_pass_wpos;
|
||||||
neighbor_pass_pos
|
|
||||||
} else {
|
|
||||||
downhill_wpos.map(|e| e as i32)
|
|
||||||
};
|
|
||||||
let pass_dist = neighbor_pass_pos
|
|
||||||
.map2(
|
|
||||||
neighbor_wpos
|
|
||||||
.map2(TerrainChunkSize::RECT_SIZE, |f, g| (f as i32, g as i32)),
|
|
||||||
|e, (f, g)| ((e - f) / g).abs(),
|
|
||||||
)
|
|
||||||
.reduce_partial_max();
|
|
||||||
if pass_dist > 1 {
|
|
||||||
return (posj, chunkj, river, None);
|
|
||||||
}
|
|
||||||
let neighbor_pass_wpos =
|
|
||||||
neighbor_pass_pos.map(|e| e as f64) + neighbor_coef * 0.5;
|
|
||||||
let neighbor_pass_pos = neighbor_pass_pos
|
|
||||||
.map2(TerrainChunkSize::RECT_SIZE, |e, sz: u32| e / sz as i32);
|
|
||||||
let coeffs =
|
|
||||||
river_spline_coeffs(neighbor_wpos, spline_derivative, neighbor_pass_wpos);
|
|
||||||
let direction = neighbor_wpos - neighbor_pass_wpos;
|
|
||||||
|
|
||||||
// Lakes get a special distance function to avoid cookie-cutter edges
|
// Lakes get a special distance function to avoid cookie-cutter edges
|
||||||
if matches!(
|
if matches!(
|
||||||
downhill_chunk.river.river_kind,
|
downhill_chunk.river.river_kind,
|
||||||
Some(RiverKind::Lake { .. } | RiverKind::Ocean)
|
Some(RiverKind::Lake { .. } | RiverKind::Ocean)
|
||||||
) {
|
) {
|
||||||
|
let water_chunk = posj.map(|e| e as f64);
|
||||||
|
let lake_width_noise = sim
|
||||||
|
.gen_ctx
|
||||||
|
.small_nz
|
||||||
|
.get((wposf.map(|e| e as f64).div(32.0)).into_array());
|
||||||
|
let water_aabr = Aabr {
|
||||||
|
min: water_chunk * neighbor_coef + 4.0 - lake_width_noise * 8.0,
|
||||||
|
max: (water_chunk + 1.0) * neighbor_coef - 4.0
|
||||||
|
+ lake_width_noise * 8.0,
|
||||||
|
};
|
||||||
|
let pos = water_aabr.projected_point(wposf);
|
||||||
|
(
|
||||||
|
direction,
|
||||||
|
coeffs,
|
||||||
|
sim.get(neighbor_pass_pos).expect("Must already work"),
|
||||||
|
0.5,
|
||||||
|
pos,
|
||||||
|
pos.distance(wposf),
|
||||||
|
)
|
||||||
|
} else if let Some((t, pt, dist)) = quadratic_nearest_point(
|
||||||
|
&coeffs,
|
||||||
|
wposf,
|
||||||
|
Vec2::new(neighbor_wpos, neighbor_pass_wpos),
|
||||||
|
) {
|
||||||
|
(
|
||||||
|
direction,
|
||||||
|
coeffs,
|
||||||
|
sim.get(neighbor_pass_pos).expect("Must already work"),
|
||||||
|
t,
|
||||||
|
pt,
|
||||||
|
dist.sqrt(),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
let ndist = wposf.distance_squared(neighbor_wpos);
|
||||||
|
/* let ddist = wposf.distance_squared(neighbor_pass_wpos); */
|
||||||
|
let (closest_pos, closest_dist, closest_t) = /*if ndist <= ddist */ {
|
||||||
|
(neighbor_wpos, ndist, 0.0)
|
||||||
|
} /* else {
|
||||||
|
(neighbor_pass_wpos, ddist, 1.0)
|
||||||
|
} */;
|
||||||
|
(
|
||||||
|
direction,
|
||||||
|
coeffs,
|
||||||
|
sim.get(neighbor_pass_pos).expect("Must already work"),
|
||||||
|
closest_t,
|
||||||
|
closest_pos,
|
||||||
|
closest_dist.sqrt(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
RiverKind::Ocean => {
|
||||||
let water_chunk = posj.map(|e| e as f64);
|
let water_chunk = posj.map(|e| e as f64);
|
||||||
let lake_width_noise = sim
|
let lake_width_noise = sim
|
||||||
.gen_ctx
|
.gen_ctx
|
||||||
@ -225,65 +284,16 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
|
|||||||
(
|
(
|
||||||
direction,
|
direction,
|
||||||
coeffs,
|
coeffs,
|
||||||
sim.get(neighbor_pass_pos).expect("Must already work"),
|
sim.get(posj).expect("Must already work"),
|
||||||
0.5,
|
0.5,
|
||||||
pos,
|
pos,
|
||||||
pos.distance(wposf),
|
pos.distance(wposf),
|
||||||
)
|
)
|
||||||
} else if let Some((t, pt, dist)) = quadratic_nearest_point(
|
},
|
||||||
&coeffs,
|
};
|
||||||
wposf,
|
let river_width_max = if let Some(RiverKind::River { cross_section }) =
|
||||||
Vec2::new(neighbor_wpos, neighbor_pass_wpos),
|
downhill_chunk.river.river_kind
|
||||||
) {
|
{
|
||||||
(
|
|
||||||
direction,
|
|
||||||
coeffs,
|
|
||||||
sim.get(neighbor_pass_pos).expect("Must already work"),
|
|
||||||
t,
|
|
||||||
pt,
|
|
||||||
dist.sqrt(),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
let ndist = wposf.distance_squared(neighbor_wpos);
|
|
||||||
/* let ddist = wposf.distance_squared(neighbor_pass_wpos); */
|
|
||||||
let (closest_pos, closest_dist, closest_t) = /*if ndist <= ddist */ {
|
|
||||||
(neighbor_wpos, ndist, 0.0)
|
|
||||||
} /* else {
|
|
||||||
(neighbor_pass_wpos, ddist, 1.0)
|
|
||||||
} */;
|
|
||||||
(
|
|
||||||
direction,
|
|
||||||
coeffs,
|
|
||||||
sim.get(neighbor_pass_pos).expect("Must already work"),
|
|
||||||
closest_t,
|
|
||||||
closest_pos,
|
|
||||||
closest_dist.sqrt(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
RiverKind::Ocean => {
|
|
||||||
let water_chunk = posj.map(|e| e as f64);
|
|
||||||
let lake_width_noise = sim
|
|
||||||
.gen_ctx
|
|
||||||
.small_nz
|
|
||||||
.get((wposf.map(|e| e as f64).div(32.0)).into_array());
|
|
||||||
let water_aabr = Aabr {
|
|
||||||
min: water_chunk * neighbor_coef + 4.0 - lake_width_noise * 8.0,
|
|
||||||
max: (water_chunk + 1.0) * neighbor_coef - 4.0 + lake_width_noise * 8.0,
|
|
||||||
};
|
|
||||||
let pos = water_aabr.projected_point(wposf);
|
|
||||||
(
|
|
||||||
direction,
|
|
||||||
coeffs,
|
|
||||||
sim.get(posj).expect("Must already work"),
|
|
||||||
0.5,
|
|
||||||
pos,
|
|
||||||
pos.distance(wposf),
|
|
||||||
)
|
|
||||||
},
|
|
||||||
};
|
|
||||||
let river_width_max =
|
|
||||||
if let Some(RiverKind::River { cross_section }) = downhill_chunk.river.river_kind {
|
|
||||||
// Harmless hack that prevents a river growing wildly outside its bounds to
|
// Harmless hack that prevents a river growing wildly outside its bounds to
|
||||||
// create water walls
|
// create water walls
|
||||||
(cross_section.x as f64).min(river_width_min * 1.75)
|
(cross_section.x as f64).min(river_width_min * 1.75)
|
||||||
@ -294,37 +304,39 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
|
|||||||
// water walls
|
// water walls
|
||||||
lake_width * 0.5
|
lake_width * 0.5
|
||||||
};
|
};
|
||||||
let river_width_noise = (sim.gen_ctx.small_nz.get((river_pos.div(16.0)).into_array()))
|
let river_width_noise =
|
||||||
.max(-1.0)
|
(sim.gen_ctx.small_nz.get((river_pos.div(16.0)).into_array()))
|
||||||
.min(1.0)
|
.max(-1.0)
|
||||||
.mul(0.5)
|
.min(1.0)
|
||||||
.sub(0.5) as f64;
|
.mul(0.5)
|
||||||
let river_width = Lerp::lerp(
|
.sub(0.5) as f64;
|
||||||
river_width_min,
|
let river_width = Lerp::lerp(
|
||||||
river_width_max,
|
river_width_min,
|
||||||
river_t.clamped(0.0, 1.0).powf(3.0),
|
river_width_max,
|
||||||
);
|
river_t.clamped(0.0, 1.0).powf(3.0),
|
||||||
|
);
|
||||||
|
|
||||||
let river_width = river_width.max(2.0) * (1.0 + river_width_noise * 0.3);
|
let river_width = river_width.max(2.0) * (1.0 + river_width_noise * 0.3);
|
||||||
// To find the distance, we just evaluate the quadratic equation at river_t and
|
// To find the distance, we just evaluate the quadratic equation at river_t and
|
||||||
// see if it's within width (but we should be able to use it for a
|
// see if it's within width (but we should be able to use it for a
|
||||||
// lot more, and this probably isn't the very best approach anyway
|
// lot more, and this probably isn't the very best approach anyway
|
||||||
// since it will bleed out). let river_pos = coeffs.x * river_t *
|
// since it will bleed out). let river_pos = coeffs.x * river_t *
|
||||||
// river_t + coeffs.y * river_t + coeffs.z;
|
// river_t + coeffs.y * river_t + coeffs.z;
|
||||||
// let river_width = 32.0f64;
|
// let river_width = 32.0f64;
|
||||||
let res = Vec2::new(0.0, (river_dist - (river_width * 0.5).max(1.0)).max(0.0));
|
let res = Vec2::new(0.0, (river_dist - (river_width * 0.5).max(1.0)).max(0.0));
|
||||||
(
|
(
|
||||||
posj,
|
posj,
|
||||||
chunkj,
|
chunkj,
|
||||||
river,
|
river,
|
||||||
Some((
|
Some((
|
||||||
direction,
|
direction,
|
||||||
res,
|
res,
|
||||||
river_width,
|
river_width,
|
||||||
(river_t, (river_pos, coeffs), downhill_chunk),
|
(river_t, (river_pos, coeffs), downhill_chunk),
|
||||||
)),
|
)),
|
||||||
)
|
)
|
||||||
});
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
debug_assert!(sim_chunk.water_alt >= CONFIG.sea_level);
|
debug_assert!(sim_chunk.water_alt >= CONFIG.sea_level);
|
||||||
|
|
||||||
@ -397,7 +409,7 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
|
|||||||
// reflect that. Additionally, the river must experience a rapid
|
// reflect that. Additionally, the river must experience a rapid
|
||||||
// change in elevation. Pooling into a lake produces a rapid.
|
// change in elevation. Pooling into a lake produces a rapid.
|
||||||
// TODO: Find a better way to produce rapids along the course of a river?
|
// TODO: Find a better way to produce rapids along the course of a river?
|
||||||
(chunk_pos.sum() as u32 % 19 < 2
|
(RandomField::new(3119).chance(chunk_pos.with_z(0), 0.1)
|
||||||
|| matches!(
|
|| matches!(
|
||||||
downhill_chunk.river.river_kind,
|
downhill_chunk.river.river_kind,
|
||||||
Some(RiverKind::Lake { .. })
|
Some(RiverKind::Lake { .. })
|
||||||
@ -418,7 +430,7 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Use this to temporarily alter the sea level
|
// Use this to temporarily alter the sea level
|
||||||
let base_sea_level = CONFIG.sea_level + 0.01;
|
let base_sea_level = CONFIG.sea_level - 1.0 + 0.01;
|
||||||
|
|
||||||
// What's going on here?
|
// What's going on here?
|
||||||
//
|
//
|
||||||
@ -440,7 +452,7 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
|
|||||||
// they do not result in artifacts, even in edge cases. The exact configuration
|
// they do not result in artifacts, even in edge cases. The exact configuration
|
||||||
// of this code is the product of hundreds of hours of testing and
|
// of this code is the product of hundreds of hours of testing and
|
||||||
// refinement and I ask that you do not take that effort lightly.
|
// refinement and I ask that you do not take that effort lightly.
|
||||||
let (river_water_level, in_river, lake_water_level, lake_dist, water_dist, unbounded_water_level) = neighbor_river_data.clone().fold(
|
let (river_water_level, in_river, lake_water_level, lake_dist, water_dist, unbounded_water_level) = neighbor_river_data.iter().copied().fold(
|
||||||
(
|
(
|
||||||
WeightedSum::default().with_max(base_sea_level),
|
WeightedSum::default().with_max(base_sea_level),
|
||||||
false,
|
false,
|
||||||
@ -566,7 +578,7 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
|
|||||||
// has been carefully designed to handle innumeral edge cases. Please
|
// has been carefully designed to handle innumeral edge cases. Please
|
||||||
// test any changes to this code extremely well to avoid regressions: some
|
// test any changes to this code extremely well to avoid regressions: some
|
||||||
// edge cases are very rare indeed!
|
// edge cases are very rare indeed!
|
||||||
let alt = neighbor_river_data.clone().fold(
|
let alt = neighbor_river_data.into_iter().fold(
|
||||||
WeightedSum::default().with(riverless_alt, 1.0),
|
WeightedSum::default().with(riverless_alt, 1.0),
|
||||||
|alt, (river_chunk_idx, river_chunk, river, dist_info)| match (
|
|alt, (river_chunk_idx, river_chunk, river, dist_info)| match (
|
||||||
river.river_kind,
|
river.river_kind,
|
||||||
@ -593,12 +605,16 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
|
|||||||
Some((river_water_alt, cross_section.y as f32, None))
|
Some((river_water_alt, cross_section.y as f32, None))
|
||||||
},
|
},
|
||||||
RiverKind::Lake { .. } | RiverKind::Ocean => {
|
RiverKind::Lake { .. } | RiverKind::Ocean => {
|
||||||
let lake_water_alt = river_water_alt(
|
let lake_water_alt = if matches!(kind, RiverKind::Ocean) {
|
||||||
river_chunk.alt.max(river_chunk.water_alt),
|
base_sea_level
|
||||||
downhill_chunk.alt.max(downhill_chunk.water_alt),
|
} else {
|
||||||
river_t as f32,
|
river_water_alt(
|
||||||
is_waterfall(river_chunk_idx, river_chunk, downhill_chunk),
|
river_chunk.alt.max(river_chunk.water_alt),
|
||||||
);
|
downhill_chunk.alt.max(downhill_chunk.water_alt),
|
||||||
|
river_t as f32,
|
||||||
|
is_waterfall(river_chunk_idx, river_chunk, downhill_chunk),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
let depth = water_level
|
let depth = water_level
|
||||||
- Lerp::lerp(
|
- Lerp::lerp(
|
||||||
@ -630,7 +646,7 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
|
|||||||
if let Some((water_alt, water_depth, min_alt)) = water_alt {
|
if let Some((water_alt, water_depth, min_alt)) = water_alt {
|
||||||
if river_edge_dist <= 0.0 {
|
if river_edge_dist <= 0.0 {
|
||||||
const MIN_DEPTH: f32 = 1.0;
|
const MIN_DEPTH: f32 = 1.0;
|
||||||
let near_centre = ((river_dist / (river_width * 0.5)) as f32)
|
let near_center = ((river_dist / (river_width * 0.5)) as f32)
|
||||||
.min(1.0)
|
.min(1.0)
|
||||||
.mul(f32::consts::PI)
|
.mul(f32::consts::PI)
|
||||||
.cos()
|
.cos()
|
||||||
@ -652,14 +668,14 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
|
|||||||
/ TerrainChunkSize::RECT_SIZE.x as f32
|
/ TerrainChunkSize::RECT_SIZE.x as f32
|
||||||
};
|
};
|
||||||
let riverbed_depth =
|
let riverbed_depth =
|
||||||
near_centre * water_depth + MIN_DEPTH + waterfall_boost;
|
near_center * water_depth + MIN_DEPTH + waterfall_boost;
|
||||||
// Handle rivers debouching into the ocean nicely by 'flattening' their
|
// Handle rivers debouching into the ocean nicely by 'flattening' their
|
||||||
// bottom
|
// bottom
|
||||||
let riverbed_alt = (water_alt - riverbed_depth)
|
let riverbed_alt = (water_alt - riverbed_depth)
|
||||||
.max(riverless_alt.min(CONFIG.sea_level - MIN_DEPTH));
|
.max(riverless_alt.min(base_sea_level - MIN_DEPTH));
|
||||||
alt.with(
|
alt.with(
|
||||||
min_alt.unwrap_or(riverbed_alt).min(riverbed_alt),
|
min_alt.unwrap_or(riverbed_alt).min(riverbed_alt),
|
||||||
near_centre * BANK_STRENGTH,
|
near_center * BANK_STRENGTH,
|
||||||
)
|
)
|
||||||
.with_min(min_alt.unwrap_or(riverbed_alt).min(riverbed_alt))
|
.with_min(min_alt.unwrap_or(riverbed_alt).min(riverbed_alt))
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user