readers.spz#

The SPZ reader reads points in the spz format, designed for storing compressed 3D gaussian splat data. The format stores compressed points, with their associated scale, rotation, color and spherical harmonics.

Default Embedded Stage

This stage is enabled by default

Reading an SPZ file will output the following dimensions:

  • X, Y, Z

  • f_dc_0, f_dc_1, f_dc_2: Red, Green and Blue colors (zeroth order spherical harmonics).

  • opacity: scalar representation of Opacity/Alpha.

  • scale_0, scale_1, scale_2: X/Y/Z scale transform applied to each gaussian when rendering.

  • rot_0, rot_1, rot_2, rot_3: W (real component)/X/Y/Z normalized rotation quaternion.

  • Optional: Spherical Harmonics – 0, 9, 24 or 45 dimensions labeled f_dc_*, with SH coefficients as the fastest-changing axis and color as the slower-changing axis.

Example#

[
    {
        "type":"readers.spz",
        "filename":"inputfile.spz"
    },
    {
        "type":"writers.ply",
        "filename":"outputfile.ply"
    }
]

Writing Splat Data to a Point Cloud#

When carrying over 3DGS data to a standard point cloud, the splat’s f_dc_* and opacity values can be mapped to PDAL’s corresponding RGB/Alpha dimensions using filters.assign. For opacity, a sigmoid function needs to be applied to convert the input into a 0-1 value, which is multiplied by 255 to get our standard 8-bit opacity.

Color in 3D Gaussian splats is encoded as the normalized spherical harmonics value at Y(0,0) (AKA the “DC component”); to convert these values to 0-1, we need to multiply it by the SH0 constant 1/sqrt(4pi), AKA 0.2821 and add 0.5 to get rid of negative values. To translate that to 0-255, we multiply both of the values previously mentioned by 255.

However, depending on the input splat data, using the SH0 constant can result in some values that are out of range of the 8-bit color dimension; to account for this, we adjusted the constant down a bit to 0.2. This can give colors that are a little desaturated, because it constrains the range of values that can be assigned; feel free to change the constant to your liking. This function was interpreted from Niantic’s spz library, but it should work for all gaussian splat data in PDAL.

{
    "type":"filters.assign",
    "value": [
        "Alpha = 255 * (1 / (1 + exp(-opacity)))",
        "Red = (0.2 * 255) * f_dc_0 + 127.5",
        "Green = (0.2 * 255) * f_dc_1 + 127.5",
        "Blue = (0.2 * 255) * f_dc_2 + 127.5"
    ]
}

Options#

filename

File to read. [Required]

count

Maximum number of points to read. [Default: unlimited]

override_srs

Spatial reference to apply to the data. Overrides any SRS in the input itself. Can be specified as a WKT, PROJ or EPSG string. Can’t use with ‘default_srs’. [Default: none]

default_srs

Spatial reference to apply to the data if the input does not specify one. Can be specified as a WKT, PROJ or EPSG string. Can’t use with ‘override_srs’. [Default: none]