splat-transform

Usage guide for the splat-transform 3DGS processing tool.

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+ with a D3D12 or Vulkan-compatible GPU. A discrete GPU is recommended when GPU features are enabled.
  • Linux: 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 meta data

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

CLI Mode

pnpm splat-transform create <input> <output>
pnpm splat-transform lod:auto --ratio <ratio> <input> <output>
pnpm splat-transform lod:auto-chunk --type <type:ply,spz,splat,sog> --max-chunk-counts <count> <input> <output>
pnpm 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

NamePurposeKey Parameters
ReadReads multiple Gaussian Splatting files and merges them into one SplatData object.inputs: string[], output: string
WriteWrites SplatData to disk in the selected format.input: string, output: string, compressLevel?: number
ModifyModifies SplatData from modify JSON files.input: string, output: string, modifyPaths?: string[]
AutoLodGenerates fused Gaussian output.input: string, output: string, counts?: number, ratio?: number
AutoChunkLodGenerates chunked fused Gaussian output for LOD scheduling.input: string, output: string, type: string, maxChunkCounts?: number, levels?: Array<{ precision: number; scaleBoost: number }>
VoxelGenerates voxel colliders.input: string, output: string, voxelResolution?: number, opacityCutoff?: number, `backend?: “cpu"

AutoChunkLod should use one of the output formats for type. Small sog chunks can compress poorly, so forceSpzFormatThreshold can force small chunks to spz. A common starting point is 200000.

Voxel also supports range-control fields such as box, navCapsule, and navSeed. Outliers can make voxelization much slower, so constrain the voxel range for the target scene.

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 }
      }
    }
  ]
}