From 7d48ac5a9cb6b843903b8d4ab54744c62e920356 Mon Sep 17 00:00:00 2001 From: shadow cat Date: Fri, 7 Jun 2024 23:55:31 -0400 Subject: [PATCH] fix transparency group order bug --- src/client/render/voxel/color.rs | 17 +++++++++------ src/client/render/voxel/pipeline.rs | 2 +- src/client/render/voxel/shader.wgsl | 32 ++++++++++++++++------------- 3 files changed, 30 insertions(+), 21 deletions(-) diff --git a/src/client/render/voxel/color.rs b/src/client/render/voxel/color.rs index b1fa0c7..819cd72 100644 --- a/src/client/render/voxel/color.rs +++ b/src/client/render/voxel/color.rs @@ -1,3 +1,5 @@ +use rand::distributions::{Distribution, Standard}; + #[repr(C)] #[derive(Debug, Clone, Copy, PartialEq, bytemuck::Zeroable, bytemuck::Pod)] pub struct VoxelColor { @@ -32,12 +34,15 @@ impl VoxelColor { a: 255, } } - pub fn random() -> Self { - Self { - r: rand::random(), - g: rand::random(), - b: rand::random(), - a: rand::random(), +} + +impl Distribution for Standard { + fn sample(&self, rng: &mut R) -> VoxelColor { + VoxelColor { + r: rng.gen(), + g: rng.gen(), + b: rng.gen(), + a: rng.gen(), } } } diff --git a/src/client/render/voxel/pipeline.rs b/src/client/render/voxel/pipeline.rs index 0e4c891..7d0ec05 100644 --- a/src/client/render/voxel/pipeline.rs +++ b/src/client/render/voxel/pipeline.rs @@ -163,7 +163,7 @@ impl VoxelPipeline { } for x in 0..lx2 { for z in 0..lz2 { - data2[x + z * lx2 * ly2] = VoxelColor::random(); + data2[x + z * lx2 * ly2] = rand::random(); } } data.append(&mut data2); diff --git a/src/client/render/voxel/shader.wgsl b/src/client/render/voxel/shader.wgsl index 0399325..09e48e0 100644 --- a/src/client/render/voxel/shader.wgsl +++ b/src/client/render/voxel/shader.wgsl @@ -37,7 +37,7 @@ fn vs_main( var pos = vec2( f32(vi % 2u) * 2.0 - 1.0, f32(vi / 2u) * 2.0 - 1.0, - ); + ) ; out.clip_position = vec4(pos.x, pos.y, 0.0, 1.0); out.tex_coords = pos; return out; @@ -71,7 +71,7 @@ fn fs_main( const ZERO3F = vec3(0.0); const ZERO2F = vec2(0.0); -const DEPTH = 20; +const DEPTH = 16u; const FULL_ALPHA = 0.9999; const GLOBAL_LIGHT = vec3(-0.5, -4.0, 2.0); @@ -80,15 +80,16 @@ fn trace_full(pos: vec4, dir: vec4) -> vec4 { var depths = array(); var colors = array(); + var hits = 0u; for (var gi: u32 = 0; gi < arrayLength(&voxel_groups); gi = gi + 1) { - apply_group(gi, pos, dir, &depths, &colors); + apply_group(gi, pos, dir, &depths, &colors, &hits); } var color = vec4(0.0); - for (var di = 0; di < DEPTH; di += 1) { + for (var di = 0u; di < DEPTH; di += 1u) { let vcolor = unpack4x8unorm(colors[di]); - color += vec4(vcolor.xyz * vcolor.a * (1.0 - color.a), (1.0 - color.a) * vcolor.a); + color += vec4(vcolor.xyz * vcolor.a, vcolor.a) * (1.0 - color.a); if vcolor.a == 0.0 || color.a >= FULL_ALPHA { - return color; + break; } } return color; @@ -102,6 +103,7 @@ fn apply_group( gi: u32, pos_view: vec4, dir_view: vec4, depths: ptr>, colors: ptr>, + hit_len: ptr, ) { let group = voxel_groups[gi]; let dim_f = vec3(group.dimensions); @@ -162,7 +164,7 @@ fn apply_group( var alpha = 0.0; var t = 0.0; var prev_t = t; - var depth = 0; + var depth = 0u; var prev_a = 0.0; loop { let i = u32(vox_pos.x + vox_pos.y * dim_i.x + vox_pos.z * dim_i.x * dim_i.y) + group.offset; @@ -188,15 +190,15 @@ fn apply_group( if depth + 1 >= DEPTH || alpha >= FULL_ALPHA { return; } - depth += 1; + depth += 1u; a = unpack4x8unorm((*colors)[depth]).a; } - var move_d = depth; + var move_d = min(*hit_len, DEPTH - 1); // move further depth hits back (top 10 efficient algorithms) - while move_d < DEPTH - 1 && unpack4x8unorm((*colors)[move_d]).a != 0.0 { - (*colors)[move_d + 1] = (*colors)[move_d]; - (*depths)[move_d + 1] = (*depths)[move_d]; - move_d += 1; + while move_d > depth { + (*colors)[move_d] = (*colors)[move_d - 1]; + (*depths)[move_d] = (*depths)[move_d - 1]; + move_d -= 1u; } let full_pos = pos_view + dir_view * full_t; @@ -211,12 +213,14 @@ fn apply_group( let new_rgb = min(vcolor.xyz * lighting + specular.xyz + light.xyz * vcolor.xyz, vec3(1.0)); let new_a = min(vcolor.a + specular.a, 1.0); let color = vec4(new_rgb, new_a); + // let color = vec4((cos(full_t * 0.1) + 1.0) * 0.5, 0.0, 0.0, new_a); // add hit (*depths)[depth] = full_t; (*colors)[depth] = pack4x8unorm(color); prev_a = vcolor.a; - depth += 1; + depth += 1u; + *hit_len += 1u; alpha += (1.0 - alpha) * vcolor.a; }