Vulkan implementation of Fast Volume Rendering with Spatiotemporal Reservoir Resampling.
- Zhihao Ruan ([email protected]), Shubham Sharma ([email protected]), Raymond Yang ([email protected])
- Tested on: Windows 10 Home 21H1 Build 19043.1288, Ryzen 7 3700X @ 3.59GHz 48GB, RTX 2060 Super 8GB
This project requires an RTX-compatible (Vulkan Ray Tracing KHR-compatible) graphics card to run.
Volume-ReSTIR | Normal ReSTIR |
---|---|
Ray Traced Volume Rendering (with OBJ Models) | Ray Traced Volume Rendering |
---|---|
Rasterization | Path Tracing |
---|---|
This project depends on the following softwares/drivers:
- C++ 17
- Vulkan SDK 1.2.189.2
- OpenVDB 8.0+
- CUDA 11.3+
This project relies on Vcpkg to provide Windows support. Before building the code, one should make sure a working Vcpkg is installed in the system.
- Install OpenVDB using Vcpkg:
vcpkg install openvdb --triplet=x64-windows
vcpkg integrate install
- Create a build folder in the project directory.
mkdir build; cd build
- Specify the root directory of Vcpkg in CMake configurations (default to be
C:\vcpkg
):
cmake .. -DVcpkg_ROOT=<PATH_TO_VCPKG>
If using CMake GUI, add a cache entry "Vcpkg_ROOT" of type STRING
and type in the path to Vcpkg root folder.
- On CMake GUI, Configure and generate the project.
- Open Visual Studio 2019, select
volume_restir
project as startup project, and run the project.
Before building, make sure that a working version of OpenVDB has been installed in the system.
mkdir build; cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j
./bin/volume_restir
This project achieves the following:
- Vulkan ray tracing pipeline with nvpro and Vulkan Ray Tracing KHR extension.
- Volume assets loading and rendering through OpenVDB.
- ReSTIR algorithm rendering on GLTF scene and volume assets.
ReSTIR has been a very successful fast path tracing-based rendering algorithm in recent computer graphics. However, the current state-of-the-art ReSTIR algorithm only works with meshes. Moreover, there exists some common objects in the scene that are not suitable for mesh creation. VDB asset is a special kind of asset that compensates the drawback of meshes and provides a much more accurate description for volume-based objects, such as smokes, clouds, fire flames, etc. Therefore, it is of great importance to migrate current ReSTIR procedures on volume assets so that we could also render the smokes and clouds photo-realistically and efficiently.
VDB is a special type of data structure for smokes, clouds, fire flames, etc. that is based on hierarchical voxel grids. It essentially holds a set of particles. It also uses a similar tree-like data structure as scene graphs for fast traversal and access that stores all transformations at intermediate nodes, and only the particle positions at leaf nodes.
Source:
- Spatiotemporal reservoir resampling for real-time ray tracing with dynamic direct lighting
- Fast Volume Rendering with Spatiotemporal Reservoir Resampling
ReSTIR algorithm is a special ray tracing-based rendering algorithm that deals with large number of light source efficiently. It takes advantage of alias tables for Resampled Importance Sampling (RIS) and flexible reservoir data structures. RIS effectively culls images of low weight lights and constructs a PDF of lights for the scene. The reservoirs, allocated one for each pixel, map geometry collisions to light sources in the scene. The reservoirs are easily updated for every bounce, each time considering a candidate from a subset of all lights. If the candidate is chosen, the reservoir will map the geometry to the new light. As more samples are considered, it becomes less likely for any candidate to be placed into the reservoir. These reservoirs use a combination of probability and giving up precision to generate result pixel color such that the image converges in near real time.
Vulkan is considered as the next-generation API for uniform graphics drivers. It is fast, efficient, light weight, but yet verbose. Vulkan users needs to explicitly set up every little details of the entire rendering pipeline, which is often quite problematic. In this project we provide an explicit example of setting up a working Vulkan rendering pipeline, and it generally involves the following procedures:
- Set up glfw to work with the latest version of Vulkan.
- Initialize Vulkan instance, Vulkan physical device, Vulkan logical device, Vulkan swapchain (for passing to frame buffer display), Vulkan graphics command queue.
- Create all buffers to be passed to device memory. This includes: frame buffer, rendering pipeline description buffer, data buffer (primitive vertices, indices, normals, materials, textures, etc.).
- Create descriptor set for all device buffers. Vulkan descriptor set defines the stage that GPU reads the data (either in vertex shader, fragment shader, or any stage in the ray tracing pipeline) and the way that GPU reads the data (either as uniform samplers, uniform images, storage buffers, uniform buffers, etc.).
- Bind the data buffer with the corresponding descriptor set.
- Create the graphics pipeline. Graphics pipelines are defined in
VkPipeline
, which specifies the actual procedures of an entire render pass. It can either be defined as a rasterization pipeline (vertex shader --> primitive assembly --> rasterization --> fragment shader), or a ray tracing pipeline (ray generation shader --> ray intersection shader --> ray closest hit shader/ray miss shader --> post processing fragment shader). - Get the current command buffer, prepare the frame, and run the pre-defined pipeline with all device buffers passing in using descriptor sets.
Vulkan does not render objects directly. Instead, it uses multiple command queues to queue all commands to be passed onto device. This is actually very similar to CUDA as CUDA also uses multiple streams to send commands to the GPU. That's why the graphics command queue comes in.
The ray tracing pipeline in Vulkan requires the usage of Vulkan Acceleration structures. The acceleration structure are divided into two levels to allow shared usage of geometry resources. For example, if you have a high poly model of sphere mesh formed with 30000 triangles, a great optimisation on the memory side would be to create the acceleration structure only once and transform it two detect intersection of rays with it.
The structure is stored in form of AABBs and can be controlled by
- Bottom Level Acceleration Structure (BLAS) - Used for creating the the Axis Aligned bounding box for a geometry. Vulkan Provides built in feature to build the AABBs for the triangle primitives but we have to specify the AABBs ourselves for non primitive geometry such as Sphere in our case.
- Top Level Acceleration structure - Points to an instance of BLAS, this allows easy transformations of an exisiting instance of BLAS across the scene. Note - BLAS requires the AABBs to be passed as 4 bit floating point. So if you see any un intended behaviour do look at memory padding in C++.
It is generally very hard to set up a complete Vulkan rendering pipeline from the lowest-level Vulkan libraries. Nowadays, there have been many different styles of Vulkan libraries wrappers for cleaner code production. In this project we took the advantage of nvpro to set up a clean Vulkan pipeline for us.
- Milestone 1 Presentation By milestone 1, we have set up a basic Vulkan rendering pipeline using vk-bootstrap.
- Milestone 2 Presentation By milestone 2, we have set up general 3D rendering in Vulkan and volume rasterization with OpenVDB
- Milestone 3 Presentation By milestone 3, we have set up a pipeline for path tracing volumetric data and a separate pipeline for ReSTIR on triangle mesh 3D data.
- Daqi Lin, Chris Wyman, Cem Yuksel. Fast Volume Rendering with Spatiotemporal Reservoir Resampling. ACM Transactions on Graphics (Proceedings of SIGGRAPH Asia 2021), 40, 6, 2021.
- Benedikt Bitterli, Chris Wyman, Matt Pharr, Peter Shirley, Aaron Lefohn, and Wojciech Jarosz. 2020. Spatiotemporal reservoir resampling for real-time ray tracing with dynamic direct lighting. ACM Trans. Graph. 39, 4, Article 148 (July 2020), 17 pages. DOI:https://doi.org/10.1145/3386569.3392481
- Volume Rendering
- Volume Rendering (Nvidia)
- Ray Tracing Gems II
- Vulkan Ray Tracing Tutorial
- OpenVDB for VDB data loading.
- nvpro for Vulkan Ray Tracing KHR setup.
- spdlog for fast C++ logging.
- nvpro-samples/vk_mini_path_tracer
- nvpro-samples/vk_raytracing_tutorial_KHR
- dipmizu914/ReSTIR_on_Vulkan
- Common graphics utilities glfw, glm, stb. These are all included in the nvpro.