Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolves #45 - implementation of GPU cache #51

Merged
merged 20 commits into from
Dec 8, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,19 @@ authors = ["Dávid Tóth <[email protected]>"]
license = "MIT OR Apache-2.0"

[features]
default = ["dot_vox_support"]
default = ["bevy_wgpu","dot_vox_support"]
raytracing = ["dep:image", "dep:show-image"]
serialization = ["dep:serde"]
dot_vox_support = ["dep:dot_vox", "dep:nalgebra"]
bevy_wgpu = ["raytracing", "dep:bevy", "dep:iyes_perf_ui"]
bevy_wgpu = ["raytracing", "dep:bevy", "dep:iyes_perf_ui", "dep:crossbeam"]

[dependencies]
num-traits = "0.2.19"
serde = { version = "1.0.183", features = ["derive"], optional = true }
bendy = { git = "https://github.com/davids91/bendy.git" , features = ["std", "serde"]}
dot_vox = { version = "5.1.1", optional = true }
nalgebra = { version = "0.33.0", optional = true }
crossbeam = { version = "0.8.4", optional = true }

# for example cpu_render
image = { version = "0.25.1", optional = true }
Expand Down
101 changes: 77 additions & 24 deletions assets/shaders/viewport_render.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,31 @@ fn dda_step_to_next_sibling(
return result;
}

// Unique to this implementation, not adapted from rust code
/// Sets the bit true for the current not under the corresponding bitmask
/// bitmask for node: 0x00000001u
/// bitmask for brick: 0x00000002u
fn set_element_used(node_key: u32, mask: u32) {
var current_value: u32;
var target_value: u32;

if 0 < (nodes[node_key] & mask) // no need to set if already true
{
return;
}

loop{
current_value = nodes[node_key];
target_value = nodes[node_key] | mask;
let exchange_result = atomicCompareExchangeWeak(
&nodes[node_key], current_value, target_value
);
if(exchange_result.exchanged || 0 < (exchange_result.old_value & mask)){
break;
}
}
}

