Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Project 4: XiaoyuDu #29

Open
wants to merge 24 commits into
base: base-code
Choose a base branch
from
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
72 changes: 67 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,73 @@ CUDA Denoiser For CUDA Path Tracer

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

* (TODO) YOUR NAME HERE
* Tested on: (TODO) Windows 22, i7-2222 @ 2.22GHz 22GB, GTX 222 222MB (Moore 2222 Lab)
* XiaoyuDu
* Tested on: Windows 10, i9-11900KF @ 3.50GHz, RTX 3080 (Personal PC)

### (TODO: Your README)

### Description
This project built a denoiser based on an GPU-based path tracer. The algorithm of the denoiser follows the mthods proposed in the paper "Edge-Avoiding À-Trous Wavelet Transform for fast Global Illumination Filtering" by Holger Dammertz, Daniel Sewtz, Johannes Hanika, Hendrik P.A. Lensch.


### Feature
* I implemented all the features for part 2.
* I implemented G-buffer optimization to switch the position of G-buffer from 3 float(glm::vec3) to 1 float(z-depth).
* I implemented a complete 7x7 gaussian kernel and a GUI checkbox to switch between A-trous kernel and gaussian kernel.

*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.
### Analysis
* Runtime for Denoiser
I tested the denoiser with 10 iterations of the cornell box scene. Averagely speaking, after adding the denoiser, the runtime for each iteration increased for about 1.11242ms.
* Influence on the number of iterations
I tested the influence of denoiser with filter size of 20, color weight of 12, normal weight of 0.02, and position weight of 0.34. The results are shown below. As you can see, originally, we need around 500 iterations to get an "acceptably smooth" result. With this denoiser, only around 60 iterations are needed to get an "acceptably smooth" result.

| Denoiser on | Denoiser off |
| ----------------- | ----------------- |
| 1 iteration | 30 iterations |
| ![](images/cornell_ceiling/1_d.png) | ![](images/cornell_ceiling/29.png) |
| 6 iterations | 100 iterations |
| ![](images/cornell_ceiling/6_d.png) | ![](images/cornell_ceiling/99.png) |
| 60 iterations | 500 iterations |
| ![](images/cornell_ceiling/60_d.png) | ![](images/cornell_ceiling/500.png) |

* Impact of Different Resolutions on Runtime
Below is a chart that compare the runtime with different resolutions. The runtime are counted in millisecond for 50 iterations. The resolution are tested from 1000x1000 to 2500x2500. Note, the increase in resolutions is not linear, so the increase in the difference of runtime is also not linear. However, we can notice from the overall trends that the runtime increase should be linear with respect to number pixels.
![](images/runtime_vs_resolution.png)

* Impact of filter sizes on Runtime
The impact of filter sizes on runtime are tested with a resolution of 1000x1000 and iterations of 50. The runtime are counted in millisecond for 50 iterations. The filter size are tested from 10x10 to 80x80. I am expecting the runtime increase as filter size increase. The result generally shows this trends and also a linear relationship with respect to the filter size.
![](images/filtersize_vs_runtime.png)

* Impact of filter sizes on Image
Generally speaking, the image quality will increase as the filter size increase. In the example below, I tested the impact of different filter sizes with 10 iterations, color weight of 3.9, normal weight of 0.01, position weight of 0.025. As shown in the result, the quality of image looks better with higher filter size. When the filter size is above 40, I can't see the difference between the images I got anymore.

| FilterSize = 10 | FilterSize = 20 | FilterSize = 40 |
| ----------------- | ----------------- | --- |
| ![](images/cornell_ceiling/filtersize/10.png) | ![](images/cornell_ceiling/filtersize/20.png) | ![](images/cornell_ceiling/filtersize/40.png) |

* Effectiveness of this method on different materials
I tested the effectiveness of this method on lambert, ideal reflective and idea refractive materials. I change the colors of all materials to be yellow and tested each scene with 50 iterations, filter size of 20, color weight of 3.9, normal weight of 0.01, position weight of 0.025. The results are shown below. Based on the result, I think the method works well on all these three materials.

| | Denoiser on | Denoiser off |
| --- | ----------------- | ----------------- |
| lambert | ![](images/cornell_ceiling_2/d_lambert.png) | ![](images/cornell_ceiling_2/lambert.png) |
| Ideal reflective | ![](images/cornell_ceiling_2/d_reflective.png) | ![](images/cornell_ceiling_2/reflective.png) |
| Ideal refractive | ![](images/cornell_ceiling_2/d_refractive.png) | ![](images/cornell_ceiling_2/refractive.png) |

* Results across Different Scenes
I tested the result between the "cornell.txt" scene which is the standard cornell box scene and the "cornell_ceiling_light.txt" scene which is the standard cornell box scene with a much larger ceiling light. I tested the two scenes with 50 iterations, filter size of 20, color weight of 10, normal weight of 0.01, position weight of 0.025. Note here I choose color weight of 10 because a higher color weight is needed for generating a good results for the "cornell.txt" scene. The result are shown below. From the results, we can see that the scene with a larger light converge to a much better result than the scene with standard light. The reason behind is that with a larger light, each ray is more likely to hit the light source and thus are more likely to provide useful and correct color information for this pixel. With standard cornell box scene, many rays may not hit the light source for many iterations and thus still give only black color for a pixel, and thus won't provide good result when we try to average the image with denoiser. One better solution is to switch our integrator to full-light integrator which will actively gather information from light sources instead of the naive integrator we currently have.

