CLI tool
francescofugazzi/3dgsconverter avatar
francescofugazzi/3dgsconverter

3dgsconverter: one command to move between 3DGS, KSplat, SOG and SPZ splat formats

A Python command-line utility for converting and processing 3D Gaussian Splatting models. Supports N-to-N conversion between 3DGS (.ply), KSplat, SOG, SPZ, Splat, CloudCompare, Parquet, and Compressed PLY. Includes GPU-accelerated filtering (SOR, Density).

602 stars42 forksPythonMIT

At a glance

What is it?
3dgsconverter is a MIT licensed Python command line tool that converts 3D Gaussian Splatting models between PLY, KSplat, SOG, SPZ, Splat, Parquet and compressed PLY, with GPU accelerated filtering and outlier removal through Taichi. It is the tool for changing a format, not for creating the model in the first place.
Who is it for?
3dgsconverter suits anyone who already has a 3D Gaussian Splatting model and needs it in another format, whether for a viewer, a web player or a mobile target, and who also wants to crop, clean or compress the scene in the same pass.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 83 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Nine formats, one conversion path

3dgsconverter is a Python command line utility for working with 3D Gaussian Splatting models, and its central promise is universal conversion: any supported format to any other supported format. The description lists 3DGS `.ply`, KSplat, SOG, SPZ, Splat, CloudCompare, Parquet and compressed PLY, and the documentation puts it plainly, for example `.ply` to `.ksplat`, `.spz` to `.ply`, `.sog` to `.sog`.

The ecosystem this addresses is fragmented by design. A scene captured or trained in the original 3DGS format has to be rewritten for a viewer that wants KSplat, for a web player that wants SPZ, for a mobile runtime that wants SOG, or for a data pipeline that wants Parquet columns. Each of those ecosystems picked its own container, and the usual answer has been a separate script per pair.

The tool does the conversion with the same pipeline regardless of the pair, and that is where the filtering comes in. The filters apply to the intermediate raw data, so they work on any input format rather than only on the format the filter was written for. A crop, an opacity threshold and an outlier removal pass run the same way whether the source is a `.ply`, a `.spz` or a Parquet file.

It is worth being clear about scope. This is a conversion and processing utility. It does not train a Gaussian splatting model, reconstruct a scene from photographs, or render one. If your problem is producing the model, this is the wrong tool, and it is the right tool only once you have one and need it somewhere else.

The format table shows where the real differences are

The most useful part of the documentation is the format table, because it records the quirks rather than pretending the formats are interchangeable. Each row lists a default maximum spherical harmonics degree, whether SH4 can be opted into, and the format specific features and parameters.

3DGS PLY is the standard format, full float32, with a default SH cap of 3 and `--sh_level` to lower it. CloudCompare PLY is viewer compatible and forces RGB generation, with `--rgb` to convert spherical harmonics to RGB. Compressed PLY keeps the standard PLY container but stores chunk based quantization inside it. Splat is the legacy web format, RGB only with no spherical harmonics, so its default maximum SH is 0.

KSplat is built for streaming and web use, with hierarchical quantization and SH defaulting to 2, and its `compression_level` runs from 0 for F32 through 1 for F16 to 2 and above for quantized output. SPZ v3 has SH defaulting to 3, is backed by a gzip stream in a legacy container, and is the default write target. SPZ v4 raises the default to SH 4 and uses a plaintext header with ZSTD streams, enabled with `spz_version=4`. SOG v2 targets web and mobile, ships as a ZIP bundle or an unpacked directory, and its `compression_level` controls codebook size. Parquet is the columnar option for data analysis and is pandas compatible.

The legacy SOG v1 layout is the row to read twice. It can be written with `--sog_version 1`, it requires square textures, and when the point count is not square the scene is reduced to the highest-opacity splats. That is a real loss of data, and it is a compatibility path rather than a recommended one.

Filters run before and after the format matters

The filtering set is small and each entry has a clear job. Region of Interest cropping uses a manual bounding box and runs first, which the documentation gives as the reason for speed. Alpha and opacity filtering removes transparent splats. Density control removes sparse areas while keeping dense clusters, with multi-cluster support. Statistical Outlier Removal cleans up what the documentation calls flyers, the stray splats that appear where the reconstruction was uncertain.

