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

feat: 4d gaussians #80

Draft
wants to merge 14 commits into
base: main
Choose a base branch
from
Prev Previous commit
Next Next commit
fix: spherindrical build errors and duplicate code
  • Loading branch information
mosure committed Jan 26, 2024
commit e349302ae30083c94cb24763c718463f0793f998
6 changes: 3 additions & 3 deletions src/gaussian/packed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ use crate::{
Scale4d,
ScaleOpacity,
},
material::spherical_harmonics::{
SphericalHarmonicCoefficients,
SpherindricalHarmonicCoefficients,
material::{
spherical_harmonics::SphericalHarmonicCoefficients,
spherindrical_harmonics::SpherindricalHarmonicCoefficients,
},
};

Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use render::RenderPipelinePlugin;
pub mod gaussian;
pub mod io;
pub mod material;
pub mod math;
pub mod morph;
pub mod query;
pub mod render;
Expand Down
10 changes: 6 additions & 4 deletions src/material/spherical_harmonics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ use serde::{
#[cfg(feature = "f16")]
use half::f16;

use crate::math::pad_4;


const SPHERICAL_HARMONICS_SHADER_HANDLE: Handle<Shader> = Handle::weak_from_u128(834667312);

Expand Down Expand Up @@ -54,10 +56,10 @@ pub const SH_DEGREE: usize = 3;

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 SH_COEFF_COUNT: usize = pad_4(SH_COEFF_COUNT_PER_CHANNEL * SH_CHANNELS);

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;
pub const PADDED_HALF_SH_COEFF_COUNT: usize = pad_4(HALF_SH_COEFF_COUNT);

#[cfg(feature = "f16")]
pub const SH_VEC4_PLANES: usize = PADDED_HALF_SH_COEFF_COUNT / 4;
Expand Down Expand Up @@ -149,7 +151,7 @@ fn coefficients_serializer<S>(n: &[u32; HALF_SH_COEFF_COUNT], s: S) -> Result<S:
where
S: Serializer,
{
let mut tup = s.serialize_tuple(SH_COEFF_COUNT)?;
let mut tup = s.serialize_tuple(HALF_SH_COEFF_COUNT)?;
for &x in n.iter() {
tup.serialize_element(&x)?;
}
Expand Down Expand Up @@ -186,7 +188,7 @@ where
}
}

d.deserialize_tuple(SH_COEFF_COUNT, CoefficientsVisitor)
d.deserialize_tuple(HALF_SH_COEFF_COUNT, CoefficientsVisitor)
}


