splat-transform

Usage guide for splat-transform.

Background

splat-transform is a 3DGS processing tool for Aholo Viewer. Use it for format conversion, data simplification, LOD generation, and voxel collider generation.

Environment Requirements

  • Node.js >= 20.19.0
  • Windows: Windows 22H2+ x86_64 with a D3D12 or Vulkan-compatible GPU. A discrete GPU is recommended when GPU features are enabled.
  • Linux: x86_64, glibc >= 2.34, libstdc++ >= 3.4.30, and a Vulkan-compatible GPU. A discrete GPU is recommended when GPU features are enabled.
  • macOS: not supported.

GPU-Required Features

  • SOG generation.
  • Voxel generation when backend is set to gpu.

Format Notes

Input Formats

  • ply
  • sog
  • ksplat
  • splat
  • spz
  • lcc
  • compressed.ply, the supersplat compressed ply format
  • meta.json, unpacked sog metadata

Output Formats

  • ply
  • spz
  • uspz, an spz file without gzip compression
  • splat
  • sog

modify Format

{
  isRowMatrix: boolean; // Whether transforms use row matrices. Defaults to true.
  transform: number[]; // Model-level transform.
  deletedIndices: number[]; // Deleted indices in bitmap form.
  indicesTransform: Array<{ indices: number[]; transform: number[] }>; // Local transform list.
}

Usage

Installation

npm install @manycore/aholo-splat-transform -g

CLI Mode

splat-transform create <input> <output> # Convert 3DGS formats.
splat-transform lod:auto --ratio <ratio> <input> <output> # Simplify 3DGS data to the specified ratio [0-1].
splat-transform lod:auto-chunk --type <type:ply,spz,splat,sog> --max-chunk-counts <count> <input> <output> # Generate schedulable multi-level LOD data. --max-chunk-counts controls the maximum chunk size.
splat-transform pipeline.json

Pipeline Descriptor (pipeline.json)

{
    "version": 1,
    "tasks": [
        {
            "id": "0",
            "type": "Read",
            "config": { "inputs": ["a.ply"], "output": "cache0" }
        },
        {
            "id": "1",
            "type": "AutoChunkLod",
            "config": { "input": "cache0", "output": "cache0", "type": "spz" }
        },
        {
            "id": "2",
            "type": "Write",
            "config": { "input": "cache0", "output": "a-lod" }
        }
    ]
}

Task

Name Purpose Parameter Type Required (Default) Description
Read Reads multiple Gaussian files and merges them into one SplatData object. inputs string[] Y Input file paths.
output string Y Resource key to write.
maxShDegree number
0..=3
N(3) Maximum spherical harmonics degree.
Write Writes a SplatData object to disk in the specified format. input string Y Resource key to read.
output string Y Output resource path.
compressLevel number
0..=9
N(6) gzip compression level.
enableMortonSort boolean N(true) Enables Morton sorting.
Modify Modifies a SplatData object. input string Y Resource key to read.
output string Y Resource key to write.
modifyPaths string[] N([]) modify JSON file paths. See modify Format.
AutoLod Generates fused Gaussian output. input string Y Resource key to read.
output string Y Resource key to write.
counts number N(Infinity) Maximum retained count.
ratio number
0..=1
N(0.3) Maximum retained ratio.
AutoChunkLod Generates chunked fused Gaussian output for use with the LOD scheduler module. input string Y Resource key to read.
output string Y Resource key to write.
type string Y Chunk file type. See Output Formats.
forceSpzFormatThreshold number N(0) Because low-count sog chunks can compress poorly, chunks below this threshold are forced to spz. A practical starting value is 200000.
maxChunkCounts number N(400000) Maximum number of Gaussian points per chunk.
levels
        
Array<{
  precision: number,
  scaleBoost: number
}>
        
      
N
        