//crate::spatial::math::step_octant
fn step_octant(octant: u32, step: ptr<function, vec3f>) -> u32 {
return (
Expand Down Expand Up @@ -270,7 +295,7 @@ fn traverse_brick(
ray_scale_factors: ptr<function, vec3f>,
direction_lut_index: u32,
) -> BrickHit {
let dimension = i32(octreeMetaData.voxel_brick_dim);
let dimension = i32(octree_meta_data.voxel_brick_dim);

var current_index = clamp(
vec3i(vec3f( // entry position in brick
Expand Down Expand Up @@ -352,8 +377,13 @@ fn probe_brick(
ray_scale_factors: ptr<function, vec3f>,
direction_lut_index: u32,
) -> OctreeRayIntersection {
let brick_start_index = node_children[((leaf_node_key * 8) + brick_octant)];
//set_element_used(brick_start_index, 0x00000002u);
// +++ DEBUG +++
if(0 == nodes[arrayLength(&nodes) - 1]){
set_element_used(brick_start_index, 0x00000002u);
}
if(0 != ((0x01u << (8 + brick_octant)) & nodes[leaf_node_key])) { // brick is not empty
let brick_start_index = children_buffer[((leaf_node_key * 8) + brick_octant)];
if(0 == ((0x01u << (16 + brick_octant)) & nodes[leaf_node_key])) { // brick is solid
// Whole brick is solid, ray hits it at first connection
return OctreeRayIntersection(
Expand All @@ -370,22 +400,45 @@ fn probe_brick(
brick_bounds, ray_scale_factors, direction_lut_index
);
if leaf_brick_hit.hit == true {

/// +++ DEBUG +++
var result_rgb = color_palette[voxels[leaf_brick_hit.flat_index].albedo_index];
if 0 < (nodes[brick_start_index] & 0x00000002u) {
result_rgb.r += 0.2;
}
return OctreeRayIntersection(
true,
color_palette[voxels[leaf_brick_hit.flat_index].albedo_index],
result_rgb,
voxels[leaf_brick_hit.flat_index].content,
point_in_ray_at_distance(ray, *ray_current_distance),
cube_impact_normal(
Cube(
(*brick_bounds).min_position + (
vec3f(leaf_brick_hit.index)
* round((*brick_bounds).size / f32(octree_meta_data.voxel_brick_dim))
),
round((*brick_bounds).size / f32(octree_meta_data.voxel_brick_dim)),
),
point_in_ray_at_distance(ray, *ray_current_distance)
)
);
/*return OctreeRayIntersection(
true,
result_rgb, //color_palette[voxels[leaf_brick_hit.flat_index].albedo_index],
voxels[leaf_brick_hit.flat_index].content,
point_in_ray_at_distance(ray, *ray_current_distance),
cube_impact_normal(
Cube(
(*brick_bounds).min_position + (
vec3f(leaf_brick_hit.index)
* round((*brick_bounds).size / f32(octreeMetaData.voxel_brick_dim))
* round((*brick_bounds).size / f32(octree_meta_data.voxel_brick_dim))
),
round((*brick_bounds).size / f32(octreeMetaData.voxel_brick_dim)),
round((*brick_bounds).size / f32(octree_meta_data.voxel_brick_dim)),
),
point_in_ray_at_distance(ray, *ray_current_distance)
)
);
*//// --- DEBUG ---
}
}
}
Expand All @@ -400,7 +453,7 @@ fn get_by_ray(ray: ptr<function, Line>) -> OctreeRayIntersection{
var node_stack: array<u32, NODE_STACK_SIZE>;
var node_stack_meta: u32 = 0;
var ray_current_distance = 0.0;
var current_bounds = Cube(vec3(0.), f32(octreeMetaData.octree_size));
var current_bounds = Cube(vec3(0.), f32(octree_meta_data.octree_size));
var current_node_key = EMPTY_MARKER;
var current_node_meta = 0u;
var target_octant = OOB_OCTANT;
Expand All @@ -422,23 +475,24 @@ fn get_by_ray(ray: ptr<function, Line>) -> OctreeRayIntersection{
while target_octant != OOB_OCTANT {
/*// +++ DEBUG +++
outer_safety += 1;
if(f32(outer_safety) > f32(octreeMetaData.octree_size) * sqrt(3.)) {
if(f32(outer_safety) > f32(octree_meta_data.octree_size) * sqrt(3.)) {
return OctreeRayIntersection(
true, vec4f(1.,0.,0.,1.), 0, vec3f(0.), vec3f(0., 0., 1.)
);
}
*/ // --- DEBUG ---
current_node_key = OCTREE_ROOT_NODE_KEY;
current_node_meta = nodes[OCTREE_ROOT_NODE_KEY];
current_bounds = Cube(vec3(0.), f32(octreeMetaData.octree_size));
current_bounds = Cube(vec3(0.), f32(octree_meta_data.octree_size));
node_stack_push(&node_stack, &node_stack_meta, OCTREE_ROOT_NODE_KEY);
/*// +++ DEBUG +++
var safety = 0;
*/// --- DEBUG ---
while(!node_stack_is_empty(node_stack_meta)) {
//set_element_used(current_node_key, 0x00000001u);
/*// +++ DEBUG +++
safety += 1;
if(f32(safety) > f32(octreeMetaData.octree_size) * sqrt(30.)) {
if(f32(safety) > f32(octree_meta_data.octree_size) * sqrt(30.)) {
return OctreeRayIntersection(
true, vec4f(0.,0.,1.,1.), 0, vec3f(0.), vec3f(0., 0., 1.)
);
Expand Down Expand Up @@ -533,7 +587,7 @@ fn get_by_ray(ray: ptr<function, Line>) -> OctreeRayIntersection{
}

target_bounds = child_bounds_for(&current_bounds, target_octant);
var target_child_key = children_buffer[(current_node_key * 8) + target_octant];
var target_child_key = node_children[(current_node_key * 8) + target_octant];
if (
(
0 == (0x00000004 & current_node_meta) // node is not a leaf
Expand Down Expand Up @@ -589,7 +643,7 @@ fn get_by_ray(ray: ptr<function, Line>) -> OctreeRayIntersection{
target_octant = step_octant(target_octant, &step_vec);
if OOB_OCTANT != target_octant {
target_bounds = child_bounds_for(&current_bounds, target_octant);
target_child_key = children_buffer[(current_node_key * 8) + target_octant];
target_child_key = node_children[(current_node_key * 8) + target_octant];
bitmap_pos_in_node += step_vec * 4. / current_bounds.size;
}
if (
Expand Down Expand Up @@ -633,15 +687,15 @@ fn get_by_ray(ray: ptr<function, Line>) -> OctreeRayIntersection{
+ step_vec * current_bounds.size
);
if(
current_octant_center.x < f32(octreeMetaData.octree_size)
&& current_octant_center.y < f32(octreeMetaData.octree_size)
&& current_octant_center.z < f32(octreeMetaData.octree_size)
current_octant_center.x < f32(octree_meta_data.octree_size)
&& current_octant_center.y < f32(octree_meta_data.octree_size)
&& current_octant_center.z < f32(octree_meta_data.octree_size)
&& current_octant_center.x > 0.
&& current_octant_center.y > 0.
&& current_octant_center.z > 0.
) {
target_octant = hash_region(
current_octant_center, f32(octreeMetaData.octree_size) / 2.
current_octant_center, f32(octree_meta_data.octree_size) / 2.
);
} else {
target_octant = OOB_OCTANT;
Expand Down Expand Up @@ -686,19 +740,19 @@ var output_texture: texture_storage_2d<rgba8unorm, read_write>;
var<uniform> viewport: Viewport;

@group(1) @binding(0)
var<uniform> octreeMetaData: OctreeMetaData;
var<uniform> octree_meta_data: OctreeMetaData;

@group(1) @binding(1)
var<storage, read_write> nodes: array<u32>;
var<storage, read_write> nodes: array<atomic<u32>>;

@group(1) @binding(2)
var<storage, read_write> children_buffer: array<u32>;
var<storage, read_write> node_children: array<u32>;

@group(1) @binding(3)
var<storage, read_write> voxels: array<Voxelement>;
var<storage, read_write> node_occupied_bits: array<u32>;

@group(1) @binding(4)
var<storage, read_write> node_occupied_bits: array<u32>;
var<storage, read_write> voxels: array<Voxelement>;

@group(1) @binding(5)
var<storage, read_write> color_palette: array<vec4f>;
Expand Down Expand Up @@ -740,13 +794,13 @@ fn update(
}

/*// +++ DEBUG +++
var root_bounds = Cube(vec3(0.,0.,0.), f32(octreeMetaData.octree_size));
var root_bounds = Cube(vec3(0.,0.,0.), f32(octree_meta_data.octree_size));
let root_intersect = cube_intersect_ray(root_bounds, &ray);
if root_intersect.hit == true {
// Display the xyz axes
if root_intersect. impact_hit == true {
let axes_length = f32(octreeMetaData.octree_size) / 2.;
let axes_width = f32(octreeMetaData.octree_size) / 50.;
let axes_length = f32(octree_meta_data.octree_size) / 2.;
let axes_width = f32(octree_meta_data.octree_size) / 50.;
let entry_point = point_in_ray_at_distance(&ray, root_intersect.impact_distance);
if entry_point.x < axes_length && entry_point.y < axes_width && entry_point.z < axes_width {
rgb_result.r = 1.;
Expand All @@ -761,7 +815,6 @@ fn update(
//rgb_result.b += 0.1; // Also color in the area of the octree
}
*/// --- DEBUG ---

textureStore(output_texture, vec2u(invocation_id.xy), vec4f(rgb_result, 1.));
}

Expand Down
23 changes: 16 additions & 7 deletions examples/minecraft.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ use bevy::{prelude::*, window::WindowPlugin};
#[cfg(feature = "bevy_wgpu")]
use shocovox_rs::octree::{
raytracing::{
bevy::create_viewing_glass, Ray, ShocoVoxRenderPlugin, ShocoVoxViewingGlass, Viewport,
bevy::create_viewing_glass, Ray, ShocoVoxRenderData, ShocoVoxRenderPlugin,
ShocoVoxViewingGlass, Viewport,
},
Albedo, V3c, VoxelData,
};
Expand Down Expand Up @@ -78,11 +79,6 @@ fn setup(mut commands: Commands, images: ResMut<Assets<Image>>) {
tree.save(&tree_path).ok().unwrap();
}

let origin = V3c::new(
tree.get_size() as f32 * 2.,
tree.get_size() as f32 / 2.,
tree.get_size() as f32 * -2.,
);
commands.spawn(DomePosition {
yaw: 0.,
roll: 0.,
Expand All @@ -92,7 +88,11 @@ fn setup(mut commands: Commands, images: ResMut<Assets<Image>>) {
let render_data = tree.create_bevy_view();
let viewing_glass = create_viewing_glass(
&Viewport {
origin,
origin: V3c {
x: 0.,
y: 0.,
z: 0.,
},
direction: V3c {
x: 0.,
y: 0.,
Expand Down Expand Up @@ -164,9 +164,15 @@ fn rotate_camera(
fn handle_zoom(
keys: Res<ButtonInput<KeyCode>>,
mut viewing_glass: ResMut<ShocoVoxViewingGlass>,
svx_data: Option<ResMut<ShocoVoxRenderData>>,
mut angles_query: Query<&mut DomePosition>,
tree: Res<TreeResource<Albedo, BRICK_DIMENSION>>,
) {
if let Some(ref svx_data) = svx_data {
if svx_data.is_changed() {
println!("changed!! --> {:?}", svx_data.node_children[0..2].to_vec());
davids91 marked this conversation as resolved.
Show resolved Hide resolved
}
}
const ADDITION: f32 = 0.05;
let angle_update_fn = |angle, delta| -> f32 {
let new_angle = angle + delta;
Expand Down Expand Up @@ -270,6 +276,9 @@ fn handle_zoom(
viewing_glass.viewport.w_h_fov.x *= 1. - 0.09 * multiplier;
viewing_glass.viewport.w_h_fov.y *= 1. - 0.09 * multiplier;
}
if keys.pressed(KeyCode::Delete) {
svx_data.unwrap().do_the_thing = true;
}
}

#[cfg(not(feature = "bevy_wgpu"))]
Expand Down
4 changes: 2 additions & 2 deletions src/octree/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ where
/// Provides immutable reference to the data, if there is any at the given position
pub fn get(&self, position: &V3c<u32>) -> Option<&T> {
let mut current_bounds = Cube::root_bounds(self.octree_size as f32);
let mut current_node_key = Octree::<T, DIM>::ROOT_NODE_KEY as usize;
let mut current_node_key = Self::ROOT_NODE_KEY as usize;
let position = V3c::from(*position);
if !bound_contains(&current_bounds, &position) {
return None;
Expand Down Expand Up @@ -248,7 +248,7 @@ where
/// Provides mutable reference to the data, if there is any at the given position
pub fn get_mut(&mut self, position: &V3c<u32>) -> Option<&mut T> {
let mut current_bounds = Cube::root_bounds(self.octree_size as f32);
let mut current_node_key = Octree::<T, DIM>::ROOT_NODE_KEY as usize;
let mut current_node_key = Self::ROOT_NODE_KEY as usize;
let position = V3c::from(*position);
if !bound_contains(&current_bounds, &position) {
return None;
Expand Down
Loading
Loading