Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 149 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,156 @@
CUDA Path Tracer
================

**University of Pennsylvania, CIS 565: GPU Programming and Architecture, Project 3**
* **University of Pennsylvania, CIS 565: GPU Programming and Architecture, Project 2**

* (TODO) YOUR NAME HERE
* Tested on: (TODO) Windows 22, i7-2222 @ 2.22GHz 22GB, GTX 222 222MB (Moore 2222 Lab)
- #### Author information

### (TODO: Your README)
- Tianming Xu (Mark)
- www.linkedin.com/in/tianming-xu-8bb81816a (LinkedIn)
- Tested on: Windows 10, i7-8700 @ 3.20GHz 16GB, GTX 2080 8192MB (my personal desktop)

*DO NOT* leave the README to the last minute! It is a crucial part of the
project, and we will not be able to grade you without a good README.
### Output Screenshots

###### Mirror World

![](img/mirror_world.png)

### General overview

Path tracing is a rendering algorithm such that stimulates how lights bounce around in the real-world scenario. In every path tracing image, we have a scene containing all the topological information of all objects in the picture. We render every pixel of the image based on the amount of light hitting on the object on that pixel and the material color and attributes of that object. Therefore, the image generated by it is based on the physical rule of the real-world and looks very "realistic".

![](img/bsdf.png)



