Working traverse2
This commit is contained in:
@ -98,6 +98,99 @@ struct ColorTile
|
||||
@group(0) @binding(0) var<storage> structure_tiles : array<StructureTile>;
|
||||
@group(0) @binding(1) var<storage> color_tiles : array<ColorTile>;
|
||||
|
||||
fn traverse2(max_depth: u32, root_color: vec4<f32>, root_subdivided: bool, eye_pos: vec3<f32>, ray_dir: vec3<f32>) -> vec4<f32>
|
||||
{
|
||||
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<u32, 4>(0, 0, 0, 0);
|
||||
var stack_struct = array<StructureTile, 4>(node_structs, node_structs, node_structs, node_structs);
|
||||
var stack_colors = array<ColorTile, 4>(node_colors, node_colors, node_colors, node_colors);
|
||||
|
||||
var voxel_scale = N * N * N;
|
||||
var scale_exp = 3;
|
||||
let voxel_scale_lut = array<u32, 4>(
|
||||
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<u32>(floor(pos)), vec3(0), vec3(N * N * N * N - 1));
|
||||
let max = 20.;
|
||||
for(var iter = 0; iter < 60; iter++)
|
||||
{
|
||||
var voxel_pos = vec3<u32>(floor(pos));
|
||||
var child_pos = voxel_pos >> vec3<u32>(scale_exp * 2);
|
||||
var local_child_pos = child_pos & vec3<u32>(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<u32>(scale_exp * 2);
|
||||
local_child_pos = child_pos & vec3<u32>(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<f32>(child_pos * voxel_scale);
|
||||
let cell_max = global_voxel + vec3<f32>(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<u32>(pos + 256) ^ vec3<u32>(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<f32>, root_subdivided: bool, eye_pos: vec3<f32>, ray_dir: vec3<f32>) -> vec4<f32>
|
||||
{
|
||||
@ -215,6 +308,7 @@ fn traverse(max_depth: u32, root_color: vec4<f32>, 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<f32>
|
||||
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<f32>, rayDir: vec3<f32>, boxMin: vec3<f32>, box
|
||||
let tFar = min(min(t2.x, t2.y), t2.z);
|
||||
return vec2(tNear, tFar);
|
||||
};
|
||||
|
||||
fn inferno_quintic( xx: f32 ) -> vec4<f32>
|
||||
{
|
||||
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.);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user