我目前正在我的游戏中实现生物群落生成,我想使生物群落的类型依赖于humidity和temperature值,这些值是由逐渐产生的噪音产生的。
不同的生物群体应该有不同的高度,如果不进行插值,就会像预期的那样在生物群落边界上产生突然的高度差异。
我尝试的是在网格中得到两个相邻的生物群落,并测量每个生物群落的混合百分比。
稍后,我从生物群落中得到3个不同的height值,并将每个值与各自的blend值相乘。
下面是简化和剥离的代码,用于获取生物群落:
const BIOME_GRID_SIZE: usize = 2;
const BIOME_INDEX_SIZE: usize = BIOME_GRID_SIZE - 1;
const BIOME_GRID: [[Biomes; BIOME_GRID_SIZE]; BIOME_GRID_SIZE] =
[
[Biomes::Mountains, Biomes::Forest],
[Biomes::Desert , Biomes::Mesa ],
];
fn get_height(coord: [i64; 2], noise: &Noise) -> i64 {
let temperature = (noise.get_2d(coord) + 0.5).clamp(0.0, 1.0);
let humidity = (noise.get_2d(coord /* + some offset */) + 0.5).clamp(0.0, 1.0);
let x = BIOME_GRID_SIZE as f64 * humidity;
let y = BIOME_GRID_SIZE as f64 * temperature;
let x_frac = (x.fract() - 0.5) * 2.0;
let y_frac = (y.fract() - 0.5) * 2.0;
let x_blending = x_frac.abs();
let y_blending = y_frac.abs();
let own_blending = 2.0 - x_blending - y_blending;
// direction of neighbour biomes
let x_direction = x_frac.signum() as isize;
let y_direction = y_frac.signum() as isize;
let x_index = (x.trunc() as isize).clamp(0, BIOME_INDEX_SIZE as isize);
let y_index = (y.trunc() as isize).clamp(0, BIOME_INDEX_SIZE as isize);
let biomes = get_biomes(x_index, y_index, x_direction, y_direction);
blend(
coord,
noise,
biomes,
[
own_blending,
x_blending,
y_blending,
]
),
}
// get main and neighbour biomes
fn get_biomes(x: isize, y: isize, x_direction: isize, y_direction: isize) -> [Biomes; 3] {
let mut biomes = [Biomes::Ocean; 3];
for (i, (d_x, d_y)) in [(0, 0), (x_direction, 0), (0, y_direction)].iter().enumerate() {
let x_index = (x + d_x).clamp(0, BIOME_INDEX_SIZE as isize) as usize;
let y_index = (y + d_y).clamp(0, BIOME_INDEX_SIZE as isize) as usize;
let biome = BIOME_GRID[x_index][y_index];
biomes[i] = biome;
}
biomes
}
pub fn blend(
coord: [i64; 2],
noise: &Noise,
biomes: [Biomes; 4],
blending: [f64; 4],
) -> i64 {
let heights: Vec<f64> = biomes
.iter()
.map(|x| x.get().height(coord, noise) as f64)
.collect();
let height = heights[0] * blending[0] + heights[1] * blending[1] + heights[2] * blending[2];
let height = height as i64;
height
}这在某些情况下很好,而在另一些情况下则完全失败。
我不确定,两个邻居是否足够,以及如何正确地获得blend值。
这个问题有更好的解决办法吗?
发布于 2022-09-11 14:21:03
一般来说,对于双线性混合,您将使用四点。如果我正确理解你的代码,那就是每个生物群落的四幅高度图。然后,您通过一个轴(例如湿度)的两个对与另一个轴,然后将这两个混合值再次与另一个轴(例如温度)。
https://stackoverflow.com/questions/73679850
复制相似问题