wgpu-3dgs-core 0.7.0

A 3D Gaussian splatting library written in Rust using wgpu.
Documentation
// Gaussian buffer structure.
//
// Corresponds to `GaussianPod`.
struct Gaussian {
    pos: vec3<f32>,
    color: u32,

    @if(sh_single)
        sh: array<f32, (3 * 15)>,
    @if(sh_half)
        sh: array<u32, ((3 * 15 + 1) / 2)>,
    @if(sh_norm8)
        sh: array<u32, ((3 * 15 + 3) / 4)>,

    @if(cov3d_rot_scale)
        cov3d: array<f32, 7>,
    @if(cov3d_single)
        cov3d: array<f32, 6>,
    @if(cov3d_half)
        cov3d: array<u32, 3>,
}

// Unpack the color from `Gaussian.color`.
fn gaussian_unpack_color(gaussian: Gaussian) -> vec4<f32> {
    return unpack4x8unorm(gaussian.color);
}

// Unpack the SH coefficients from `Gaussian.sh`.
@if(sh_single) fn gaussian_unpack_sh(gaussian: Gaussian, sh_index: u32) -> vec3<f32> {
    return vec3<f32>(
        gaussian.sh[sh_index * 3],
        gaussian.sh[sh_index * 3 + 1],
        gaussian.sh[sh_index * 3 + 2],
    );
}

// Unpack the SH coefficients from `Gaussian.sh`.
@if(sh_half) fn gaussian_unpack_sh(gaussian: Gaussian, sh_index: u32) -> vec3<f32> {
    let i = sh_index * 3;
    let xi = i / 2;
    let yi = (i + 1) / 2;
    let zi = (i + 2) / 2;
    
    if xi == yi {
        return vec3<f32>(
            unpack2x16float(gaussian.sh[xi]),
            unpack2x16float(gaussian.sh[zi]).x,
        );
    } else {
        return vec3<f32>(
            unpack2x16float(gaussian.sh[xi]).y,
            unpack2x16float(gaussian.sh[yi]),
        );
    }
}

// Unpack the SH coefficients from `Gaussian.sh`.
@if(sh_norm8) fn gaussian_unpack_sh(gaussian: Gaussian, sh_index: u32) -> vec3<f32> {
    let i = sh_index * 3;
    let xi = i / 4;
    let xj = i % 4;
    let yi = (i + 1) / 4;
    let yj = (i + 1) % 4;
    let zi = (i + 2) / 4;
    let zj = (i + 2) % 4;
    
    return vec3<f32>(
        unpack4x8snorm(gaussian.sh[xi])[xj],
        unpack4x8snorm(gaussian.sh[yi])[yj],
        unpack4x8snorm(gaussian.sh[zi])[zj],
    );
}

// Unpack the SH coefficients from `Gaussian.sh`.
@if(sh_none) fn gaussian_unpack_sh(gaussian: Gaussian, sh_index: u32) -> vec3<f32> {
    return vec3<f32>(0.0);
}

// Unpack the 3D covariance matrix from `Gaussian.cov3d`.
@if(cov3d_rot_scale) fn gaussian_unpack_cov3d(gaussian: Gaussian) -> array<f32, 6> {
    let rot = vec4<f32>(gaussian.cov3d[0], gaussian.cov3d[1], gaussian.cov3d[2], gaussian.cov3d[3]);
    let scale = vec3<f32>(gaussian.cov3d[4], gaussian.cov3d[5], gaussian.cov3d[6]);

    let x2 = rot.x + rot.x;
    let y2 = rot.y + rot.y;
    let z2 = rot.z + rot.z;
    let xx = rot.x * x2;
    let xy = rot.x * y2;
    let xz = rot.x * z2;
    let yy = rot.y * y2;
    let yz = rot.y * z2;
    let zz = rot.z * z2;
    let wx = rot.w * x2;
    let wy = rot.w * y2;
    let wz = rot.w * z2;

    let sx = scale.x;
    let sy = scale.y;
    let sz = scale.z;

    let m = mat3x3<f32>(
        vec3<f32>(
            (1.0 - (yy + zz)) * sx,
            (xy + wz) * sx,
            (xz - wy) * sx,
        ),
        vec3<f32>(
            (xy - wz) * sy,
            (1.0 - (xx + zz)) * sy,
            (yz + wx) * sy,
        ),
        vec3<f32>(
            (xz + wy) * sz,
            (yz - wx) * sz,
            (1.0 - (xx + yy)) * sz,
        ),
    );

    let sigma = m * transpose(m);

    return array<f32, 6>(
        sigma[0][0],
        sigma[0][1],
        sigma[0][2],
        sigma[1][1],
        sigma[1][2],
        sigma[2][2],
    );
}

// Unpack the 3D covariance matrix from `Gaussian.cov3d`.
@if(cov3d_single) fn gaussian_unpack_cov3d(gaussian: Gaussian) -> array<f32, 6> {
    return gaussian.cov3d;
}

// Unpack the 3D covariance matrix from `Gaussian.cov3d`.
@if(cov3d_half) fn gaussian_unpack_cov3d(gaussian: Gaussian) -> array<f32, 6> {
    let x = unpack2x16float(gaussian.cov3d[0]);
    let y = unpack2x16float(gaussian.cov3d[1]);
    let z = unpack2x16float(gaussian.cov3d[2]);
    return array<f32, 6>(
        x.x,
        x.y,
        y.x,
        y.y,
        z.x,
        z.y,
    );
}