summaryrefslogtreecommitdiff
path: root/src/content/world
diff options
context:
space:
mode:
authorKai Stevenson <kai@kaistevenson.com>2026-09-01 20:23:56 -0700
committerKai Stevenson <kai@kaistevenson.com>2026-09-01 20:23:56 -0700
commit5ebc92d5a6bbbe14e7c4c25b25a4ff8578ddcd5a (patch)
treec47ee1588da1e95d95d0eb064fdad39025d47a4a /src/content/world
parent7eedb19a5f28150a28b8cf1ec5fb08139d6b5590 (diff)
smooth material mixing
Diffstat (limited to 'src/content/world')
-rw-r--r--src/content/world/mines.rs77
1 files changed, 67 insertions, 10 deletions
diff --git a/src/content/world/mines.rs b/src/content/world/mines.rs
index d750619..961b068 100644
--- a/src/content/world/mines.rs
+++ b/src/content/world/mines.rs
@@ -1,5 +1,5 @@
use fastnoise_lite::{FastNoiseLite, FractalType};
-use glam::IVec2;
+use glam::{IVec2, Vec2};
use crate::{
content::materials::MaterialId,
@@ -7,28 +7,85 @@ use crate::{
sim::cell::Cell,
};
-const ROUGHNESS: f32 = 0.375;
+const DISPLACEMENT_ROUGHNESS: f32 = 0.375;
+const BOUNDARY_ROUGHNESS: f32 = 0.375;
pub struct MinesBiome {
- pub edge_roughness: FastNoiseLite,
+ pub dirt_roughness: FastNoiseLite,
+ pub water_roughness: FastNoiseLite,
+ pub wood_roughness: FastNoiseLite,
}
impl MinesBiome {
+ fn pixel_idx_to_type(idx: u8) -> MinesBiomePixelType {
+ match idx {
+ 1 => MinesBiomePixelType::Dirt,
+ 12 => MinesBiomePixelType::Water,
+ 13 => MinesBiomePixelType::Wood,
+ _ => MinesBiomePixelType::Void,
+ }
+ }
+
+ fn material_roughness(&self, pixel_type: MinesBiomePixelType, world: Vec2) -> f32 {
+ match pixel_type {
+ MinesBiomePixelType::Dirt => self.dirt_roughness.get_noise_2d(world.x, world.y),
+ MinesBiomePixelType::Water => self.water_roughness.get_noise_2d(world.x, world.y),
+ MinesBiomePixelType::Wood => self.wood_roughness.get_noise_2d(world.x, world.y),
+ _ => self.dirt_roughness.get_noise_2d(world.x, world.y),
+ }
+ }
+
pub fn new() -> Self {
- let mut edge_roughness = FastNoiseLite::new();
- edge_roughness.set_fractal_type(Some(FractalType::Ridged));
- edge_roughness.set_fractal_octaves(Some(2));
- MinesBiome { edge_roughness }
+ let mut dirt_roughness = FastNoiseLite::with_seed(0);
+ dirt_roughness.set_fractal_type(Some(FractalType::Ridged));
+ dirt_roughness.set_fractal_octaves(Some(2));
+
+ let mut water_roughness = FastNoiseLite::with_seed(100);
+ water_roughness.set_fractal_type(Some(FractalType::FBm));
+ water_roughness.set_frequency(Some(0.005));
+ water_roughness.set_fractal_octaves(Some(2));
+
+ let mut wood_roughness = FastNoiseLite::with_seed(200);
+ wood_roughness.set_fractal_type(Some(FractalType::FBm));
+ wood_roughness.set_frequency(Some(0.02));
+ wood_roughness.set_fractal_octaves(Some(2));
+ MinesBiome {
+ dirt_roughness,
+ water_roughness,
+ wood_roughness,
+ }
}
}
+enum MinesBiomePixelType {
+ Void,
+ Dirt,
+ Water,
+ Wood,
+}
+
impl Biome for MinesBiome {
fn fragment(&self, pixel: InterpolatedPixel, world: IVec2) -> Cell {
let world = world.as_vec2();
- let displacement = ROUGHNESS * self.edge_roughness.get_noise_2d(world.x, world.y);
- match pixel.interpolated_pixel_index {
- 0 => {
+ let pixel_idx = pixel
+ .interpolated_pixel_indices
+ .iter()
+ .map(|&(i, s)| {
+ (
+ i,
+ s + self.material_roughness(MinesBiome::pixel_idx_to_type(i), world)
+ * BOUNDARY_ROUGHNESS,
+ )
+ })
+ .max_by(|&(_, s1), &(_, s2)| s1.total_cmp(&s2))
+ .map_or(0, |(i, _)| i);
+
+ let displacement =
+ DISPLACEMENT_ROUGHNESS * self.dirt_roughness.get_noise_2d(world.x, world.y);
+
+ match pixel_idx {
+ 1 => {
if pixel.interpolated_solidity + displacement <= 0.0 {
return Cell::void();
}