README.md
June 25, 2026 · View on GitHub
RNb-NeuS2: Multi-View Surface Reconstruction
Using Normal and Reflectance Cues
Robin Bruneau★ · Baptiste Brument★
Yvain Quéau . Jean Mélou · François Lauze · Jean-Denis Durou · Lilian Calvet
★ corresponding authors
Tip
🆕 RNb-NeuS2 is now available as a Meshroom node! Run the full pipeline (prepare → scale → train → mesh) directly inside Meshroom from SfMData inputs — see the Meshroom Plugin section.
Looking for a fully open-source, CUDA-library-free variant? Check out Open-RNb — a PyTorch / tiny-cuda-nn reimplementation integrated into Meshroom.
Table of Contents
Installation
RNb-NeuS2 builds on Instant-NGP; its requirements (a recent CUDA toolkit, a CUDA-capable NVIDIA GPU, CMake ≥ 3.18 and a C++14 compiler) apply here as well. Our build steps mirror theirs. OptiX is optional — if found it enables hardware ray tracing, but the project compiles fine without it.
1. Clone the repository
All C++/CUDA dependencies are vendored under dependencies/, so a plain clone is
enough:
git clone https://github.com/RobinBruneau/RNb-NeuS2/
cd RNb-NeuS2
2. Build the CUDA testbed with CMake
cmake . -B build
cmake --build build --config RelWithDebInfo -j
This produces the ./build/testbed executable used by the training pipeline.
3. Create the Python environment
The Python side (data preparation, scene scaling, albedo scaling and pipeline
orchestration) lives in the rnb_neus2 package. Use either a plain venv or conda.
Option A — venv (no conda). Create the environment as a venv/ directory at the
repository root. This is also exactly what the Meshroom plugin
expects, so no extra symlink is needed later:
python3.10 -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -e .
Option B — conda.
conda create -n rnb2 python=3.10 # pick another name if "rnb2" already exists
conda activate rnb2
pip install -e .
Data
We provide the DiLiGenT-MV, LUCES-MV and Skoltech3D datasets with normals and reflectance maps estimated using SDM-UniPS and Uni-MS-PS. This link also contains the cleaned resulting meshes and ground truths.
Data Convention
Organize your data in the ./data/ folder following this structure:
./data/FOLDER/
normal/ # (Mandatory)
000.png
001.png
002.png
mask/ # (Mandatory)
000.png
001.png
002.png
albedo/ # (Optional — enables albedo-based training)
000.png
001.png
002.png
cameras.npz
Image files are matched by name across folders (e.g. normal/000.png,
mask/000.png, albedo/000.png describe the same view).
cameras.npz follows the data format in
IDR, where
world_mat_xx denotes the world-to-image projection matrix and scale_mat_xx
denotes the normalization matrix.
Training
Reconstruction is driven by a single Python entry point, run_pipeline.py, which
runs the full pipeline: load data → normalize the scene → train the CUDA testbed →
(optionally) scale albedos → extract the mesh.
Baseline (normals only)
python run_pipeline.py --input ./data/FOLDER --testbed ./build/testbed --output ./out/FOLDER
The reconstructed mesh is written to ./out/FOLDER/mesh.obj.
Reproduce the paper results (with reflectance)
To use reflectance maps, add --has-albedo. This enables two-phase training and
automatically scales the reflectance maps via multi-view consistency — required to
reproduce the results of our paper:
python run_pipeline.py --input ./data/FOLDER --testbed ./build/testbed \
--output ./out/FOLDER --has-albedo
Other options
--max-steps INT # Total training steps (default: 10000)
--mesh-resolution INT # Marching cubes resolution (default: 1024; use 512 if low on memory)
--scaling-mode MODE # auto | pcd | silhouettes | silhouettes_v2 | cameras | none (default: auto)
--sphere-scale FLOAT # Target sphere radius after normalization (default: 1.0)
--mask-weight FLOAT # Weight of the mask loss (default: 1.0)
--l1 # Use L1 color loss (L2 by default)
--no-rgbplus # Disable the reflectance-singularity (RGB+) correction
--supernormal # SuperNormal sub-case (single-stage, normals only)
--warmup-ratio FLOAT # Fraction of steps for the geometry-only warmup (albedo mode, default: 0.1)
A console entry point is also installed with the package:
rnb-neus2 --input ./data/FOLDER --testbed ./build/testbed --output ./out/FOLDER
Advanced: calling the testbed directly
The compiled ./build/testbed can be driven manually for custom experiments
(the Python pipeline wraps these same calls):
--scene FOLDER # Path to the prepared data
--maxiter INT # Number of iterations
--mask-weight FLOAT # Weight of the mask loss
--save-mesh # Extract the mesh at the end
--save-snapshot # Save the neural weights
--no-albedo # Train only on normals
--lone # Apply L1 loss (L2 by default)
--resolution INT # Marching cubes resolution (default 1024)
--no-gui # Run without GUI
--supernormal # Apply the canonical lights (SuperNormal)
--opti-lights # Apply the optimal triplet of lights per pixel
--no-rgbplus # Disable the reflectance-singularity correction
Meshroom Plugin
RNb-NeuS2 ships a Meshroom node,
RNbNeuS2, that runs the entire pipeline (prepare → scale → train → mesh)
from AliceVision SfMData inputs — no manual data conversion required.
Install (3 steps):
- Build the testbed and create the Python environment (see Installation).
- Make the package importable inside Meshroom as the plugin
venv/. Meshroom expects avenv/directory at the plugin root and adds it to its Python path.- If you used Option A (
venv), you already havevenv/at the repository root — nothing to do. - If you used Option B (conda), symlink the conda environment from the
repository root, with it active:
ln -s "$CONDA_PREFIX" venv
- If you used Option A (
- Register the plugin and start Meshroom:
export MESHROOM_PLUGINS_PATH=/path/to/RNb-NeuS2 meshroom
The path to the testbed is read from meshroom/config.json
(RNB_NEUS2_TESTBED_PATH, default ../build/testbed); adjust it if your build
lives elsewhere.
Use it: drop an RNbNeuS2 node in your graph, connect a normal-maps SfMData to
Normal Maps SfMData (and, optionally, albedo/mask SfMData), then compute. The
node outputs the reconstructed mesh.obj in world coordinates.
📖 Full node reference (all inputs/outputs, CLI equivalents): see
meshroom/README.md.
Acknowledgements & Citation
@article{Bruneau26,
title={{Multi-view Surface Reconstruction Using Normal and Reflectance Cues}},
author={Robin Bruneau and Baptiste Brument and Yvain Quéau and Jean Mélou and François Bernard Lauze and Jean-Denis Durou and Lilian Calvet},
journal={International Journal of Computer Vision (IJCV)},
volume={134},
number={2},
pages={69},
year={2026},
doi={10.1007/s11263-025-02628-8},
url={https://doi.org/10.1007/s11263-025-02628-8}
}
@inproceedings{Brument24,
title={{RNb-NeuS: Reflectance and Normal-based Multi-View 3D Reconstruction}},
author={Baptiste Brument and Robin Bruneau and Yvain Quéau and Jean Mélou and François Lauze and Jean-Denis Durou and Lilian Calvet},
booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},
year={2024}
}
This project is built on NeuS2.