Open-source project
hku-mars/GS-SDF avatar
hku-mars/GS-SDF

GS-SDF puts LiDAR geometry and Gaussian splatting in one reconstruction pipeline

[IROS 2025] LiDAR-Augmented Gaussian Splatting and Neural SDF for Geometrically Consistent Rendering and Reconstruction

541 stars43 forksC++GPL-2.0

At a glance

What is it?
GS-SDF is an IROS 2025 research system that couples a neural signed distance field with Gaussian splatting so the rendered view and the reconstructed surface agree geometrically, using LiDAR point clouds to supervise the SDF and to initialise the Gaussians. The repository ships the C++ implementation, ROS and plain CMake builds, and dataset preparation scripts.
Who is it for?
Adopt GS-SDF if you are doing research on geometrically consistent neural scene reconstruction and want a reference implementation that pairs a neural SDF with Gaussian splatting, since the repository includes the training node, configuration files for Replica and the colmap multi-camera set, and the rosbag conversion tooling.
Can I use it commercially?
Yes, with conditions. GPL-2.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 99 days ago.
What is it written in?
Mainly C++, according to GitHub's language statistics.

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

Editorial analysis

The problem being solved: a render that disagrees with the geometry

GS-SDF stands for LiDAR-Augmented Gaussian Splatting and Neural SDF, and the subtitle is for geometrically consistent rendering and reconstruction.

The description of the contribution is dense but precise. The project proposes a unified LiDAR-visual system that synergizes Gaussian splatting with a neural signed distance field. The accurate LiDAR point clouds enable a trained neural signed distance field to offer a manifold geometry field. That motivates an SDF-based Gaussian initialization for physically grounded primitive placement and a comprehensive geometric regularization for geometrically consistent rendering and reconstruction.

Three ideas in that paragraph matter. A manifold geometry field is a surface representation that is continuous and well-defined everywhere, which is what an SDF gives you and what a bag of Gaussians does not. Physically grounded primitive placement is the initialisation step: rather than placing Gaussians at random and letting the optimiser find them, the SDF tells the system where surfaces actually are. And geometric regularization is the training-time constraint that keeps the rendered view and the extracted surface in agreement rather than letting the renderer take a shortcut.

The pipeline diagram in the README, at pics/pipeline.jpg, is where the components sit relative to each other, and the project page at jianhengliu.github.io/Projects/GS-SDF/ carries the paper and a video.

The code is C++ with a CMake build, the licence is GPL-2.0, the default branch is master, and the last push was on 2026-07-16. There are no GitHub releases, so there is nothing to pin. The news entries show two additions: support for colmap-format multi-camera datasets in August 2025, and an update to the custom FAST-LIVO2 dataset instructions in February 2026 for better adaption to general collection settings.

Building it: libtorch by hand, then CMake or catkin

The installation is pinned to a specific environment: tested on Ubuntu 20.04 with CUDA 11.8.

The dependency install is a sequence of shell commands, and the libtorch part is the fiddly bit because you fetch the archive and point CMake at it yourself:

bash
  pip install open3d==0.18.0
  # Libtorch
  wget https://download.pytorch.org/libtorch/cu118/libtorch-cxx11-abi-shared-with-deps-2.4.1%2Bcu118.zip
  apt install zip
  unzip libtorch-cxx11-abi-shared-with-deps-*.zip
  rm *.zip
  echo "export Torch_DIR=$PWD/libtorch/share/cmake/Torch" >> ~/.bashrc # ~/.zshrc if you use zsh
  source ~/.bashrc # .zshrc if you use zsh

  mkdir -p gs_sdf_ws/src
  cd gs_sdf_ws/src
  apt install git libdw-dev
  git clone https://github.com/hku-mars/GS-SDF.git --recursive
  cd ..

Three details are worth calling out. The libtorch URL carries cu118 in it, so the CPU-only or newer CUDA builds are not what the instructions fetch, and Torch_DIR is written into your shell profile because the CMake build looks for libtorch there rather than finding it on its own. And the clone uses --recursive, which matters because the repository has a submodules/ directory and a .gitmodules file.

open3d is pinned to 0.18.0, which suggests it is used for point cloud and mesh processing in the pipeline.

There are two build routes. The ROS route is one command:

bash
  catkin_make -j8 -DENABLE_ROS=ON

The plain CMake route replaces that with a manual build directory:

bash
  # Instead of build with catkin_make, you can also build with cmake
  cd gs_sdf_ws/src/GS-SDF
  mkdir build
  cd build
  cmake ..
  make -j8

The ROS notes explain why you might want one or the other. The software does not rely on ROS, but under ROS noetic installed, the installation should be easier. And if real-time visualisation is needed, ROS is required.

