From 7acb01a78b2aa6a11e4166f7c0d19be22f439ef0 Mon Sep 17 00:00:00 2001 From: mosure Date: Sun, 31 Dec 2023 03:19:38 -0600 Subject: [PATCH] fix: sh0 padding --- src/gaussian/cloud.rs | 27 ++++++++++++++++++++------- src/gaussian/rand.rs | 4 ++-- src/material/spherical_harmonics.rs | 21 +++++++++++---------- src/query/sparse.rs | 4 ++-- src/render/bindings.wgsl | 24 ++++++++++++++++++++++++ src/render/texture.rs | 14 +++++++++++--- src/render/texture.wgsl | 8 ++++++++ 7 files changed, 78 insertions(+), 24 deletions(-) diff --git a/src/gaussian/cloud.rs b/src/gaussian/cloud.rs index ed41c759..b8ad4b92 100644 --- a/src/gaussian/cloud.rs +++ b/src/gaussian/cloud.rs @@ -28,6 +28,7 @@ use crate::{ packed::Gaussian, }, material::spherical_harmonics::{ + HALF_SH_COEFF_COUNT, SH_COEFF_COUNT, SphericalHarmonicCoefficients, }, @@ -211,6 +212,23 @@ impl GaussianCloud { pub fn spherical_harmonic_mut(&mut self, index: usize) -> &mut SphericalHarmonicCoefficients { &mut self.spherical_harmonic[index] } + + pub fn resize_to_square(&mut self) { + #[cfg(all(feature = "buffer_texture", feature = "f16"))] + { + self.position_visibility.resize(self.square_len(), PositionVisibility::default()); + self.spherical_harmonic.resize(self.square_len(), SphericalHarmonicCoefficients::default()); + self.rotation_scale_opacity_packed128.resize(self.square_len(), RotationScaleOpacityPacked128::default()); + } + + #[cfg(all(feature = "buffer_texture", feature = "f32"))] + { + self.position_visibility.resize(self.square_len(), PositionVisibility::default()); + self.spherical_harmonic.resize(self.square_len(), SphericalHarmonicCoefficients::default()); + self.rotation.resize(self.square_len(), Rotation::default()); + self.scale_opacity.resize(self.square_len(), ScaleOpacity::default()); + } + } } @@ -290,12 +308,7 @@ impl GaussianCloud { rotation_scale_opacity_packed128, }; - #[cfg(feature = "buffer_texture")] - { - cloud.position_visibility.resize(cloud.square_len(), PositionVisibility::default()); - cloud.spherical_harmonic.resize(cloud.square_len(), SphericalHarmonicCoefficients::default()); - cloud.rotation_scale_opacity_packed128.resize(cloud.square_len(), RotationScaleOpacityPacked128::default()); - } + cloud.resize_to_square(); cloud } @@ -349,7 +362,7 @@ impl GaussianCloud { coefficients: { #[cfg(feature = "f16")] { - let mut coefficients = [0 as u32; SH_COEFF_COUNT / 2]; + let mut coefficients = [0 as u32; HALF_SH_COEFF_COUNT]; for coefficient in coefficients.iter_mut() { let upper = rng.gen_range(-1.0..1.0); diff --git a/src/gaussian/rand.rs b/src/gaussian/rand.rs index 05a4c892..ee84937a 100644 --- a/src/gaussian/rand.rs +++ b/src/gaussian/rand.rs @@ -12,7 +12,7 @@ use crate::{ packed::Gaussian, }, material::spherical_harmonics::{ - SH_COEFF_COUNT, + HALF_SH_COEFF_COUNT, SphericalHarmonicCoefficients, }, }; @@ -43,7 +43,7 @@ impl Distribution for rand::distributions::Standard { coefficients: { #[cfg(feature = "f16")] { - let mut coefficients: [u32; SH_COEFF_COUNT / 2] = [0; SH_COEFF_COUNT / 2]; + let mut coefficients: [u32; HALF_SH_COEFF_COUNT] = [0; HALF_SH_COEFF_COUNT]; for coefficient in coefficients.iter_mut() { let upper = rng.gen_range(-1.0..1.0); let lower = rng.gen_range(-1.0..1.0); diff --git a/src/material/spherical_harmonics.rs b/src/material/spherical_harmonics.rs index a44d7b5f..b27ec3e9 100644 --- a/src/material/spherical_harmonics.rs +++ b/src/material/spherical_harmonics.rs @@ -51,16 +51,17 @@ const fn num_sh_coefficients(degree: usize) -> usize { const SH_DEGREE: usize = 0; #[cfg(not(feature = "web"))] -const SH_DEGREE: usize = 3; +const SH_DEGREE: usize = 0; pub const SH_CHANNELS: usize = 3; pub const SH_COEFF_COUNT_PER_CHANNEL: usize = num_sh_coefficients(SH_DEGREE); pub const SH_COEFF_COUNT: usize = (SH_COEFF_COUNT_PER_CHANNEL * SH_CHANNELS + 3) & !3; -pub const HALF_SH_COEFF_COUNT: usize = ((SH_COEFF_COUNT + 1) & !1) / 2; +pub const HALF_SH_COEFF_COUNT: usize = SH_COEFF_COUNT / 2; +pub const PADDED_HALF_SH_COEFF_COUNT: usize = (HALF_SH_COEFF_COUNT + 3) & !3; #[cfg(feature = "f16")] -pub const SH_VEC4_PLANES: usize = ((HALF_SH_COEFF_COUNT + 3) & !3) / 4; +pub const SH_VEC4_PLANES: usize = PADDED_HALF_SH_COEFF_COUNT / 4; #[cfg(feature = "f32")] pub const SH_VEC4_PLANES: usize = SH_COEFF_COUNT / 4; @@ -82,7 +83,7 @@ pub const SH_VEC4_PLANES: usize = SH_COEFF_COUNT / 4; pub struct SphericalHarmonicCoefficients { #[reflect(ignore)] #[serde(serialize_with = "coefficients_serializer", deserialize_with = "coefficients_deserializer")] - pub coefficients: [u32; SH_COEFF_COUNT / 2], + pub coefficients: [u32; HALF_SH_COEFF_COUNT], } @@ -110,7 +111,7 @@ pub struct SphericalHarmonicCoefficients { impl Default for SphericalHarmonicCoefficients { fn default() -> Self { Self { - coefficients: [0; SH_COEFF_COUNT / 2], + coefficients: [0; HALF_SH_COEFF_COUNT], } } } @@ -145,7 +146,7 @@ impl SphericalHarmonicCoefficients { #[cfg(feature = "f16")] -fn coefficients_serializer(n: &[u32; SH_COEFF_COUNT / 2], s: S) -> Result +fn coefficients_serializer(n: &[u32; HALF_SH_COEFF_COUNT], s: S) -> Result where S: Serializer, { @@ -158,24 +159,24 @@ where } #[cfg(feature = "f16")] -fn coefficients_deserializer<'de, D>(d: D) -> Result<[u32; SH_COEFF_COUNT / 2], D::Error> +fn coefficients_deserializer<'de, D>(d: D) -> Result<[u32; HALF_SH_COEFF_COUNT], D::Error> where D: serde::Deserializer<'de>, { struct CoefficientsVisitor; impl<'de> serde::de::Visitor<'de> for CoefficientsVisitor { - type Value = [u32; SH_COEFF_COUNT / 2]; + type Value = [u32; HALF_SH_COEFF_COUNT]; fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { formatter.write_str("an array of floats") } - fn visit_seq(self, mut seq: A) -> Result<[u32; SH_COEFF_COUNT / 2], A::Error> + fn visit_seq(self, mut seq: A) -> Result<[u32; HALF_SH_COEFF_COUNT], A::Error> where A: serde::de::SeqAccess<'de>, { - let mut coefficients = [0; SH_COEFF_COUNT / 2]; + let mut coefficients = [0; HALF_SH_COEFF_COUNT]; for (i, coefficient) in coefficients.iter_mut().enumerate().take(SH_COEFF_COUNT) { *coefficient = seq diff --git a/src/query/sparse.rs b/src/query/sparse.rs index 440ef99a..e22edba8 100644 --- a/src/query/sparse.rs +++ b/src/query/sparse.rs @@ -25,8 +25,8 @@ pub struct SparseSelect { impl Default for SparseSelect { fn default() -> Self { Self { - radius: 0.03, - neighbor_threshold: 5, + radius: 0.05, + neighbor_threshold: 4, completed: false, } } diff --git a/src/render/bindings.wgsl b/src/render/bindings.wgsl index da75ebe4..b694376c 100644 --- a/src/render/bindings.wgsl +++ b/src/render/bindings.wgsl @@ -61,11 +61,23 @@ struct Gaussian { #ifdef PLANAR_TEXTURE_F16 #ifdef READ_WRITE_POINTS @group(2) @binding(0) var position_visibility: texture_storage_2d; + +#if SH_VEC4_PLANES == 1 +@group(2) @binding(1) var spherical_harmonics: texture_storage_2d; +#else @group(2) @binding(1) var spherical_harmonics: texture_storage_2d_array; +#endif + @group(2) @binding(2) var rotation_scale_opacity: texture_storage_2d; #else @group(2) @binding(0) var position_visibility: texture_storage_2d; + +#if SH_VEC4_PLANES == 1 +@group(2) @binding(1) var spherical_harmonics: texture_storage_2d; +#else @group(2) @binding(1) var spherical_harmonics: texture_storage_2d_array; +#endif + @group(2) @binding(2) var rotation_scale_opacity: texture_storage_2d; #endif #endif @@ -74,11 +86,23 @@ struct Gaussian { #ifdef PLANAR_TEXTURE_F32 #ifdef READ_WRITE_POINTS @group(2) @binding(0) var position_visibility: texture_storage_2d; + +#if SH_VEC4_PLANES == 1 +@group(2) @binding(1) var spherical_harmonics: texture_storage_2d; +#else @group(2) @binding(1) var spherical_harmonics: texture_storage_2d_array; +#endif + @group(2) @binding(2) var rotation_scale_opacity: texture_storage_2d; #else @group(2) @binding(0) var position_visibility: texture_storage_2d; + +#if SH_VEC4_PLANES == 1 +@group(2) @binding(1) var spherical_harmonics: texture_storage_2d; +#else @group(2) @binding(1) var spherical_harmonics: texture_storage_2d_array; +#endif + @group(2) @binding(2) var rotation_scale_opacity: texture_storage_2d; #endif #endif diff --git a/src/render/texture.rs b/src/render/texture.rs index a51b244e..d5993e69 100644 --- a/src/render/texture.rs +++ b/src/render/texture.rs @@ -32,7 +32,6 @@ use crate::{ GpuGaussianCloud, }, material::spherical_harmonics::{ - HALF_SH_COEFF_COUNT, SH_COEFF_COUNT, SH_VEC4_PLANES, SphericalHarmonicCoefficients, @@ -222,7 +221,10 @@ fn queue_textures( let start_index = plane_index * 4; let end_index = std::cmp::min(start_index + 4, sh.coefficients.len()); - sh.coefficients[start_index..end_index].to_vec() + let mut depthwise = sh.coefficients[start_index..end_index].to_vec(); + depthwise.resize(4, 0); + + depthwise }) }) .collect(); @@ -282,6 +284,12 @@ pub fn get_bind_group_layout( StorageTextureAccess::ReadWrite }; + let sh_view_dimension = if SH_VEC4_PLANES == 1 { + TextureViewDimension::D2 + } else { + TextureViewDimension::D2Array + }; + render_device.create_bind_group_layout(&BindGroupLayoutDescriptor { label: Some("planar_f16_gaussian_cloud_layout"), entries: &[ @@ -301,7 +309,7 @@ pub fn get_bind_group_layout( ty: BindingType::StorageTexture { access, format: TextureFormat::Rgba32Uint, - view_dimension: TextureViewDimension::D2Array, + view_dimension: sh_view_dimension, }, count: None, }, diff --git a/src/render/texture.wgsl b/src/render/texture.wgsl index 90c102a3..5ca8dd84 100644 --- a/src/render/texture.wgsl +++ b/src/render/texture.wgsl @@ -33,11 +33,19 @@ fn get_spherical_harmonics(index: u32) -> array { var coefficients: array; for (var i = 0u; i < #{SH_VEC4_PLANES}u; i = i + 1u) { + +#if SH_VEC4_PLANES == 1 + let sample = textureLoad( + spherical_harmonics, + location(index), + ); +#else let sample = textureLoad( spherical_harmonics, location(index), i, ); +#endif let v0 = unpack2x16float(sample.x); let v1 = unpack2x16float(sample.y);