Expand Down
51 changes: 26 additions & 25 deletions src/material/spherindrical_harmonics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,24 @@ use serde::{
#[cfg(feature = "f16")]
use half::f16;

use crate::material::spherical_harmonics::{
SH_CHANNELS,
SH_DEGREE,
use crate::{
material::spherical_harmonics::{
SH_CHANNELS,
SH_DEGREE,
},
math::{
gcd,
pad_4,
},
};


const fn gcd(a: usize, b: usize) -> usize {
if b == 0 {
a
} else {
gcd(b, a % b)
}
}


pub const SH_4D_DEGREE_TIME: usize = 2;

pub const SH_4D_COEFF_COUNT_PER_CHANNEL: usize = (SH_DEGREE + 1).pow(2) * (SH_4D_DEGREE_TIME + 1);
pub const SH_4D_COEFF_COUNT: usize = (SH_4D_COEFF_COUNT_PER_CHANNEL * SH_CHANNELS + 3) & !3;
pub const SH_4D_COEFF_COUNT: usize = pad_4(SH_4D_COEFF_COUNT_PER_CHANNEL * SH_CHANNELS);

pub const HALF_SH_4D_COEFF_COUNT: usize = (SH_4D_COEFF_COUNT / 2 + 3) & !3;
pub const HALF_SH_4D_COEFF_COUNT: usize = pad_4(SH_4D_COEFF_COUNT / 2);

// TODO: calculate POD_PLANE_COUNT for f16 and f32 based on a switch for HALF_SH_4D_COEFF_COUNT vs. SH_4D_COEFF_COUNT
pub const MAX_POD_U32_ARRAY_SIZE: usize = 32;
Expand Down Expand Up @@ -125,7 +122,7 @@ impl Default for SpherindricalHarmonicCoefficients {
impl Default for SpherindricalHarmonicCoefficients {
fn default() -> Self {
Self {
coefficients: [0.0; SH_4D_COEFF_COUNT],
coefficients: [[0.0; POD_ARRAY_SIZE]; POD_PLANE_COUNT],
}
}
}
Expand All @@ -135,9 +132,13 @@ impl SpherindricalHarmonicCoefficients {
#[cfg(feature = "f16")]
pub fn set(&mut self, index: usize, value: f32) {
let quantized = f16::from_f32(value).to_bits();
self.coefficients[index / 2] = match index % 2 {
0 => (self.coefficients[index / 2] & 0xffff0000) | (quantized as u32),
1 => (self.coefficients[index / 2] & 0x0000ffff) | ((quantized as u32) << 16),
let pair_index = index / 2;
let pod_index = pair_index / POD_ARRAY_SIZE;
let pod_offset = pair_index % POD_ARRAY_SIZE;

self.coefficients[pod_index][pod_offset] = match index % 2 {
0 => (self.coefficients[pod_index][pod_offset] & 0xffff0000) | (quantized as u32),
1 => (self.coefficients[pod_index][pod_offset] & 0x0000ffff) | ((quantized as u32) << 16),
_ => unreachable!(),
};
}
Expand All @@ -151,11 +152,11 @@ impl SpherindricalHarmonicCoefficients {


#[cfg(feature = "f16")]
fn coefficients_serializer<S>(n: &[u32; HALF_SH_4D_COEFF_COUNT], s: S) -> Result<S::Ok, S::Error>
fn coefficients_serializer<S>(n: &[[u32; POD_ARRAY_SIZE]; POD_PLANE_COUNT], s: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut tup = s.serialize_tuple(SH_4D_COEFF_COUNT)?;
let mut tup = s.serialize_tuple(HALF_SH_4D_COEFF_COUNT)?;
for &x in n.iter() {
tup.serialize_element(&x)?;
}
Expand All @@ -164,24 +165,24 @@ where
}

#[cfg(feature = "f16")]
fn coefficients_deserializer<'de, D>(d: D) -> Result<[u32; HALF_SH_4D_COEFF_COUNT], D::Error>
fn coefficients_deserializer<'de, D>(d: D) -> Result<[[u32; POD_ARRAY_SIZE]; POD_PLANE_COUNT], D::Error>
where
D: serde::Deserializer<'de>,
{
struct CoefficientsVisitor;

impl<'de> serde::de::Visitor<'de> for CoefficientsVisitor {
type Value = [u32; HALF_SH_4D_COEFF_COUNT];
type Value = [[u32; POD_ARRAY_SIZE]; POD_PLANE_COUNT];

fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("an array of floats")
}

fn visit_seq<A>(self, mut seq: A) -> Result<[u32; HALF_SH_4D_COEFF_COUNT], A::Error>
fn visit_seq<A>(self, mut seq: A) -> Result<[[u32; POD_ARRAY_SIZE]; POD_PLANE_COUNT], A::Error>
where
A: serde::de::SeqAccess<'de>,
{
let mut coefficients = [0; HALF_SH_4D_COEFF_COUNT];
let mut coefficients = [[0; POD_ARRAY_SIZE]; POD_PLANE_COUNT];

for (i, coefficient) in coefficients.iter_mut().enumerate().take(SH_4D_COEFF_COUNT) {
*coefficient = seq
Expand All @@ -192,7 +193,7 @@ where
}
}

d.deserialize_tuple(SH_4D_COEFF_COUNT, CoefficientsVisitor)
d.deserialize_tuple(HALF_SH_4D_COEFF_COUNT, CoefficientsVisitor)
}


Expand Down
13 changes: 13 additions & 0 deletions src/math/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

pub const fn gcd(a: usize, b: usize) -> usize {
if b == 0 {
a
} else {
gcd(b, a % b)
}
}


pub const fn pad_4(x: usize) -> usize {
(x + 3) & !3
}
Loading