That last one is the operation most people want from a splat cleaning tool, and it is one of the two that run on the GPU. The acceleration comes from Taichi, which supports NVIDIA CUDA, Apple Metal and Vulkan or integrated GPUs, and the documentation names K-Means clustering for SOG and KSplat compression and Statistical Outlier Removal as the accelerated operations.

Compression is controlled separately from filtering through `--compression_level`, where 0 means maximum quality, and the level means something different per format. For SOG it is codebook size, for SPZ v3 it is the gzip level, and for KSplat it selects the numeric representation. A single flag with format-specific meanings is a mild trap, and the format table is the place to check what a given level will do.

One flag exists to protect data that the formats do not standardise. `--extra_elements` preserves non-standard PLY properties such as `extrinsic` and `intrinsic`, which is what camera parameters live in. Without it, converting between PLY-based formats can quietly drop fields that your downstream tool expects.

Converting and cleaning a scene in one command

The basic syntax is short, with an optional output path:

bash
3dgsconverter -i <input_file> -f <target_format> [-o <output_file>] [options]

If the output path is omitted, the filename is derived from the input with the correct extension. The command is installed under four names, `3dgsconverter`, `gsconverter`, `3dgsconv` and `gsconv`, and `--force` overwrites existing files without a confirmation prompt.

The simplest conversion, from PLY to KSplat, needs only the input and the target format:

bash
3dgsconverter -i input.ply -f ksplat
# Creates input.ksplat automatically

For a smaller SOG bundle, the compression level decides the trade-off, with level 1 for high quality and level 10 for high compression:

bash
# Level 1 = High Quality. Level 10 = High Compression.
3dgsconverter -i input.ply -o output.sog -f sog --compression_level 1

The legacy SOG v1 layout can be written either as a bundled ZIP or as an unpacked directory, and the rule is in the extension: both SOG versions write a ZIP bundle when the output ends in `.sog`, so a path without that extension produces a directory containing `meta.json` and WebP assets.

Cleaning is where the filters appear on the command line, and two of them are combined in the documented example:

bash
# Remove invisible points and outliers
3dgsconverter -i raw.ply -o clean.ply -f 3dgs --min_opacity 5 --sor_intensity 8

Cropping is the operation the documentation wants run before the others, and it takes six coordinates:

bash
# Crop BEFORE filtering (Attributes: minX minY minZ maxX maxY maxZ)
3dgsconverter -i scene.spz -o crop.ply -f 3dgs --bbox -2 -2 -2 2 2 2

The parameter reference also covers `--rgb` to force RGB generation from spherical harmonics, `--sh_level` to cap the target degree, `--crop_sh` to trim SH padding so only the coefficients present in the source are written, and `--spz_version` to select SPZ v3 or v4.

Spherical harmonics are capped, never upscaled

The most likely source of disappointment with this tool is the spherical harmonics handling, so it is worth reading the rules rather than assuming parity.

The `--sh_level` parameter sets the target degree between 0 and 4, and the documentation states the tool never upscales. If the source model has a lower degree, that lower degree is kept. In other words, the tool will not invent higher order coefficients to reach a target, which means a conversion to a format whose default is SH 3, such as 3DGS PLY, from a source with SH 0 gives you SH 0 data in an SH 3 container.

Writing SH 4 outside of SPZ v4 requires the experimental `--preserve_sh4` opt-in, which preserves SH 4 on compatible non-SPZ-v4 formats when the source already contains SH 4. Standard writes remain capped at SH 3. The documentation marks this option experimental in the format table as well as in the parameter list, which is the clearest signal that it is not the path to build a pipeline on.

The `--crop_sh` option is the more everyday tool. It trims SH padding and writes only the coefficients actually present in the source, which the documentation describes as useful when you want a tighter, non-canonical output. That matters for file size, since a canonical file carries the full coefficient array even when the higher orders are zero.