The repository layout reflects the two build systems: there is a package.xml and a launch/ directory for the ROS side, plus CMakeLists.txt at the root, a config/ directory for the per-dataset YAML files, eval/ for evaluation, include/ and src/ for the code, scripts/ for the data conversion tools, and submodules/ for the vendored dependencies.

Data preparation, and the two dataset families the code expects

The data section is where a reader learns what the pipeline actually consumes, and there are two families.

The first is Replica, the standard synthetic indoor scene benchmark, downloaded as a zip and unpacked into a specific tree with cull_replica_mesh and room2 subdirectories, each containing an eval/results folder and a traj.txt file. The layout tree in the README is precise about the nesting, which matters because the config files reference paths inside it.

The second is the FAST-LIVO2 dataset, which comes as either Rosbag or Parsered Data from the M2Mapping Datasets page. The rosbag form holds a .bag file per sequence; the parsed form holds images, depths, color_poses.txt and depth_poses.txt. The poses in the parsed form are the reason the pipeline can work without ROS at all, because the camera and LiDAR poses that the rosbag topics would carry are written out as text files.

The custom dataset section shows the full capture workflow, and it is the most instructive part of the README because it names every moving part. You run LIVO from the modified-FAST-LIVO2 repository with roslaunch fast_livo mapping_avia.launch, record a bag with rosbag record covering the mapped-to-initial LiDAR and camera topics plus the origin image, the registered point cloud, the tf and tf_static transforms and the path, then play the bag back, and then convert it to colmap format:

bash
  # 4. convert rosbag into colmap format
  python scripts/rosbag_convert/rosbag_to_colmap.py \                       
    --bag_path data/YOUR_BAG_NAME.bag \--image_topic /origin_img/compressed \
    --image_pose_topic /aft_mapped_to_init_cam \
    --point_topic /cloud_registered_body \
    --point_pose_topic /aft_mapped_to_init_lidar \
    --output_dir data/YOUR_BAG_NAME_colmap \
    --fx [fx] --fy [fy] --cx [cx] --cy [cy] \
    --width [width] --height [height] \
    --k1=[k1] --k2=[k2] --p1=[p1] --p2=[p2]
  # 5. run GS-SDF with the converted colmap format data
  rosrun neural_mapping neural_mapping_node train src/GS-SDF/config/colmap/colmap_example.yaml data/YOUR_BAG_NAME_colmap

The converter takes the camera intrinsics and distortion coefficients explicitly, which tells you the colmap output needs real calibration values rather than defaults, and the topic names are FAST-LIVO2's own naming rather than generic ones.

Multi-camera datasets follow the colmap text format, with cameras.txt, images.txt, depths.txt and separate images and depths directories, and the demo set has a ready-made config named shenzhenbei.yaml. That entry is the one the news section calls new in August 2025, and the February 2026 update was about making the custom capture instructions work for general collection settings rather than the one flight they were written for.

Running it, and the gap between the README and the release

The Run section is short. You source the workspace setup file, which is devel/setup.bash or setup.zsh, and then invoke the training node with a config file and a data path:

bash
    source devel/setup.bash # or setup.zsh

    # Replica
    ./src/GS-SDF/build/neural_mapping_node train src/GS-SDF/config/replica/replica.yaml src/GS-SDF/data/Replica/room2
    # If ROS is installed, you can also run the following command:

The pattern is consistent across the README: a config YAML per dataset or sequence, and a data path. The configs are named after the dataset, replica.yaml, colmap_example.yaml, shenzhenbei.yaml, which tells you the experiment settings live in version-controlled YAML rather than in command-line arguments, and that comparing runs means comparing config files.

There is one sentence in the README that deserves attention, and it sits in the introduction rather than in a warning box: our paper is currently undergoing peer review, and the code will be released once the paper is accepted.

That is confusing next to a repository that contains src/, include/, eval/, config/ and a scripts/ directory with the conversion tooling in it. The repository description says IROS 2025, so the paper has been at a venue since the README text was written. The reading that fits everything is that the source tree present now is a development state, and the promise in the README referred to a public release that has not been formalised as a tagged version. There are no GitHub releases, the default branch is master, and the last push was 2026-07-16, so there is no published artefact to point at.

For a reader this matters more than usual, because a research codebase that is still being reorganised will have entry points, config keys and directory expectations that shift. The README's own mitigation is the documentation links, and the repository's own docs directory and the config files are where the detail lives.

The paper itself is on arXiv at 2503.10170, and the README asks that you cite it if you use GS-SDF for academic research, giving a BibTeX entry with the authors Jianheng Liu, Yunfei Wan, Bowen Wang, Chunran Zheng, Jiarong Lin and Fu Zhang.