[
  { precision: 1.0, scaleBoost: 1 },
  { precision: 0.5, scaleBoost: 1 },
  { precision: 0.25, scaleBoost: 1 },
  { precision: 0.05, scaleBoost: 1.01 },
  { precision: 0.01, scaleBoost: 1.02 },
]
        
      
LOD level precision settings.
Voxel Generates voxel colliders. input string Y Resource key to read.
output string Y Output file path.
voxelResolution number N(0.05) Voxel size.
opacityCutoff number N(0.1) Voxel filtering threshold. Higher values cull voxels more aggressively. Increase it when the scene has many floating artifacts.
backend string
  • cpu
  • gpu
N(gpu) Generation backend. Defaults to gpu; cpu is available but significantly slower. Results can differ slightly between backends.
box
        
{
  minCorner: [number, number, number],
  maxCorner: [number, number, number]
}
        
      
N
        
{
  minCorner: [-100, -100, -100],
  maxCorner: [100, 100, 100]
}
        
      
Scene box limit. Outliers can severely affect voxelization performance and produce meaningless output, so this constrains the voxel generation range.
navCapsule
        
{
  height: number,
  radius: number
}
        
      
N(null) Both fields are used for navigation simplification. navCapsule sets the navigation body height and radius, and navSeed sets the navigation start center.

When enabled, voxels are simplified by the reachable range of the navigation body. This can optimize voxel output, but the feature is still incomplete and may have side effects in some cases, so it is disabled by default.

navSeed
        
{
  x: number,
  y: number,
  z: number
}
        
      
N(null)

Examples

Apply modifications to a.ply and b.ply, then write c.spz:

{
    "version": 1,
    "tasks": [
        {
            "id": "0",
            "type": "Read",
            "config": { "inputs": ["a.ply", "b.ply"], "output": "cache0" }
        },
        {
            "id": "1",
            "type": "Modify",
            "config": { "input": "cache0", "output": "cache0", "modifyPaths": ["a.json", "b.json"] }
        },
        {
            "id": "2",
            "type": "Write",
            "config": { "input": "cache0", "output": "c.spz" }
        }
    ]
}

Apply a modification to a.ply, then generate auto chunk LOD output:

{
    "version": 1,
    "tasks": [
        {
            "id": "0",
            "type": "Read",
            "config": { "inputs": ["a.ply"], "output": "cache0" }
        },
        {
            "id": "1",
            "type": "Modify",
            "config": { "input": "cache0", "output": "cache0", "modifyPaths": ["a.json"] }
        },
        {
            "id": "2",
            "type": "AutoChunkLod",
            "config": { "input": "cache0", "output": "cache0", "type": "spz" }
        },
        {
            "id": "3",
            "type": "Write",
            "config": { "input": "cache0", "output": "a-lod" }
        }
    ]
}

Generate voxel colliders:

{
    "version": 1,
    "tasks": [
        {
            "id": "0",
            "type": "Read",
            "config": { "inputs": ["input.ply"], "output": "cache0" }
        },
        {
            "id": "1",
            "type": "Voxel",
            "config": {
                "input": "cache0",
                "output": "voxel-output",
                "voxelResolution": 0.05,
                "opacityCutoff": 0.1,
                "navCapsule": { "height": 1.4, "radius": 0.2 },
                "navSeed": { "x": 0, "y": 0, "z": 0 }
            }
        }
    ]
}

Notes

  • A reasonably powerful discrete GPU is recommended when generating SOG or generating Voxel data with GPU. Converting large datasets to SOG may require more than 10 GB of GPU memory.
  • When generating chunk-lod with AutoChunkLod or lod:auto-chunk, spz output is recommended. After chunking and multi-level lod generation, some chunks can contain very little data. sog compresses these small chunks less effectively than spz. You can also use forceSpzFormatThreshold to force chunks below a chosen count to spz.
  • chunk-lod generation is resource-intensive, so use a relatively powerful machine. For large datasets, memory >= 32 GB and CPU cores >= 16, including hyper-threading, are recommended. If generation cannot complete directly, split the data into coarse chunks first, then generate and merge lod-meta.json files. Merging can be done with the merge-lod command from @manycore/aholo-splat-dev-server@>=1.0.1.