| standard cornell box scene | cornell box scene with larger light |
| ------ | -- |
| ![](images/cornell_ceiling_1and2/cornell.png) | ![](images/cornell_ceiling_1and2/cornell_ceiling.png) |

### Extra Features
* G-buffer Optimization
I also implemented G-buffer optimization that uses Z-depth instead of glm::vec3 for positions in the G-buffer. On the GUI, I added a checkbox called "using Z for position". You can check it to switch to z-depth mode and uncheck it to switch back to vec3 mode. I compared the difference between the two modes and the results are shown below. The result below are tested with 50 iterations, resolutions from 1000x1000 to 3000x3000. We can see that the runtime of z-depth mode are slightly smaller than vec3 mode for all resolution and it also seems to be linear to the resolution.
![](images/zdepth_vs_vec3.png)

* Gaussian kernel
I also implemented a complete 7x7 gaussian kernel. Since gaussian kernel is different for different kernel dimension I just choose one dimension to implement which is 7x7. On the GUI, I added a checkbox called "gaussian" which can be checked to switch between gaussian kernel and A-trous kernel. Below is a compare result with gaussian kernel and A-trous. I set the filter size as 7, iterations as 50. Now, no matter how I adjust the parameters, the results from gaussian kernel and A-trous all look really similar. So I think that A-trous is a quite good approximate to gaussian kernel.

| gaussian kernel | A-trous kernel |
| --- | --- |
| ![](images/gaussian/gaussian.png) | ![](images/gaussian/no_gaussian.png) |
Binary file added images/cornell_ceiling/1_d.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 images/cornell_ceiling/29.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 images/cornell_ceiling/500.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 images/cornell_ceiling/60_d.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 images/cornell_ceiling/6_d.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 images/cornell_ceiling/99.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 images/cornell_ceiling/filtersize/10.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 images/cornell_ceiling/filtersize/20.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 images/cornell_ceiling/filtersize/40.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 images/cornell_ceiling_1and2/cornell.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 images/cornell_ceiling_1and2/cornell_ceiling.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 images/cornell_ceiling_2/d_lambert.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 images/cornell_ceiling_2/d_reflective.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 images/cornell_ceiling_2/d_refractive.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 images/cornell_ceiling_2/lambert.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 images/cornell_ceiling_2/reflective.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 images/cornell_ceiling_2/refractive.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 images/filtersize_vs_runtime.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 images/gaussian/gaussian.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 images/gaussian/no_gaussian.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 images/runtime_vs_resolution.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 images/zdepth_vs_vec3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions scenes/cornell.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ EMITTANCE 0

// Camera
CAMERA
RES 800 800
RES 1000 1000
FOVY 45
ITERATIONS 5000
ITERATIONS 50
DEPTH 8
FILE cornell
EYE 0.0 5 10.5
Expand Down
4 changes: 2 additions & 2 deletions scenes/cornell_ceiling_light.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ EMITTANCE 0

// Camera
CAMERA
RES 800 800
RES 1000 1000
FOVY 45
ITERATIONS 10
ITERATIONS 50
DEPTH 8
FILE cornell
EYE 0.0 5 10.5
Expand Down
148 changes: 148 additions & 0 deletions scenes/cornell_ceiling_light2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
// Emissive material (light)
MATERIAL 0
RGB 1 1 1
SPECEX 0
SPECRGB 0 0 0
REFL 0
REFR 0
REFRIOR 0
EMITTANCE 1

// 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

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

// yellow refractive
MATERIAL 5
RGB .98 .98 .8
SPECEX 0
SPECRGB .98 .98 .98
REFL 0
REFR 1
REFRIOR 0
EMITTANCE 0

// yellow reflectance
MATERIAL 6
RGB .98 .98 .8
SPECEX 0
SPECRGB .98 .98 .98
REFL 1
REFR 0
REFRIOR 0
EMITTANCE 0

// yellow lambert
MATERIAL 7
RGB .98 .98 .8
SPECEX 0
SPECRGB .98 .98 .98
REFL 0
REFR 0
REFRIOR 0
EMITTANCE 0


// Camera
CAMERA
RES 1000 1000
FOVY 45
ITERATIONS 40
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 10 .3 10

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

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

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

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

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

// Sphere
OBJECT 6
sphere
material 5
TRANS -1 4 -1
ROTAT 0 0 0
SCALE 3 3 3
6 changes: 5 additions & 1 deletion src/interactions.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,11 @@ void scatterRay(
glm::vec3 newDirection;
if (m.hasReflective) {
newDirection = glm::reflect(pathSegment.ray.direction, normal);
} else {
}
else if (m.hasRefractive) {
newDirection = pathSegment.ray.direction;
}
else {
newDirection = calculateRandomDirectionInHemisphere(normal, rng);
}

Expand Down
Loading