Where GS-SDF is the wrong tool

Three limits, and the first is about the environment rather than the method.

The first is the pinned toolchain. Ubuntu 20.04, CUDA 11.8, and a libtorch archive fetched for cu118 specifically. A machine with a modern GPU driver and CUDA 12 will not be served by those instructions, and libtorch and the CUDA runtime have to match closely enough to load the compiled kernels. That is a day of environment work before the first run, and it is work that has to be redone on every machine.

The second is the data dependency. The pipeline is LiDAR-augmented, so the point cloud and the camera must be calibrated together, which is why the rosbag converter demands the intrinsics and distortion coefficients as explicit arguments. If your sequence has no LiDAR, or has a LiDAR that was not registered to the camera, the method has nothing to work with, and this is not a system that degrades gracefully to image-only input.

The third is the maturity of the artifact, which the README itself flags. There is no release, the paper was under peer review at the time the text was written, and the repository contains a second, related codebase in the submodules/ directory and a .gitmodules file, so the dependency versions are pinned to specific commits of other people's code. The build depends on those submodules being fetched with --recursive and on the ROS and CMake paths agreeing about where they land.

The alternative approach for most people is to build the two halves separately and connect them yourself. A pure Gaussian splatting implementation gives you the photorealistic view with no geometry supervision, and a separate SDF method gives you the surface, and you can evaluate them independently and understand which one is failing when the results disagree. The difference in approach is that GS-SDF is precisely the argument that the two should be trained together, that a LiDAR-supervised SDF should constrain the Gaussians rather than being computed afterwards, and this repository is the evidence for that argument in code form. For a paper reproduction or a research baseline, that is the point. For a product that needs a stable, supported library with a documented API and regular releases, this is the wrong artifact, and the standard splatting and SDF codebases are the right starting point.

Editorial conclusion

Adopt GS-SDF if you are doing research on geometrically consistent neural scene reconstruction and want a reference implementation that pairs a neural SDF with Gaussian splatting, since the repository includes the training node, configuration files for Replica and the colmap multi-camera set, and the rosbag conversion tooling. Do not adopt it as a finished product, since the README says the paper is under peer review and that the code will be released once the paper is accepted, and the build environment is pinned to Ubuntu 20.04 with CUDA 11.8. Verify first that your GPU driver and CUDA version match that pinned combination, since libtorch is fetched for cu118 specifically, that you can install libtorch and export Torch_DIR before running CMake, that your data is in one of the two supported layouts, Replica or a FAST-LIVO2 sequence converted to colmap format, and that you read the ROS notes, since the software does not rely on ROS but real-time visualisation does.

Frequently asked questions

What is GS-SDF and what does it combine?

It is a unified LiDAR-visual system that synergizes Gaussian splatting with a neural signed distance field. The accurate LiDAR point clouds let the trained SDF offer a manifold geometry field, which motivates SDF-based Gaussian initialization for physically grounded primitive placement and geometric regularization for consistent rendering and reconstruction.

How do I build GS-SDF?

The tested environment is Ubuntu 20.04 with CUDA 11.8. Install open3d 0.18.0, download the cu118 libtorch archive, export Torch_DIR pointing at its cmake directory, then clone the repository with --recursive into a gs_sdf_ws/src directory and build with catkin_make -j8 -DENABLE_ROS=ON or with plain cmake and make.

Does GS-SDF require ROS?

No. The README states the software does not rely on ROS, and that under ROS noetic installed the installation should be easier. ROS is required only if real-time visualisation is needed.

Which datasets does GS-SDF support?

The processed FAST-LIVO2 datasets and the Replica extrapolation datasets, plus custom FAST-LIVO2 sequences captured with the modified-FAST-LIVO2 repository and converted from rosbag to colmap format, and multi-camera datasets following the colmap text format with a shenzhenbei demo set.

How do I run the GS-SDF training node?

Source the workspace setup file, devel/setup.bash or setup.zsh, then run neural_mapping_node train with a config YAML and a data path, for example the replica.yaml config with the Replica/room2 directory. The same pattern is used for the colmap configs, so runs are compared by config file.

Is GS-SDF released yet?

There are no GitHub releases, and the README says the paper is under peer review and the code will be released once the paper is accepted, while the repository description already names IROS 2025. The last push was on 2026-07-16 on the master branch, so there is no tagged artefact to pin.

Official sources

  1. hku-mars/GS-SDF on GitHub
  2. Issues
  3. License: GPL-2.0
  4. Project website
  5. README
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/hku-mars-gs-sdf.svg)](https://hysenlabs.com/projects/hku-mars-gs-sdf)

Was this useful?