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
76 changes: 71 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,77 @@ 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)
* Shixuan Fang
* Tested on: Windows 11, i7-12700kf, RTX 3080Ti

### (TODO: Your README)
# Project Overview

*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.
| Original | Denoised |
| ------------- |:-------------:|
|<img src="img/noise.png" width=300 height=300>|<img src="img/10spp.png" width=300 height=300>|

In this project, I implemented a pathtracing denoiser using A-trous wavelet filter.

<img src="https://user-images.githubusercontent.com/54868517/197315297-c679c20d-7fa1-4edb-a3fa-af63aa814d58.png" width=700 height=250>

A-trous is an approximation of gaussian blur by iteratively applying sparse blurs of increasing size, which significantly reduce the number of pixel read.

## G-Buffer

In order to use A-trous filter to denoise the result while preseving edges, we need extra information other than the path traced image.

|Normal|Position|
|------|:-------:|
|<img src="img/normal.jpg" width=300 height=300> |<img src="img/pos.jpg" width=300 height=300> |

## Performance Analysis

- how much time denoising adds to renders

![800](https://user-images.githubusercontent.com/54868517/197315609-766b58ce-e6d0-4e43-9315-0e191bcae323.jpg)

As seen in this figure, denoising only adds 2-3ms to the render, which is considered good enough for real-time rendering.

- how denoising influences the number of iterations needed to get an "acceptably smooth" result

|2spp|10spp|Ground Truth|
|------|:-------:|:-------------:|
|<img src="img/2spp.png" width=300 height=300> |<img src="img/10spp.png" width=300 height=300> |<img src="img/truch.png" width=300 height=300> |

As seen in this table, 10spp with denoising is acceptably smooth compared to the ground truth(5000spp).

- how denoising at different resolutions impacts runtime

![image](https://user-images.githubusercontent.com/54868517/197312998-79594b67-bc01-4701-b9e7-e6a04f5094f3.png)

As seen in this chart, with the increasement of screen resolution, the runtime of denoising also increases. This makes sense as there are more pixels to be considered, and A-trous filter needs more iterations to finish the whole picture, therefore denoising takes more time.

- how varying filter sizes affect performance

![image](https://user-images.githubusercontent.com/54868517/197314664-59f5fd76-cf51-473b-9c6d-76e3ab028a6c.png)

As seen in this chart, when filter size increases the runtime of denoising also increases. This also caused by the same reason, which is with filter size increases, the A-trous filter needs more iterations, therefore increases denoising time.

- how visual results vary with filter size

|1|16|32|100|
|------|:-------:|:--------:|:--------:|
|<img src="img/1.jpg" width=200 height=200> |<img src="img/16.jpg" width=200 height=200> |<img src="img/32.jpg" width=200 height=200> |<img src="img/80.jpg" width=200 height=200> |

This table shows how the denoised image looks with 1/16/32/80 filter size. The visual quality does increase from 1 to 16 and 16 to 32, but from 32 to 100 there aren't too much difference.

- how effective/ineffective is this method with different material types

|diffuse|specular|
|------|:-------:|
|<img src="img/diffuse.png" width=300 height=300> |<img src="img/10spp.png" width=300 height=300>|

As seen in this table, A-trous works better with diffuse object in my opinion, as with specular objects it will blur the reflection face, which will result in a very blury surface. This is because position buffer and normal buffer can't really help split the edges on the same surface.

- how do results compare across different scenes

|cornell|cornell_ceiling|
|------|:-------:|
|<img src="img/cornell.png" width=300 height=300> |<img src="img/10spp.png" width=300 height=300>|

As seen in this table, with same parameters, cornell_ceiling scene looks better and smoother than the cornell scene. This is because it has a larger light source, therefore making path tracing converge faster than small light source. Better path traced image will definitely makes denoised image better.
Binary file added img/1.jpg
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/1000.jpg
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/10spp.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/1200.jpg
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/16.jpg
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/2spp.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/32.jpg
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/80.jpg
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/800.jpg
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/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 img/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/gauss.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/noise.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/normal.jpg
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/pos.jpg
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/truch.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions scenes/cornell_ceiling_light.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,16 @@ REFR 0
REFRIOR 0
EMITTANCE 0

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

// Camera
CAMERA
RES 800 800
Expand Down
8 changes: 7 additions & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ float ui_normalWeight = 0.35f;
float ui_positionWeight = 0.2f;
bool ui_saveAndExit = false;


static bool camchanged = true;
static float dtheta = 0, dphi = 0;
static glm::vec3 cammove;
Expand Down Expand Up @@ -70,6 +71,7 @@ int main(int argc, char** argv) {
height = cam.resolution.y;

ui_iterations = renderState->iterations;
ui_iterations = 5000;
startupIterations = ui_iterations;

glm::vec3 view = cam.view;
Expand Down Expand Up @@ -165,7 +167,11 @@ void runCuda() {
pathtrace(frame, iteration);
}

if (ui_showGbuffer) {
if (ui_denoise) {
Denoise_Image(ui_colorWeight, ui_normalWeight, ui_positionWeight, ui_filterSize);
showDenoisedImage(pbo_dptr, iteration);
}
else if (ui_showGbuffer) {
showGBuffer(pbo_dptr);
} else {
showImage(pbo_dptr, iteration);
Expand Down
1 change: 1 addition & 0 deletions src/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ extern float ui_normalWeight;
extern float ui_positionWeight;
extern bool ui_saveAndExit;


void runCuda();
void keyCallback(GLFWwindow *window, int key, int scancode, int action, int mods);
void mousePositionCallback(GLFWwindow* window, double xpos, double ypos);
Expand Down
Loading