Skip to content

Commit

Permalink
Updated bevy module to not copy octree data to GPU in every loop
Browse files Browse the repository at this point in the history
  • Loading branch information
davids91 committed Jul 11, 2024
1 parent d0f100d commit af1ae63
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 41 deletions.
16 changes: 9 additions & 7 deletions assets/shaders/viewport_render.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,6 @@ fn traverse_brick(
) -> BrickHit{
var result: BrickHit;
result.hit = false;

let pos = (
point_in_ray_at_distance(ray, *ray_current_distance)
- bounds.min_position
Expand Down Expand Up @@ -469,7 +468,10 @@ fn get_by_ray(ray_: Line) -> OctreeRayIntersection{
);
node_stack_i = 1;
}

var i = 0.;
while(0 < node_stack_i && node_stack_i < max_depth) {
i += 1.;
var current_bounds = node_stack[node_stack_i - 1].bounds;
var current_node = nodes[node_stack[node_stack_i - 1].node]; //!NOTE: should be const, but then it can not be indexed dynamically
var target_octant = node_stack[node_stack_i - 1].target_octant;
Expand Down Expand Up @@ -630,22 +632,22 @@ struct Viewport {
fov: f32,
}

@group(0) @binding(1)
@group(0) @binding(0)
var output_texture: texture_storage_2d<rgba8unorm, read_write>;

@group(0) @binding(2)
@group(0) @binding(1)
var<uniform> viewport: Viewport;

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

@group(0) @binding(4)
@group(1) @binding(1)
var<storage, read_write> nodes: array<SizedNode>;

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

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

@compute @workgroup_size(8, 8, 1)
Expand Down
14 changes: 11 additions & 3 deletions examples/bevy_wgpu_render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ fn main() {

#[cfg(feature = "bevy_wgpu")]
fn setup(mut commands: Commands, images: ResMut<Assets<Image>>) {
use shocovox_rs::octree::raytracing::bevy::create_viewing_glass;

let origin = Vec3::new(
ARRAY_DIMENSION as f32 * 2.,
ARRAY_DIMENSION as f32 / 2.,
Expand Down Expand Up @@ -74,15 +76,19 @@ fn setup(mut commands: Commands, images: ResMut<Assets<Image>>) {
};
tree.insert(
&V3c::new(x, y, z),
Albedo::from(r | (g << 8) | (b << 16) | 0xFF000000),
Albedo::default()
.with_red(r as u8)
.with_green(g as u8)
.with_blue(b as u8),
)
.ok()
.unwrap();
}
}
}
}
let viewing_glass = tree.create_bevy_view(
let render_data = tree.create_bevy_view();
let viewing_glass = create_viewing_glass(
&Viewport {
direction: (Vec3::new(0., 0., 0.) - origin).normalize(),
origin,
Expand All @@ -92,6 +98,7 @@ fn setup(mut commands: Commands, images: ResMut<Assets<Image>>) {
DISPLAY_RESOLUTION,
images,
);

commands.spawn(SpriteBundle {
sprite: Sprite {
custom_size: Some(Vec2::new(1024., 768.)),
Expand All @@ -101,6 +108,7 @@ fn setup(mut commands: Commands, images: ResMut<Assets<Image>>) {
..default()
});
commands.spawn(Camera2dBundle::default());
commands.insert_resource(render_data);
commands.insert_resource(viewing_glass);
}

Expand All @@ -116,7 +124,7 @@ fn rotate_camera(
mut viewing_glass: ResMut<ShocoVoxViewingGlass>,
) {
let angle = {
let addition = ARRAY_DIMENSION as f32 / 10.;
let addition = ARRAY_DIMENSION as f32 / 100000.;
let angle = angles_query.single().yaw + addition;
if angle < 360. {
angle
Expand Down
20 changes: 4 additions & 16 deletions src/octree/raytracing/bevy/data.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
use crate::object_pool::empty_marker;

use crate::octree::{
raytracing::{
bevy::create_ouput_texture,
bevy::types::{OctreeMetaData, ShocoVoxViewingGlass, SizedNode, Viewport, Voxelement},
},
raytracing::bevy::types::{OctreeMetaData, ShocoVoxRenderData, SizedNode, Voxelement},
types::{NodeChildrenArray, NodeContent},
Octree, VoxelData,
};

use bevy::{
asset::Assets, ecs::system::ResMut, math::Vec3, render::color::Color, render::texture::Image,
};
use bevy::{math::Vec3, render::color::Color};

impl<T, const DIM: usize> Octree<T, DIM>
where
Expand Down Expand Up @@ -49,12 +44,7 @@ where
meta
}

pub fn create_bevy_view(
&self,
viewport: &Viewport,
resolution: [u32; 2],
images: ResMut<Assets<Image>>,
) -> ShocoVoxViewingGlass {
pub fn create_bevy_view(&self) -> ShocoVoxRenderData {
let meta = OctreeMetaData {
octree_size: self.octree_size,
voxel_brick_dim: DIM as u32,
Expand Down Expand Up @@ -115,9 +105,7 @@ where
nodes.push(sized_node);
}

ShocoVoxViewingGlass {
output_texture: create_ouput_texture(resolution, images),
viewport: *viewport,
ShocoVoxRenderData {
meta,
nodes,
children_buffer,
Expand Down
52 changes: 44 additions & 8 deletions src/octree/raytracing/bevy/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pub use crate::octree::raytracing::bevy::types::{
};

use crate::octree::raytracing::bevy::types::{
ShocoVoxLabel, ShocoVoxRenderNode, ShocoVoxRenderPipeline,
ShocoVoxLabel, ShocoVoxRenderData, ShocoVoxRenderNode, ShocoVoxRenderPipeline,
};

use bevy::{
Expand All @@ -32,38 +32,57 @@ use bevy::{

use std::borrow::Cow;

pub fn create_viewing_glass(
viewport: &Viewport,
resolution: [u32; 2],
images: ResMut<Assets<Image>>,
) -> ShocoVoxViewingGlass {
ShocoVoxViewingGlass {
output_texture: create_ouput_texture(resolution, images),
viewport: *viewport,
}
}

impl FromWorld for ShocoVoxRenderPipeline {
fn from_world(world: &mut World) -> Self {
let render_device = world.resource::<RenderDevice>();
let viewing_glass_bind_group_layout =
ShocoVoxViewingGlass::bind_group_layout(render_device);
let render_data_bind_group_layout = ShocoVoxRenderData::bind_group_layout(render_device);
let shader = world
.resource::<AssetServer>()
.load("shaders/viewport_render.wgsl");
let pipeline_cache = world.resource::<PipelineCache>();
let update_pipeline = pipeline_cache.queue_compute_pipeline(ComputePipelineDescriptor {
label: None,
layout: vec![viewing_glass_bind_group_layout.clone()],
layout: vec![
viewing_glass_bind_group_layout.clone(),
render_data_bind_group_layout.clone(),
],
push_constant_ranges: Vec::new(),
shader,
shader_defs: vec![],
entry_point: Cow::from("update"),
});

ShocoVoxRenderPipeline {
update_tree: true,
viewing_glass_bind_group_layout,
render_data_bind_group_layout,
update_pipeline,
bind_group: None,
viewing_glass_bind_group: None,
tree_bind_group: None,
}
}
}

fn prepare_bind_group(
fn prepare_bind_groups(
gpu_images: Res<RenderAssets<Image>>,
fallback_image: Res<FallbackImage>,
render_device: Res<RenderDevice>,
mut pipeline: ResMut<ShocoVoxRenderPipeline>,
octree_viewing_glass: Res<ShocoVoxViewingGlass>,
render_data: Res<ShocoVoxRenderData>,
) {
let bind_group = octree_viewing_glass
.as_bind_group(
Expand All @@ -74,7 +93,21 @@ fn prepare_bind_group(
)
.ok()
.unwrap();
pipeline.bind_group = Some(bind_group.bind_group);
pipeline.viewing_glass_bind_group = Some(bind_group.bind_group);

if pipeline.update_tree {
let tree_bind_group = render_data
.as_bind_group(
&pipeline.render_data_bind_group_layout,
&render_device,
&gpu_images,
&fallback_image,
)
.ok()
.unwrap();
pipeline.tree_bind_group = Some(tree_bind_group.bind_group);
pipeline.update_tree = false;
}
}

pub(crate) fn create_ouput_texture(
Expand All @@ -100,10 +133,11 @@ pub(crate) fn create_ouput_texture(
impl Plugin for ShocoVoxRenderPlugin {
fn build(&self, app: &mut App) {
app.add_plugins(ExtractResourcePlugin::<ShocoVoxViewingGlass>::default());
app.add_plugins(ExtractResourcePlugin::<ShocoVoxRenderData>::default());
let render_app = app.sub_app_mut(RenderApp);
render_app.add_systems(
Render,
prepare_bind_group.in_set(RenderSet::PrepareBindGroups),
prepare_bind_groups.in_set(RenderSet::PrepareBindGroups),
);

let mut render_graph = render_app.world.resource_mut::<RenderGraph>();
Expand All @@ -127,12 +161,13 @@ const WORKGROUP_SIZE: u32 = 8;
impl render_graph::Node for ShocoVoxRenderNode {
fn update(&mut self, world: &mut World) {
let pipeline = world.resource::<ShocoVoxRenderPipeline>();
let render_data = world.get_resource::<ShocoVoxRenderData>();
let pipeline_cache = world.resource::<PipelineCache>();
if !self.ready {
if let CachedPipelineState::Ok(_) =
pipeline_cache.get_compute_pipeline_state(pipeline.update_pipeline)
{
self.ready = true;
self.ready = render_data.is_some();
}
}
}
Expand All @@ -151,7 +186,8 @@ impl render_graph::Node for ShocoVoxRenderNode {
.command_encoder()
.begin_compute_pass(&ComputePassDescriptor::default());

pass.set_bind_group(0, pipeline.bind_group.as_ref().unwrap(), &[]);
pass.set_bind_group(0, pipeline.viewing_glass_bind_group.as_ref().unwrap(), &[]);
pass.set_bind_group(1, pipeline.tree_bind_group.as_ref().unwrap(), &[]);
let pipeline = pipeline_cache
.get_compute_pipeline(pipeline.update_pipeline)
.unwrap();
Expand Down
21 changes: 14 additions & 7 deletions src/octree/raytracing/bevy/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,30 +77,37 @@ pub struct ShocoVoxRenderPlugin {
#[derive(Resource, Clone, AsBindGroup, TypePath, ExtractResource)]
#[type_path = "shocovox::gpu::ShocoVoxViewingGlass"]
pub struct ShocoVoxViewingGlass {
#[storage_texture(1, image_format = Rgba8Unorm, access = ReadWrite)]
#[storage_texture(0, image_format = Rgba8Unorm, access = ReadWrite)]
pub output_texture: Handle<Image>,

#[uniform(2, visibility(compute))]
#[uniform(1, visibility(compute))]
pub viewport: Viewport,
}

#[uniform(3, visibility(compute))]
#[derive(Resource, Clone, AsBindGroup, TypePath, ExtractResource)]
#[type_path = "shocovox::gpu::ShocoVoxRenderData"]
pub struct ShocoVoxRenderData {
#[uniform(0, visibility(compute))]
pub(crate) meta: OctreeMetaData,

#[storage(4, visibility(compute))]
#[storage(1, visibility(compute))]
pub(crate) nodes: Vec<SizedNode>,

#[storage(5, visibility(compute))]
#[storage(2, visibility(compute))]
pub(crate) children_buffer: Vec<u32>,

#[storage(6, visibility(compute))]
#[storage(3, visibility(compute))]
pub(crate) voxels: Vec<Voxelement>,
}

#[derive(Resource)]
pub(crate) struct ShocoVoxRenderPipeline {
pub update_tree: bool,
pub(crate) viewing_glass_bind_group_layout: BindGroupLayout,
pub(crate) render_data_bind_group_layout: BindGroupLayout,
pub(crate) update_pipeline: CachedComputePipelineId,
pub(crate) bind_group: Option<BindGroup>,
pub(crate) viewing_glass_bind_group: Option<BindGroup>,
pub(crate) tree_bind_group: Option<BindGroup>,
}

#[derive(Debug, Hash, PartialEq, Eq, Clone, RenderLabel)]
Expand Down

0 comments on commit af1ae63

Please sign in to comment.