The consequence for planning is straightforward. If the target consumer needs full SH 4 and your source is not SPZ v4, either keep the source format or accept the cap. Discovering that after converting a large scene is expensive, so check the source degree before the run rather than after it.

Installation, packaging and where the project stands

The recommended environment is Conda, and the documented creation step pins Python 3.10:

bash
    conda create -n gsconv python=3.10
    conda activate gsconv

A local `.venv` is offered as an alternative. The quick install pulls the package straight from the repository:

bash
    pip install git+https://github.com/francescofugazzi/3dgsconverter.git

For development the repository is cloned and the requirements installed directly:

bash
    git clone https://github.com/francescofugazzi/3dgsconverter.git
    cd 3dgsconverter
    pip install -r requirements.txt

GPU acceleration depends on Taichi, and the documentation says to ensure `taichi` is installed with `pip install taichi`, adding that it is already included in `requirements.txt`. That file is short and covers the numerical and IO stack:

code
scikit-learn
numpy
scipy
pillow
tqdm
taichi
pandas
zstandard

The package metadata lists the distribution as `gsconverter`, which differs from the repository name and from the primary command, and it registers the four command names:

python
    entry_points={
        'console_scripts': [
            '3dgsconverter=gsconverter.main:main',
            'gsconverter=gsconverter.main:main',
            '3dgsconv=gsconverter.main:main',
            'gsconv=gsconverter.main:main',
        ],

The licence is MIT, and the package declares itself operating system independent with a Python floor of `>=3.8`, while the Conda recipe recommends 3.10. The releases are 0.9.1 on 2026-08-01, 0.9.0 on 2026-05-22 and 0.8.2 on 2026-05-02. The repository is not archived and the last push was on 2026-08-01, the same day as the newest tag. The versions stay below 1.0, and the format table's own warnings about experimental flags and legacy paths are the honest summary of what to expect from a pre-1.0 converter.

Editorial conclusion

3dgsconverter suits anyone who already has a 3D Gaussian Splatting model and needs it in another format, whether for a viewer, a web player or a mobile target, and who also wants to crop, clean or compress the scene in the same pass. It does not suit someone who needs to train or reconstruct a scene, since the project converts and filters existing models, and it does not suit a pipeline that needs full spherical harmonics on a non-SPZ-v4 format, since standard writes stay capped at SH degree 3 and the SH4 preservation path is experimental. Before converting, check the default spherical harmonics degree of the target format and the compression level, since the last push was on 2026-08-01 with release 0.9.1.

Frequently asked questions

How do I convert a 3DGS PLY file to KSplat?

Run `3dgsconverter -i input.ply -f ksplat`, which creates input.ksplat automatically because the output name is derived from the input. Use `-o` if you want a different path, and `--force` to overwrite an existing file without a prompt.

What does the compression_level option mean in 3dgsconverter?

It means something different per format. For SOG it controls codebook size, for SPZ v3 it controls the gzip level, and for KSplat it selects between F32, F16 and quantized output. Level 0 means maximum quality everywhere.

Can 3dgsconverter write full spherical harmonics degree 4?

Only in limited cases. The tool never upscales, standard writes remain capped at SH degree 3, and `--preserve_sh4` is marked experimental for compatible non-SPZ-v4 formats. SPZ v4 natively supports SH 4 and is selected with `spz_version=4`.

Does 3dgsconverter need a GPU?

No. GPU acceleration is optional and comes from Taichi, which supports NVIDIA CUDA, Apple Metal and Vulkan, and it accelerates K-Means clustering and Statistical Outlier Removal. Installing Taichi is enough to enable it, and it is already listed in requirements.txt.

What happens to camera parameters when converting between PLY formats?

They can be preserved with `--extra_elements`, which keeps non-standard PLY elements such as `extrinsic` and `intrinsic` when converting between the 3DGS and CloudCompare formats. Without that flag those properties are not carried over.

Official sources

  1. francescofugazzi/3dgsconverter on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/francescofugazzi-3dgsconverter.svg)](https://hysenlabs.com/projects/francescofugazzi-3dgsconverter)

Was this useful?