diff --git a/README.md b/README.md index 111a160f..11f4d417 100644 --- a/README.md +++ b/README.md @@ -8,10 +8,11 @@ [![Average time to resolve an issue](https://isitmaintained.com/badge/resolution/mosure/bevy_gaussian_splatting.svg)](http://isitmaintained.com/project/mosure/bevy_gaussian_splatting) [![crates.io](https://img.shields.io/crates/v/bevy_gaussian_splatting.svg)](https://crates.io/crates/bevy_gaussian_splatting) -![Alt text](docs/notferris.png) - bevy gaussian splatting render pipeline plugin +![Alt text](docs/notferris.png) +![Alt text](docs/bike.png) + `cargo run -- scenes/icecream.gcloud` ## capabilities @@ -69,7 +70,7 @@ to build wasm run: | `bevy_gaussian_splatting` | `bevy` | | :-- | :-- | -| `0.1` | `0.11` | +| `0.1 - 0.3` | `0.11` | # credits diff --git a/docs/bike.png b/docs/bike.png new file mode 100644 index 00000000..a4cf22e0 Binary files /dev/null and b/docs/bike.png differ diff --git a/src/render/gaussian.wgsl b/src/render/gaussian.wgsl index ab2fce92..71ecd4fd 100644 --- a/src/render/gaussian.wgsl +++ b/src/render/gaussian.wgsl @@ -296,7 +296,11 @@ fn temporal_sort_flop( // https://github.com/cvlab-epfl/gaussian-splatting-web/blob/905b3c0fb8961e42c79ef97e64609e82383ca1c2/src/shaders.ts#L185 // TODO: precompute fn compute_cov3d(scale: vec3, rotation: vec4) -> array { - let S = scale * uniforms.global_scale; + let S = mat3x3( + scale.x * uniforms.global_scale, 0.0, 0.0, + 0.0, scale.y * uniforms.global_scale, 0.0, + 0.0, 0.0, scale.z * uniforms.global_scale, + ); let r = rotation.x; let x = rotation.y; @@ -317,12 +321,7 @@ fn compute_cov3d(scale: vec3, rotation: vec4) -> array { 1.0 - 2.0 * (x * x + y * y), ); - let M = mat3x3( - S[0] * R.x, - S[1] * R.y, - S[2] * R.z, - ); - + let M = S * R; let Sigma = transpose(M) * M; return array( @@ -345,18 +344,16 @@ fn compute_cov2d(position: vec3, scale: vec3, rotation: vec4) -> var t = view.inverse_view * vec4(position, 1.0); -#ifdef USE_AABB - let focal_x = view.viewport.z / (2.0 * view.projection[0][0]); - let focal_y = view.viewport.w / (2.0 * view.projection[1][1]); -#endif + let focal_x = 600.0; + let focal_y = 600.0; -#ifdef USE_OBB - let focal_x = view.viewport.z / (2.0 * view.inverse_projection[0][0]); - let focal_y = view.viewport.w / (2.0 * view.inverse_projection[1][1]); -#endif + let fovy = 2.0 * atan(1.0 / view.projection[1][1]); + let fovx = 2.0 * atan(1.0 / view.projection[0][0]); + let tan_fovy = tan(fovy * 0.5); + let tan_fovx = tan(fovx * 0.5); - let limx = 1.3 * 0.5 * view.viewport.z / focal_x; - let limy = 1.3 * 0.5 * view.viewport.w / focal_y; + let limx = 1.3 * tan_fovx; + let limy = 1.3 * tan_fovy; let txtz = t.x / t.z; let tytz = t.y / t.z; t.x = min(limx, max(-limx, txtz)) * t.z; @@ -368,13 +365,12 @@ fn compute_cov2d(position: vec3, scale: vec3, rotation: vec4) -> -(focal_x * t.x) / (t.z * t.z), 0.0, - focal_y / t.z, - -(focal_y * t.y) / (t.z * t.z), + -focal_y / t.z, + (focal_y * t.y) / (t.z * t.z), 0.0, 0.0, 0.0, ); -#ifdef USE_AABB let W = transpose( mat3x3( view.inverse_view.x.xyz, @@ -382,17 +378,6 @@ fn compute_cov2d(position: vec3, scale: vec3, rotation: vec4) -> view.inverse_view.z.xyz, ) ); -#endif - -#ifdef USE_OBB - let W = transpose( - mat3x3( - view.inverse_view.x.xyz, - view.inverse_view.y.xyz, - view.inverse_view.z.xyz, - ) - ); -#endif let T = W * J; diff --git a/src/render/mod.rs b/src/render/mod.rs index ca513965..a7540d6d 100644 --- a/src/render/mod.rs +++ b/src/render/mod.rs @@ -535,11 +535,9 @@ impl Default for ShaderDefines { let workgroup_entries_a = workgroup_invocations_a * entries_per_invocation_a; let workgroup_entries_c = workgroup_invocations_c * entries_per_invocation_c; let max_tile_count_c = (10000000 + workgroup_entries_c - 1) / workgroup_entries_c; - let sorting_buffer_size = ( - radix_base as usize * + let sorting_buffer_size = radix_base as usize * (radix_digit_places as usize + max_tile_count_c as usize) * - std::mem::size_of::() - ) + std::mem::size_of::() * 5; + std::mem::size_of::() + 5 * std::mem::size_of::(); Self { radix_bits_per_digit, @@ -1126,16 +1124,23 @@ impl render_graph::Node for RadixSortNode { let radix_digit_places = ShaderDefines::default().radix_digit_places; - command_encoder.clear_buffer( - &cloud.sorting_global_buffer, - 0, - None, - ); + { + command_encoder.clear_buffer( + &cloud.sorting_global_buffer, + 0, + None, + ); + + command_encoder.clear_buffer( + &cloud.draw_indirect_buffer, + 0, + None, + ); + } { let mut pass = command_encoder.begin_compute_pass(&ComputePassDescriptor::default()); - // TODO: view/global pass.set_bind_group( 0, &view_bind_group.value, @@ -1172,11 +1177,12 @@ impl render_graph::Node for RadixSortNode { for pass_idx in 0..radix_digit_places { if pass_idx > 0 { - let size = ShaderDefines::default().radix_base * ShaderDefines::default().max_tile_count_c * std::mem::size_of::() as u32; + // clear SortingGlobal.status_counters + let size = (ShaderDefines::default().radix_base * ShaderDefines::default().max_tile_count_c) as u64 * std::mem::size_of::() as u64; command_encoder.clear_buffer( &cloud.sorting_global_buffer, 0, - std::num::NonZeroU64::new(size as u64).unwrap().into() + std::num::NonZeroU64::new(size).unwrap().into() ); }