This project implements ray tracing using CUDA for computation and OpenGL for rendering. It leverages the cuda_gl_interop
library provided by Nvidia for efficient data transfer between CUDA and OpenGL. The implementation includes various geometric primitives, bounding volume hierarchy (BVH) for acceleration, and depth of field effects.
⚠️ Warning: This project was intended to be a technical and fast experimentation. The code here does not reflect my full capabilities in terms of code architecture and optimization. I just wanted to spend 5 days learning as much new technical notions as possible. There are still technical points that I need to fix later also.
The project supports various geometric primitives, including:
- Bezier surfaces
- Squares
- Spheres
- Cylinders
- Meshes
BVH is an acceleration structure that enhances rendering performance by organizing geometric primitives within a hierarchical tree of bounding volumes. This structure allows the ray tracing algorithm to quickly eliminate large portions of the scene that do not intersect with a given ray, thereby reducing the number of intersection tests required.
Depth of field (DoF) is an effect that simulates the focus properties of a camera lens. In ray tracing, DoF is achieved by:
- Aperture: The aperture size determines the depth of field; a larger aperture results in a shallower depth of field.
- Focal Distance: This is the distance from the camera at which objects are in perfect focus. Rays are sampled within the aperture and focused on the focal plane, creating a natural blur for objects not in focus.
- CUDA-capable GPU (I used my own laptop for this project, a RTX 3070 Laptop with Ampere architecture)
- CUDA Toolkit
- OpenGL
-
Clone the repository:
git clone https://github.com/yourusername/CUDA_RayTracing.git
-
Open the
Visual Studio solution
inCUDA_RayTracing\CUDA_RayTracing.sln
. -
Build the solution.
-
Launch
CUDA_RayTracing.exe
.
- Load scenes from the ImGUI GUI.
- Choose between continuously generating frames or rendering a single image.
- Set depth of field, aperture, and focal distance.
- Take screenshots (GUI is not included in the screenshots).
- Change texture size (number of pixels processed by CUDA).
- Adjust viewport size (window size where the rendered image is displayed).
Use Nvidia NSight Compute for detailed performance analysis and optimization of CUDA kernels.
- Ray Tracing with CUDA and OpenGL: Efficient integration using
cuda_gl_interop
. - Geometric Primitives: Supports bezier surfaces, squares, spheres, cylinders, and meshes.
- Bounding Volume Hierarchy (BVH): Optimizes rendering by efficiently managing spatial data.
- Depth of Field: Simulates camera focus with adjustable aperture and focal distance.
- CUDA/OpenGL Interoperability Documentation
- CUDA Architecture Code Matching for different setups
- Post on how occupancy influences kernel performances
- BVH: Bounding Volume Hierarchy
- Acceleration Techniques (BVH/Kd-Tree/Octree)
- GDC Convention on Fundamental Optimizations
- Visual Studio Configuration: Ensure
Properties/Cuda C/C++/Common/Generate Relocatable Device Code
is enabled for external symbol linking. - GPU Architecture: For an RTX 3070 Laptop, use
sm_86
architecture. - Thread and Block Configuration: Utilize a 16x16 thread block size. Calculate the number of blocks as
(width + block_size - 1) / block_size
and(height + block_size - 1) / block_size
. - Performance Profiling: Use Nvidia NSight Compute for performance profiling.
- Stack Size Management: Manage stack size with
cudaDeviceSetLimit(cudaLimitStackSize, N)
. - Random Seed Generation: Ensure unique seeds for each device to avoid correlation in random number generation.