This is the related code running on the gpu, written in wgsl.
The render looks less detailed and the voxels appear bigger then they should.
This is what my render looks like:
And this is the render by MagicaVoxel:
This is what my octree looks like gpu side:
struct Octree {
root: array<u32, 3>,
width: u32,
}
struct Leaf {
voxel: OctreeVoxel,
children: array<u32, 8>,
}
struct OctreeVoxel {
id: u32,
color: vec3<f32>,
}
//this is used only during the traversing and it not part of the octree
struct Oct {
root: array<u32, 3>,
width: u32,
leaf_index: u32,
}
this is the function that gets the color of the pixel:
fn get_pixel_color(ray: Ray) -> vec4<f32> {
let inv_direction = vec3<f32>(1.0/ray.direction.x, 1.0/ray.direction.y, 1.0/ray.direction.z); //pre calc the inv of ray direction
let aabb_ray = AabbRay(ray.start, ray.direction, inv_direction);
var found_voxel_color = vec4<f32>(0.0, 0.0, 0.0, 1.0); // Default color for no hit
var dist = 1e6;
//prepare the holder of octs
var stack: array<Oct, STACKSIZE>;
var stack_size = 0u;
stack[stack_size] = Oct(octree.root, octree.width, 0u);
stack_size ++;
while stack_size > 0u {
stack_size --;
let cur_oct = stack[stack_size];
var root = cur_oct.root;
var width = cur_oct.width;
var node = leaves[cur_oct.leaf_index];
for (var i = 0u; i < 8; i++) {
let r = get_new_root(i, root, width);
let w = width;
if distance(vec3<f32>(f32(r[0]), f32(r[1]), f32(r[2])), ray.start) < dist {
let box = Aabb(vec3<f32>(f32(r[0] - (w / 2)), f32(r[1] - (w / 2)), f32(r[2] - (w / 2))), vec3<f32>(f32(r[0] + (w / 2)), f32(r[1] + (w / 2)), f32(r[2] + (w / 2))));
let intersection = ray_box_intersect(aabb_ray, box);
if intersection.x < intersection.y {
if node.children[i] != U32MAX {
let child_index = node.children[i];
let child_node = leaves[child_index];
if child_node.voxel.id != 0 && intersection.x < dist{
dist = intersection.x;
found_voxel_color = vec4<f32>(child_node.voxel.color[0], child_node.voxel.color[1], child_node.voxel.color[2], 1.0);
} else {
stack[stack_size] = Oct(get_new_root(i, root, width), width / 2u, child_index);
stack_size++;
}
}
}
}
}
}
//return the color it detected
return found_voxel_color;
}
and lastly the ray-aabb intersection test:
fn ray_box_intersect(r: AabbRay, b: Aabb) -> vec2<f32> {
var tmin = 0.0;
var tmax = 1e6;
for (var d = 0; d < 3; d++) {
let t1 = (b.min[d] - r.start[d]) * r.inv_direction[d];
let t2 = (b.max[d] - r.start[d]) * r.inv_direction[d];
tmin = max(tmin, min(min(t1, t2), tmax));
tmax = min(tmax, max(max(t1, t2), tmin));
}
return vec2<f32>(tmin, tmax);
}
So to recap my question is:
Why the loss in detail and how would i fix this?