From fe0f331a19369daa95c3c603a80fea4a1be1afbe Mon Sep 17 00:00:00 2001 From: Avi Weinstock Date: Sat, 24 Apr 2021 18:43:09 -0400 Subject: [PATCH] Add 5x5 manhattan blur effect to quadpng, and omit interpolation at chunk borders. --- common/net/src/msg/compression.rs | 78 +++++++++++++++++++++---------- 1 file changed, 53 insertions(+), 25 deletions(-) diff --git a/common/net/src/msg/compression.rs b/common/net/src/msg/compression.rs index 24a062ed44..28cc67d98b 100644 --- a/common/net/src/msg/compression.rs +++ b/common/net/src/msg/compression.rs @@ -143,7 +143,7 @@ pub trait VoxelImageEncoding: Copy { pub trait VoxelImageDecoding: VoxelImageEncoding { fn start(ws: &Self::Output) -> Option; - fn get_block(ws: &Self::Workspace, x: u32, y: u32) -> Block; + fn get_block(ws: &Self::Workspace, x: u32, y: u32, is_border: bool) -> Block; } #[derive(Debug, Clone, Copy, Serialize, Deserialize)] @@ -324,7 +324,7 @@ impl VoxelImageDecoding for MixedEncoding { Some((a, b, c, d)) } - fn get_block(ws: &Self::Workspace, x: u32, y: u32) -> Block { + fn get_block(ws: &Self::Workspace, x: u32, y: u32, _: bool) -> Block { if let Some(kind) = BlockKind::from_u8(ws.0.get_pixel(x, y).0[0]) { if kind.is_filled() { let rgb = ws.3.get_pixel(x, y); @@ -459,24 +459,24 @@ impl VoxelImageDecoding for QuadPngEncoding { } #[allow(clippy::many_single_char_names)] - fn get_block(ws: &Self::Workspace, x: u32, y: u32) -> Block { - //let a = inline_tweak::tweak!(1.3); - //let b = inline_tweak::tweak!(4.0); - let a = 1.3; - let b = 4.0; + fn get_block(ws: &Self::Workspace, x: u32, y: u32, is_border: bool) -> Block { + //let a = inline_tweak::tweak!(10.0); + //let b = inline_tweak::tweak!(1.0); + let a = 2.0 / 3.0; + let b = 2.0; if let Some(kind) = BlockKind::from_u8(ws.0.get_pixel(x, y).0[0]) { if kind.is_filled() { let (w, h) = ws.3.dimensions(); - let rgb = match 1 { + let mut rgb = match 1 { 0 => { let mut rgb: Vec3 = Vec3::::from(ws.3.get_pixel(x / N, y / N).0).as_(); - rgb *= 2.0; - let mut total = 2; + //rgb *= 2.0; + let mut total = 1; for (dx, dy) in [(-1i32, 0i32), (1, 0), (0, -1), (0, 1)].iter() { let (i, j) = ( - (x / N).wrapping_add(*dx as u32), - (y / N).wrapping_add(*dy as u32), + (x.wrapping_add(*dx as u32) / N), + (y.wrapping_add(*dy as u32) / N), ); if i < w && j < h { rgb += Vec3::::from(ws.3.get_pixel(i, j).0).as_(); @@ -486,32 +486,58 @@ impl VoxelImageDecoding for QuadPngEncoding { rgb /= total as f64; rgb }, + 1 => { + let mut rgb: Vec3 = Vec3::zero(); + let mut total = 0.0; + for dx in -2i32..=2 { + for dy in -2i32..=2 { + let (i, j) = ( + (x.wrapping_add(dx as u32) / N), + (y.wrapping_add(dy as u32) / N), + ); + if i < w && j < h { + let r = 5.0 - (dx.abs() + dy.abs()) as f64; + rgb += r * Vec3::::from(ws.3.get_pixel(i, j).0).as_(); + total += r; + } + } + } + rgb /= total; + rgb + }, _ => { let mut rgb: Vec3 = Vec3::zero(); for dx in -1i32..=1 { for dy in -1i32..=1 { let (i, j) = ( - (x / N).wrapping_add(dx as u32), - (y / N).wrapping_add(dy as u32), + (x.wrapping_add(dx as u32) / N), + (y.wrapping_add(dy as u32) / N), ); if i < w && j < h { let pix: Vec3 = Vec3::::from(ws.3.get_pixel(i, j).0).as_(); - rgb += lanczos( - a * Vec2::new( - (x % N) as f64 - (N - 1) as f64 / 2.0, - (y % N) as f64 - (N - 1) as f64 / 2.0, - ) - .magnitude(), - b, - ) * pix; + let c = (x.wrapping_add(dx as u32) % N) as f64 + - (N - 1) as f64 / 2.0; + let d = (y.wrapping_add(dy as u32) % N) as f64 + - (N - 1) as f64 / 2.0; + let _euclid = Vec2::new(c, d).magnitude(); + let _manhattan = c.abs() + d.abs(); + //println!("{:?}, {:?}, {:?}: {} {}", (x, y), (i, j), (c, d), + // euclid, manhattan); + // rgb += lanczos(a * euclid, b) * pix; + //rgb += lanczos(a * c, b) * lanczos(a * d, b) * pix; + rgb += lanczos(a * (i as f64 - (x / N) as f64), b) + * lanczos(a * (j as f64 - (y / N) as f64), b) + * pix; } } } rgb }, }; - //let rgb = ; + if is_border { + rgb = Vec3::::from(ws.3.get_pixel(x / N, y / N).0).as_(); + } Block::new(kind, Rgb { r: rgb.x as u8, g: rgb.y as u8, @@ -537,6 +563,7 @@ impl VoxelImageDecoding for QuadPngEncoding { pub struct TriPngEncoding; impl VoxelImageEncoding for TriPngEncoding { + #[allow(clippy::type_complexity)] type Output = CompressedData<(Vec, Vec>, [usize; 3])>; #[allow(clippy::type_complexity)] type Workspace = ( @@ -641,7 +668,7 @@ impl VoxelImageDecoding for TriPngEncoding { Some((a, b, c, d)) } - fn get_block(ws: &Self::Workspace, x: u32, y: u32) -> Block { + fn get_block(ws: &Self::Workspace, x: u32, y: u32, _: bool) -> Block { if let Some(kind) = BlockKind::from_u8(ws.0.get_pixel(x, y).0[0]) { if kind.is_filled() { let rgb = *ws @@ -781,7 +808,8 @@ pub fn write_image_terrain< for y in 0..dims.y { for x in 0..dims.x { let (i, j) = packing.index(dims, x, y, z); - let block = VIE::get_block(&ws, i, j); + let is_border = x <= 1 || x >= dims.x - 2 || y <= 1 || y >= dims.y - 2; + let block = VIE::get_block(&ws, i, j, is_border); if let Err(e) = vol.set(lo.as_() + Vec3::new(x, y, z).as_(), block) { warn!( "Error placing a block into a volume at {:?}: {:?}",