This repository host a C++ implementation of the Restir algorithm inside Falcor 8.0.
Video showcase: https://www.youtube.com/watch?v=pyQrblYP_VY
Source code: https://github.com/Trylz/Restir_CPP/tree/main/Source/Samples/Restir
Here the original paper: https://research.nvidia.com/sites/default/files/pubs/2020-07_Spatiotemporal-reservoir-resampling/ReSTIR.pdf
The dragon buddha model used is huge. Git doesnt allow me to push files that are greater than 100 MB. That model need to be installed has explained here: https://github.com/Trylz/Restir_CPP/blob/main/TestScenes/DragonBuddha/README.txt
-
Windows 10 version 20H2 (October 2020 Update) or newer, OS build revision .789 or newer
-
Visual Studio 2022
-
Cmake
-
Cuda toolkit installed. Right now 12.6(https://developer.nvidia.com/cuda-12-6-0-download-archive) is hardcoded set(CMAKE_CUDA_COMPILER "C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v12.6/bin") in root CMakeLists.txt
You may want to change this to your current cuda installation but note that only 12.6 was tested.
This mean your CUDA_PATH environment variable should look something like this C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v12.6 -
An Nvidia GPU since Cuda is used
-
A GPU which supports DirectX Raytracing, such as the NVIDIA Titan V or GeForce RTX
-
NVIDIA driver 466.11 or newer
- Run the setup_vs2022.bat script after cloning this repository. The solution files are written to build/windows-vs2022.
- Open the Falcor.sln solution
- Set Samples/Restir as your startup project
- Set your configuration to Release(Unless you are debbuging)
- Build and run
Three test scenes are provided. The Arcade scene that ships with Falcor, the Sponza scene and the DragonBuddha scene.
To switch scene simply change the SCENE_NAME define inside RestirApp.cpp file
0: Arcade scene
1: Dragon buddha scene.
2: Sponza scene.
Restir specific source code is located here
https://github.com/Trylz/Restir_CPP/tree/main/Source/Samples/Restir
The application entry point is located in the RestirApp.cpp file
Reservoirs are managed by the reservoir manager. See ReservoirManager.cpp.
Lights are managed by the light manager. See LightManager.cpp.
This is where lights are created for each scene.
Right now only spherical(so area) lights are supported.
Scenes specific tweaks are stored in the SceneSettings struct.
GBuffer rendering is the first pass. It is generated by raytracing. See GBuffer.cpp.
Should ideally be done by rasterization to save time but doing so amplify flickering(See CURRENT ISSUES below) in my opinion.
So this is WIP see: #2
Resampled Importance Sampling is performed as described in paper. See RISPass.cpp
For each reservoir its weight is set to zero if occluded. So raytracing is performed here. See VisibilityPass.cpp
#define USE_TEMPORAL_FILTERING 1
We combine the current frame reservoirs with thoses of the previous frame. See TemporalFilteringPass.cpp
Here the dragon buddha scene with temporal filtering ON and OFF
ON: https://youtu.be/8Q-eVLcEUPY
OFF: https://youtu.be/iBL5fuxIujA
#define USE_SPATIAL_FILTERING 0
Combine each pixel reservoirs with thoses of its neighbors. This is disabled by default since i dont see any gain using it.
See SpatialFilteringPass.cpp
Shading is performed using the reservoirs from the previous passes. See ShadingPass.cpp.
#define USE_DENOISING 1
Denoising can be done using NRD or Optix denoiser
#define DENOISING_NRD 0
Note that NRD is currently performed on the final image(same for Optix). It is not recommended when i read the doc. So we may want to denoise the reservoirs instead? This is being investigated here: https://github.com/Trylz/Restir_CPP/tree/NRD-before-shading
This is work in progress and some artefacts are still visible.
Buddha_Flickering.mp4
Either my temporal filtering pass doesnt do a good job enough or it is the Optix denoiser. It is more noticeable when camera is far away from objects.
a) Dragon buddha scene
GIF: https://github.com/user-attachments/assets/3888a81e-9df1-4b40-9b1a-e8cc7dcd4dfe
b) Acnee with denoising OFF in Sponza scene
Video: https://youtu.be/tykjTZ2svXw
The glitch happens when moving fast then stoping close to an occluder.
This is CAUSED by the temporal filtering (See TemporalFilteringPass.slang). Then amplified by the denoiser
The following fixes it for the dragon buddha scene WHILE the Sponza scene still exibits it
- Apply a blue noise when shading using a reservoir shading = shading * min(reservoir.m_W * (4.0f * gBlueNoise[pixelIdx % 470].x), 10.0f); (ShadingPass.slang)
- Clamp temporal reservoirs M to smaller value. 5 instead of 20 mentioned in paper previousReservoir.mM = min(5 * currentReservoir.mM, previousReservoir.mM);
And you get this:
GIF: https://github.com/user-attachments/assets/e082b290-5991-4bc3-8c07-bc038b04338a
There is still lot of work to be done to have a production ready implementation. Performance wise a i am getting decent results for a raytracer.