diff --git a/client/assets/shaders/chunk_visibility.wgsl b/client/assets/shaders/chunk_visibility.wgsl index e25c196..802ccb1 100644 --- a/client/assets/shaders/chunk_visibility.wgsl +++ b/client/assets/shaders/chunk_visibility.wgsl @@ -2,9 +2,9 @@ // Input arrays must match in length and are processed per invocation. struct Params { - centre: vec3; - radius: i32; + centre_radius: vec4; count: u32; + _pad: u32; }; @group(0) @binding(0) var occupied: array>; @@ -19,10 +19,12 @@ fn main(@builtin(global_invocation_id) id: vec3) { if idx >= params.count { return; } let key = occupied[idx]; if spawned[idx] != 0u { return; } - let dx = key.x - params.centre.x; - let dy = key.y - params.centre.y; - let dz = key.z - params.centre.z; - if dx*dx + dy*dy + dz*dz <= params.radius * params.radius { + let centre = params.centre_radius.xyz; + let radius = params.centre_radius.w; + let dx = key.x - centre.x; + let dy = key.y - centre.y; + let dz = key.z - centre.z; + if dx*dx + dy*dy + dz*dz <= radius * radius { let i = atomicAdd(&out_count, 1u); out_keys[i] = key; } diff --git a/client/src/app.rs b/client/src/app.rs index b72c41e..db468e5 100644 --- a/client/src/app.rs +++ b/client/src/app.rs @@ -12,7 +12,7 @@ impl Plugin for AppPlugin { app.add_plugins(crate::plugins::input::input_plugin::InputPlugin); app.add_plugins(WireframePlugin::default()); - app.add_systems(Update, (debug_gizmos)); + app.add_systems(Update, debug_gizmos); app.register_type::>>(); app.register_type::(); } diff --git a/client/src/helper/debug_gizmos.rs b/client/src/helper/debug_gizmos.rs index 5df061c..acdc2f7 100644 --- a/client/src/helper/debug_gizmos.rs +++ b/client/src/helper/debug_gizmos.rs @@ -1,4 +1,3 @@ -use bevy::color::palettes::css::{BLUE, GREEN, RED}; use bevy::prelude::*; pub fn debug_gizmos(mut gizmos: Gizmos) { diff --git a/client/src/plugins/environment/environment_plugin.rs b/client/src/plugins/environment/environment_plugin.rs index 9b21478..5281adc 100644 --- a/client/src/plugins/environment/environment_plugin.rs +++ b/client/src/plugins/environment/environment_plugin.rs @@ -4,7 +4,6 @@ use crate::plugins::environment::systems::voxels::meshing_gpu::{ GpuMeshingWorker, queue_gpu_meshing, }; use bevy_app_compute::prelude::{AppComputePlugin, AppComputeWorkerPlugin}; -use crate::plugins::environment::systems::voxels::queue_systems; use crate::plugins::environment::systems::voxels::queue_systems::process_chunk_queue; use crate::plugins::environment::systems::voxels::visibility_gpu::{ enqueue_visible_chunks_gpu, GpuVisibilityWorker, @@ -14,7 +13,7 @@ use crate::plugins::environment::systems::voxels::structure::{ ChunkBudget, ChunkCullingCfg, ChunkQueue, MeshBufferPool, PrevCameraChunk, SparseVoxelOctree, SpawnedChunks, }; -use bevy::app::{App, Plugin, PreStartup, PreUpdate, Startup}; +use bevy::app::{App, Plugin, Startup}; use bevy::prelude::*; pub struct EnvironmentPlugin; diff --git a/client/src/plugins/environment/systems/voxels/visibility_gpu.rs b/client/src/plugins/environment/systems/voxels/visibility_gpu.rs index 61c6ab6..55e890e 100644 --- a/client/src/plugins/environment/systems/voxels/visibility_gpu.rs +++ b/client/src/plugins/environment/systems/voxels/visibility_gpu.rs @@ -1,15 +1,15 @@ use bevy::prelude::*; use bevy_app_compute::prelude::*; -use super::structure::{ChunkCullingCfg, ChunkQueue, PrevCameraChunk, SpawnedChunks, SparseVoxelOctree}; +use super::structure::{ChunkCullingCfg, ChunkQueue, PrevCameraChunk, SpawnedChunks, SparseVoxelOctree, ChunkKey}; use crate::plugins::environment::systems::voxels::helper::world_to_chunk; #[repr(C)] -#[derive(ShaderType, Copy, Clone, Default)] +#[derive(ShaderType, Copy, Clone, Default, bytemuck::Pod, bytemuck::Zeroable)] pub struct Params { - pub centre: IVec3, - pub radius: i32, + pub centre_radius: [i32; 4], pub count: u32, + pub _pad: u32, } #[derive(TypePath)] @@ -32,7 +32,7 @@ impl ComputeWorker for GpuVisibilityWorker { .add_rw_storage::<[IVec3; 1]>("out_keys", &[IVec3::ZERO; 1]) .add_rw_storage::("out_count", &0u32) .add_uniform("params", &Params::default()) - .add_pass::([1, 1, 1], &["occupied", "spawned", "out_keys", "out_count", "params"]) + .add_pass::([1024, 1, 1], &["occupied", "spawned", "out_keys", "out_count", "params"]) .one_shot() .build() } @@ -51,15 +51,19 @@ pub fn enqueue_visible_chunks_gpu( let Ok(tree) = tree_q.get_single() else { return }; let Ok(cam_tf) = cam_q.get_single() else { return }; let cam_pos = cam_tf.translation(); - let centre = world_to_chunk(tree, cam_pos); - if prev_cam.0 == Some(centre) { return; } - prev_cam.0 = Some(centre); + let centre_key = world_to_chunk(tree, cam_pos); + if prev_cam.0 == Some(centre_key) { return; } + prev_cam.0 = Some(centre_key); if !worker.ready() { return; } - let occupied: Vec = tree.occupied_chunks.iter().copied().collect(); - let mut spawned_flags = Vec::with_capacity(occupied.len()); - for key in &occupied { + let occupied_keys: Vec = tree.occupied_chunks.iter().copied().collect(); + let occupied: Vec = occupied_keys + .iter() + .map(|k| IVec3::new(k.0, k.1, k.2)) + .collect(); + let mut spawned_flags = Vec::with_capacity(occupied_keys.len()); + for key in &occupied_keys { spawned_flags.push(if spawned.0.contains_key(key) { 1u32 } else { 0u32 }); } worker.write_slice("occupied", &occupied); @@ -67,11 +71,18 @@ pub fn enqueue_visible_chunks_gpu( worker.write_slice("out_keys", &vec![IVec3::ZERO; occupied.len()]); worker.write("out_count", &0u32); - let params = Params { centre, radius: cfg.view_distance_chunks, count: occupied.len() as u32 }; + let params = Params { + centre_radius: [ + centre_key.0, + centre_key.1, + centre_key.2, + cfg.view_distance_chunks, + ], + count: occupied.len() as u32, + _pad: 0, + }; worker.write("params", ¶ms); - let workgroups = ((occupied.len() as f32) / 64.0).ceil() as u32; - worker.pass(0).dispatch([workgroups, 1, 1]); worker.execute(); let count: u32 = worker.read("out_count"); @@ -79,7 +90,8 @@ pub fn enqueue_visible_chunks_gpu( queue.keys.clear(); queue.set.clear(); for key in keys.into_iter().take(count as usize) { - queue.keys.push_back(key.into()); - queue.set.insert(key.into()); + let ck = ChunkKey(key.x, key.y, key.z); + queue.keys.push_back(ck); + queue.set.insert(ck); } }