A Neural Radiance Field in C++ and LibTorch. Takes images of a static scene with known camera poses, fits a radiance field, and renders RGB and depth from new viewpoints.
![]() |
![]() |
|---|---|
| RGB | Depth |
Under 1000 lines of C++ implementing a NeRF end to end: ray generation, Fourier positional encoding, a SIREN network, hierarchical sampling with a proposal network, volume rendering, and PSNR/SSIM evaluation. No framework abstraction, no Python in the training loop. The whole pipeline is small enough to step through in a debugger.
The scope is narrow:
- Plain LibTorch ops, not Instant-NGP or fused CUDA kernels. Minutes to hours, not seconds.
- No pose estimation. You supply camera poses; use COLMAP or nerfstudio for that.
- Bounded scenes only. Objects inside a near/far shell, like the NeRF synthetic set. No unbounded 360° scenes, no mip-NeRF cone tracing.
- One input format, the
transforms.jsondocumented in docs/usage.md.
For state-of-the-art quality or speed use nerfstudio or instant-ngp. This repo is for reading the algorithm.
On the NeRF synthetic scenes at 160×160 it reaches 25.1 PSNR / 0.90 SSIM on lego over 13 held-out views. Full numbers and method in docs/internals.md.
Everything the build needs — compiler, CMake, LibTorch, nlohmann_json, and ImageMagick for the GIFs — comes from one conda environment. A CUDA GPU is strongly recommended.
1. Create the environment.
git clone https://github.com/Bharath2/NeRF.cpp
cd NeRF.cpp
conda env create -f environment.yml
conda activate nerfcppThat installs a CUDA 13 LibTorch, which needs an NVIDIA driver 580 or newer; on an older
driver, environment.yml says which two values to change. With no GPU at all, comment out
the six CUDA lines and uncomment the single cpu_mkl line before creating the
environment.
2. Build. CMake picks up LibTorch and nlohmann_json from the active environment, so there is nothing to configure:
cmake -B build
cmake --build build -jBuilding without conda
Download the LibTorch C++ distribution from the
PyTorch site, unzip it into the repo so that
./libtorch/share/cmake/Torch exists, and CMake finds it the same way. If you keep it
elsewhere, pass cmake -B build -DCMAKE_PREFIX_PATH=/path/to/libtorch. You also need a
C++20 compiler, CMake 3.20 or newer, and
nlohmann_json.
3. Train on the bundled lego scene. A 100-frame copy of the NeRF synthetic lego
scene ships in data/lego, so you can run immediately:
./build/NeRF.cpp data/lego output_legoStart with a short run to confirm everything works before committing to the full 10,000 iterations:
./build/NeRF.cpp data/lego output_lego --iters 200 --size 64Checkpoints, preview renders and metrics land in the output directory. Every 8th view is held out and never trained on, so the metrics are measured on unseen data.
4. Turn the frames into GIFs (ImageMagick, already in the conda environment):
bash scripts/make_gifs.sh output_lego 30 10000 100 5To rebuild the GIFs later without retraining, point RENDER_DATA at the scene and the
orbit is re-rendered from checkpoint.pt first:
RENDER_DATA=data/lego bash scripts/make_gifs.sh output_lego 30 10000 100 5--help lists every setting; none of them require a rebuild.
- docs/usage.md — running it on your own scenes: the
transforms.jsonformat, camera pose conventions, the full flag reference, output files, and troubleshooting. - docs/internals.md — how it works: rays, sampling strategies, network architecture, volume rendering, loss, evaluation, and measured results.
Issues and pull requests are welcome. Results on scenes outside the synthetic dataset would be useful. If you train it on something interesting, open an issue with the renders.
- NeRF: Representing Scenes as Neural Radiance Fields for View Synthesis (Mildenhall et al., ECCV 2020)
- Implicit Neural Representations with Periodic Activation Functions (Sitzmann et al., NeurIPS 2020)
- Mip-NeRF 360: Unbounded Anti-Aliased Neural Radiance Fields (Barron et al., CVPR 2022)
- cNeRF by rafaelanderka, another C++/LibTorch NeRF
BSD 3-Clause. If you use it in academic work, there is a CITATION.cff.