​ (https://en.wikipedia.org/wiki/Bidirectional_scattering_distribution_function)

​ The three fundamental ways light translate in the scene

However, there is a fundamental difference between the path tracing and real-world light: the light in path tracing starts from the eye, or usually said as camera, and try to reach the light source, while in the real-world, the light comes from light source to the eye. Therefore, that is why path tracing is also said "backward tracing".

![](img/real_world_light.PNG)

​ This is how light bounces in the real-world

![](img/backward_tracing.PNG)

​ This is how light works in the path tracer

In this project, we not only implement a path tracer, but also use GPU CUDA cores to accelerate the rendering process significantly.

### Features

#### Overview

- Shading kernel with BSDF features: diffuse, reflective and refractive with Fresnel law
- Kernel optimization: terminating path using stream compaction
- Kernel optimization: sorting material in global memory
- Kernel optimization: caching the first layer path and their intersections for the rest iterations
- Stochastic sampled antialiasing
- Motion blur



#### Details

###### basic scene

![](img/basic_scene.png)

###### three materials

![](img/three_materials.png)

Three materials

top mid: reflective

botom right: refractive with IOR 1.55

bottom left: diffuse yellow

###### Stochastic sampled antialiasing

With Antialiasing

![](img/with_antialiasing.png)

Without antialiasing

![](img/without_antialiasing.png)

The idea of antialiasing is fairly simple: in each iteration we generate the initial ray with a little bit offset within a certain range. As more iterations have been rendered, the color of the pixel will be blend with its surrounding pixel and form a very natural transition especially on the boundary of object.

It is not very obvious in the large screenshot, so I enlarge the picture to see it more closely to show the effect.

![](img/with_aa_enlarge.PNG)

​ The boundary of cube is more like a straight line when AA is on

​ ![](img/without_aa_enlarge.PNG)

​ Notice the boundary of cube is very serrated when AA is not on

###### Motion Blur

![](img/blur.png)

![](img/motion_blur.png)

Motion blur is a very cool effect. The basic idea behind it is that. We add a velocity to the object, and for each iteration, we slowly but continuously update the position of the object. The updated position will also be shaded as the object's color while blurring with its previous color, causing such effect.

I made a funny mistake when I update the position of object too fast, which makes my object fly out of scene after several iteration.

### Performance Analysis

We use our basic scene, which doesn't have anti-aliasing, stream compaction, first ray cache and sorting materials, as the benchmark to compare with the three optimizations we do on our CUDA code.



###### Stream compaction

![](img/ray_terminated_compact.png)

The idea of stream compaction is that, as the ray terminates in some reasons( hits on light source or doesn't hit anything in the scene), we don't actually need it in the next several bounces. Hence, we should remove them from our ray pools to reduce the number of thread required in the next bounce, accelerating the speed.

![](img/time_compact.png)

In this figure, we can clearly see the improvement of applying stream compaction algorithm in our CUDA code. The threads saved from terminated ray can be allocated to compute the remaining ray instead of being idle for the rest of time.



###### Sorting by materials

Sorting by materials seems to be unnecessary if we implement a normal CPU path tracer. However, it is an optimization in GPU version because the bottleneck of the efficiency in GPU is not computation, but memory I/O. Therefore, sorting rays by materials can maximize the utilization of locality for getting data from global memory, which significantly improve the performance.

![](img/time_sorting.png)

However, we don't see the improvement as we expected. Instead, the time for each iteration raises significantly comparing to the program without using this technique. The possible reason I guess, is that the number of materials in my benchmark scene(very basic) is too small to make this technique show its efficiency. Sorting is a time consuming algorithm, so if the number of materials is not very large, the sorting time can outweighs the time we saved from utilizing locality. When we render a complex scene, this technique might perform better I guess.



###### Cache first ray and intersection

Because the initial rays generated from camera(eye) are fixed, and we have many iterations to render a picture. It is natural to think of a way to cache the fixed data and use them later. The performance of this technique shows up after the first iteration, as we still need to generate rays in the first iteration. Hence, I only compare the performance after the first iteration.

![](img/time_cache.png)

The improvement on the performance is exactly what we expected.



### Acknowledgements

- Motion blur
- http://www.cemyuksel.com/research/papers/time_interval_ray_tracing_for_motion_blur-high.pdf
- Yue Li
- Jie Meng and Hannah for helping me solve the sorting by materials optimization
- Jiangping Xu for helping me stream compaction part and refractive material in Fresnel law
- also the Schlick's approximation formula in https://en.wikipedia.org/wiki/Schlick's_approximation



### Comments and Future work

There are some issues when I try to run the path tracer in Release mode, so I use Debug mode to collect data. Therefore, the performance of the program is significantly slower, but the relative efficiency comparison should still be valid. I will work on fixing the issues and update the chart later.
Binary file added img/50_50chance_by_diffuse.PNG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/after_mod.PNG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/backward_tracing.PNG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/basic_scene.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/blur.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/bsdf.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/low_depth.PNG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/mirror_world.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/motion_blur.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/motion_blur_debug.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/ray_terminated_compact.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/real_world_light.PNG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/three_materials.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/time_cache.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/time_compact.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/time_sorting.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/too_light_when_add_depth.PNG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/with_aa_enlarge.PNG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/with_antialiasing.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/without_aa_enlarge.PNG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/without_antialiasing.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 20 additions & 1 deletion scenes/cornell.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,17 @@ REFR 0
REFRIOR 0
EMITTANCE 0

// Diffuse yellow
MATERIAL 5
RGB .85 .85 .35
SPECEX 0
SPECRGB 0 0 0
REFL 0
REFR 0
REFRIOR 0
EMITTANCE 0


// Camera
CAMERA
RES 800 800
Expand Down Expand Up @@ -112,6 +123,14 @@ SCALE .01 10 10
OBJECT 6
sphere
material 4
TRANS -1 4 -1
TRANS -1 5 -1
ROTAT 0 0 0
SCALE 3 3 3

// Cube
OBJECT 7
cube
material 5
TRANS 2 2 1
ROTAT 0 45 0
SCALE 3 4 3
135 changes: 135 additions & 0 deletions scenes/cornell_motion.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
// Emissive material (light)
MATERIAL 0
RGB 1 1 1
SPECEX 0
SPECRGB 0 0 0
REFL 0
REFR 0
REFRIOR 0
EMITTANCE 5

// Diffuse white
MATERIAL 1
RGB .98 .98 .98
SPECEX 0
SPECRGB 0 0 0
REFL 0
REFR 0
REFRIOR 0
EMITTANCE 0

// Diffuse red
MATERIAL 2
RGB .85 .35 .35
SPECEX 0
SPECRGB 0 0 0
REFL 0
REFR 0
REFRIOR 0
EMITTANCE 0

// Diffuse green
MATERIAL 3
RGB .35 .85 .35
SPECEX 0
SPECRGB 0 0 0
REFL 0
REFR 0
REFRIOR 0
EMITTANCE 0

// Specular white
MATERIAL 4
RGB .98 .98 .98
SPECEX 0
SPECRGB .98 .98 .98
REFL 1
REFR 0
REFRIOR 0
EMITTANCE 0

// Diffuse yellow
MATERIAL 5
RGB .85 .85 .35
SPECEX 0
SPECRGB 0 0 0
REFL 0
REFR 0
REFRIOR 0
EMITTANCE 0


// Camera
CAMERA
RES 800 800
FOVY 45
ITERATIONS 5000
DEPTH 8
FILE cornell
EYE 0.0 5 10.5
LOOKAT 0 5 0
UP 0 1 0


// Ceiling light
OBJECT 0
cube
material 0
TRANS 0 10 0
ROTAT 0 0 0
SCALE 3 .3 3
VELOCITY 0 0 0

// Floor
OBJECT 1
cube
material 1
TRANS 0 0 0
ROTAT 0 0 0
SCALE 10 .01 10
VELOCITY 0 0 0

// Ceiling
OBJECT 2
cube
material 1
TRANS 0 10 0
ROTAT 0 0 90
SCALE .01 10 10
VELOCITY 0 0 0

// Back wall
OBJECT 3
cube
material 1
TRANS 0 5 -5
ROTAT 0 90 0
SCALE .01 10 10
VELOCITY 0 0 0

// Left wall
OBJECT 4
cube
material 2
TRANS -5 5 0
ROTAT 0 0 0
SCALE .01 10 10
VELOCITY 0 0 0

// Right wall
OBJECT 5
cube
material 3
TRANS 5 5 0
ROTAT 0 0 0
SCALE .01 10 10
VELOCITY 0 0 0

// Sphere
OBJECT 6
sphere
material 5
TRANS -1 4 -1
ROTAT 0 0 0
SCALE 3 3 3
VELOCITY 1 0 0
Loading