From 5488bb2c4bada3043c635dc62a64639f20463bd8 Mon Sep 17 00:00:00 2001 From: Albin Chaboissier Date: Tue, 30 Dec 2025 16:42:37 +0100 Subject: [PATCH] Working traverse2 --- shaders/cube.wgsl | 107 +++++++++++++++++++++++++++++++++++++++++++++- src/state.rs | 4 +- 2 files changed, 107 insertions(+), 4 deletions(-) diff --git a/shaders/cube.wgsl b/shaders/cube.wgsl index 6f149df..616389d 100644 --- a/shaders/cube.wgsl +++ b/shaders/cube.wgsl @@ -98,6 +98,99 @@ struct ColorTile @group(0) @binding(0) var structure_tiles : array; @group(0) @binding(1) var color_tiles : array; +fn traverse2(max_depth: u32, root_color: vec4, root_subdivided: bool, eye_pos: vec3, ray_dir: vec3) -> vec4 +{ + if max_depth == 0 || !root_subdivided + { + return inferno_quintic(0.); + return root_color; + } + + var node_structs = structure_tiles[0]; + var node_colors = color_tiles[0]; + var node_tile_idx = u32(0); + //var stack = array(0, 0, 0, 0); + var stack_struct = array(node_structs, node_structs, node_structs, node_structs); + var stack_colors = array(node_colors, node_colors, node_colors, node_colors); + + var voxel_scale = N * N * N; + var scale_exp = 3; + let voxel_scale_lut = array( + 1, + N, + N * N, + N * N * N + ); + + let dist = 1. / ray_dir; + let origin = eye_pos * 256.; + var pos = origin; // In voxel space + let offset = - origin * dist; + let wall_offset = select(vec3(0.), vec3(1.), ray_dir > vec3(0.)); + var voxel_pos = clamp(vec3(floor(pos)), vec3(0), vec3(N * N * N * N - 1)); + let max = 20.; + for(var iter = 0; iter < 60; iter++) + { + var voxel_pos = vec3(floor(pos)); + var child_pos = voxel_pos >> vec3(scale_exp * 2); + var local_child_pos = child_pos & vec3(3); + var child_idx = local_child_pos.x + local_child_pos.y * N + local_child_pos.z * N * N; + + while (node_structs.children[child_idx] >> 31) != 0 && (u32(4 - scale_exp) < max_depth) + { + //stack[scale_exp] = u32(node_tile_idx); + stack_struct[scale_exp] = node_structs; + stack_colors[scale_exp] = node_colors; + scale_exp -= 1; + voxel_scale = voxel_scale_lut[scale_exp]; + + node_tile_idx = node_structs.children[child_idx] & 0x3fffffff; + node_structs = structure_tiles[node_tile_idx]; + node_colors = color_tiles[node_tile_idx]; + + child_pos = voxel_pos >> vec3(scale_exp * 2); + local_child_pos = child_pos & vec3(3); + child_idx = local_child_pos.x + local_child_pos.y * N + local_child_pos.z * N * N; + } + + if node_colors.colors[child_idx].w != 0 + { + return inferno_quintic(f32(iter) / max); + return node_colors.colors[child_idx]; + } + + // Compute intersection + let global_voxel = vec3(child_pos * voxel_scale); + let cell_max = global_voxel + vec3(voxel_scale) * wall_offset; + + let t1 = fma(dist, cell_max, offset); + + let t_far = min(t1.x, min(t1.y, t1.z)) + 0.001; + pos = origin + t_far * ray_dir; + + let diff = vec3(pos + 256) ^ vec3(global_voxel + 256); + let diff_exp = (firstLeadingBit((diff.x | diff.y | diff.z)) >> 1); + + if diff_exp > 3 + { + return inferno_quintic(f32(iter) / max); + discard; + } + + if diff_exp > u32(scale_exp) + { + scale_exp = i32(diff_exp); + + voxel_scale = voxel_scale_lut[scale_exp]; + //node_tile_idx = stack[scale_exp]; + node_structs = stack_struct[scale_exp]; + node_colors = stack_colors[scale_exp]; + } + } + + return vec4(1., 0., 1., 1.); +} + //@fragment fn traverse(max_depth: u32, root_color: vec4, root_subdivided: bool, eye_pos: vec3, ray_dir: vec3) -> vec4 { @@ -215,6 +308,7 @@ fn traverse(max_depth: u32, root_color: vec4, root_subdivided: bool, eye_po let next_child = current_child_pos + advance_mask * step; if any(next_child < vec3(0)) || any(next_child >= vec3(i32(N))) { + let aligned_child = select(vec3(0), vec3(i32(N)), vec3(step) > vec3(0)); let masked_aligned = advance_mask * ((aligned_child * i32(current_child_size)) + current_node_offset); let exiting_axis = masked_aligned.x + masked_aligned.y + masked_aligned.z + 256; @@ -304,7 +398,7 @@ fn fragment_tree_main(in: VertexOutput) -> @location(0) vec4 div *= 4; } overlay = 1.; - return overlay * traverse(4, in.root_color, in.root_subdivided != 0, in.eye_pos - in.cube_pos, dir); + return overlay * traverse2(4, in.root_color, in.root_subdivided != 0, hit_pos, dir); } @fragment @@ -437,3 +531,14 @@ fn intersectAABB(rayOrigin: vec3, rayDir: vec3, boxMin: vec3, box let tFar = min(min(t2.x, t2.y), t2.z); return vec2(tNear, tFar); }; + +fn inferno_quintic( xx: f32 ) -> vec4 +{ + let x = saturate(xx); + let x1 = vec4( 1.0, x, x * x, x * x * x ); // 1 x x2 x3 + let x2 = x1 * x1.w * x; // x4 x5 x6 x7 + return vec4(saturate( vec3( + dot( x1.xyzw, vec4( -0.027780558, 1.228188385, 0.278906882, 3.892783760 ) ) + dot( x2.xy, vec2( -8.490712758, 4.069046086 ) ), + dot( x1.xyzw, vec4( 0.014065206, 0.015360518, 1.605395918, -4.821108251 ) ) + dot( x2.xy, vec2( 8.389314011, -4.193858954 ) ), + dot( x1.xyzw, vec4( -0.019628385, 3.122510347, -5.893222355, 2.798380308 ) ) + dot( x2.xy, vec2( -3.608884658, 4.324996022 ) ) ) ), 1.); +} diff --git a/src/state.rs b/src/state.rs index 316b817..6960f0a 100644 --- a/src/state.rs +++ b/src/state.rs @@ -11,8 +11,6 @@ use cgmath::SquareMatrix; use cgmath::Vector3; use cgmath::Vector4; use crevice::std430::AsStd430; -use egui::ProgressBar; -use egui::menu::bar; use egui_wgpu::ScreenDescriptor; use indicatif::ProgressIterator; use itertools::Itertools; @@ -233,7 +231,7 @@ impl State { let dist = cgmath::Vector3::new(x as f32 - 128., y as f32 - 128., z as f32 - 128.).magnitude(); - if dist < 128. + if dist <= 128. && dist >= 127. { ntree.set(x, y, z, crate::voxel::Color(0.2, 1., 0.2, 1.)); }