From 3460d889aa2e7af1a60d218a1a8589027b4e4e63 Mon Sep 17 00:00:00 2001 From: salmonik Date: Thu, 9 Jul 2026 23:27:55 +0200 Subject: init --- src/texture.rs | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 src/texture.rs (limited to 'src/texture.rs') diff --git a/src/texture.rs b/src/texture.rs new file mode 100644 index 0000000..bdbb15c --- /dev/null +++ b/src/texture.rs @@ -0,0 +1,102 @@ +use rand::Rng; + +pub const TEX_SIZE: usize = 64; + +/// Deterministic hash for coherent procedural noise. +fn hash(x: u32, y: u32, seed: u64) -> u64 { + let mut h = (x as u64).wrapping_mul(0x9e3779b9); + h = h.wrapping_add((y as u64).wrapping_mul(0x517cc1b727220a95)); + h = h.wrapping_add(seed); + h = (h ^ (h >> 33)).wrapping_mul(0xc6a4a7935bd1e995); + h = (h ^ (h >> 29)).wrapping_mul(0x5bd1e995); + h +} + +/// Brown cracked wall texture — 64×64, brick pattern with mortar lines and fissures. +pub fn generate_wall_texture(rng: &mut impl Rng) -> Vec { + let seed = rng.gen::(); + let mut tex = vec![0u32; TEX_SIZE * TEX_SIZE]; + + for y in 0..TEX_SIZE { + for x in 0..TEX_SIZE { + let h = hash(x as u32, y as u32, seed); + + let r = 105u8.wrapping_add((h % 50) as u8); + let g = 55u8.wrapping_add(((h >> 8) % 35) as u8); + let b = 22u8.wrapping_add(((h >> 16) % 25) as u8); + + // Brick mortar every 16 pixels + let mortar = y % 16 == 0 || y % 16 == 15; + + let (r, g, b) = if mortar { + (42, 20, 8) + } else { + let crack_hash = hash(x.wrapping_add(1000) as u32, y as u32, seed); + let crack_val = (crack_hash % 100) as u8; + if crack_val < 8 { + // dark crack + let factor = 0.30 + (crack_val as f64 / 8.0) * 0.25; + ( + (r as f64 * factor) as u8, + (g as f64 * factor) as u8, + (b as f64 * factor) as u8, + ) + } else if crack_val < 14 { + // light crack highlight + ( + (r.saturating_add(25)).min(255), + (g.saturating_add(18)).min(255), + (b.saturating_add(10)).min(255), + ) + } else { + (r, g, b) + } + }; + + tex[y * TEX_SIZE + x] = + 0xFF00_0000 | ((r as u32) << 16) | ((g as u32) << 8) | (b as u32); + } + } + tex +} + +/// Gray stone-tile floor — 64×64, checkerboard with grout and subtle colour tint. +pub fn generate_floor_texture(rng: &mut impl Rng) -> Vec { + let seed = rng.gen::(); + let mut tex = vec![0u32; TEX_SIZE * TEX_SIZE]; + + for y in 0..TEX_SIZE { + for x in 0..TEX_SIZE { + let h = hash(x as u32, y as u32, seed); + let h2 = hash(x.wrapping_add(2000) as u32, y.wrapping_add(2000) as u32, seed); + + let tile_x = x / 16; + let tile_y = y / 16; + let is_light_tile = (tile_x + tile_y) % 2 == 0; + + let local_x = x % 16; + let local_y = y % 16; + let is_grout = local_x == 0 || local_y == 0; + + let base_gray: u8 = if is_light_tile { 115 } else { 95 }; + let noise = (h % 15) as u8; + + let tint_r = (h2 % 8) as i16 - 4i16; + let tint_b = ((h2 >> 8) % 8) as i16 - 4i16; + + let gray = if is_grout { + base_gray.saturating_sub(30).saturating_add(noise / 3) + } else { + base_gray.saturating_add(noise / 2) + }; + + let r = (gray as i16 + tint_r).clamp(0, 255) as u8; + let g = gray; + let b = (gray as i16 + tint_b).clamp(0, 255) as u8; + + tex[y * TEX_SIZE + x] = + 0xFF00_0000 | ((r as u32) << 16) | ((g as u32) << 8) | (b as u32); + } + } + tex +} -- cgit v1.2.3