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: Han Yan #3

Open
wants to merge 21 commits into
base: base-code
Choose a base branch
from
73 changes: 68 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,74 @@ 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)
* Han Yan
* Tested on: CETS Virtual Lab

### (TODO: Your README)
### Performance Analysis

*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.
* Influence on number of iterations

* scenes/cornell.txt

Without denoising, this scene takes about 4000 to 5000 iterations to get a smooth image.

With denoising, the image after 1000 iterations is already quite snooth.

* Without denoising (1000 iterations)

![](img/cornell.2020-10-18_20-59-08z.1009samp.png)

* Denoising (1000 iterations)

![](img/cornell.2020-10-18_20-59-08z.1009samp_denoised.png)

* scenes/cornell_ceiling_light.txt

Without denoising: 1500 iterations

With denoising: 600 iterations

* Without denoising (600 iterations)

![](img/cornell.2020-10-18_21-12-10z.666samp.png)

* Denoising (600 iterations)

![](img/cornell.2020-10-18_21-12-10z.666samp_denoised.png)

Denoising is more effective on scenes/cornell.txt, where the lighting is more sparse. This is reasonable since sparse lighting can create many 'black' pixels in the raw raytracing image, generating lots of noise. And denoising can seem more effective on noisy image.

* Influence on run time

* Tested with 'scenes/cornell.txt', filter size 80

Without denoising, each iteration takes about ~37 ms. But when denoising is turned on, each iteration takes ~100 ms.
So each iteration of filtering can take up to 12 ms.

This additional run time by denoiser can become more trivial in cases where raw path tracing takes longer time (eg. higher resolution).

* Tested with 'scenes/cornell_ceiling_light.txt', filter size 80

Without denoising, each iteration takes about ~34 ms. But when denoising is turned on, each iteration takes ~96 ms.

Each iteration of filtering still takes the same amount of time.

* Effects on different material types

I think it's more effective on diffusive materials. Since for diffusive materials, rays are scattered randomly, many rays may not reach emissive light source and the surface can be noisy. Denoising effectively mitigates the randomness and thus creates a smooth surface after fewer iterations. On the other hand, scattering on reflective/refrative surface is a bit more determined, so pixels neighboring each other can be quite similar even without denoising.

* Varying filter size

* Using 'scenes/cornell.txt', denoising with filter size 40 takes ~50 ms, whereas denoising with filter size 80 takes ~63 ms. Filter size 40 requires one less filtering iteration than 80, and the difference in time corresponds to exactly one iteration of filtered calculated previously. Smaller filter size reduces run time.

* Visual comparison (1000 iterations)

Filter size = 40

![](img/cornell.2020-10-18_21-36-05z.1010samp_denoised.png)

Filter size = 80

![](img/cornell.2020-10-18_20-59-08z.1009samp_denoised.png)

It seems to me that filter size 80 generates a smoother image. For different scenes, there could be different optimal filter sizes.
Binary file added img/cornell.2020-10-18_20-59-08z.1009samp.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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.2020-10-18_21-12-10z.666samp.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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.2020-10-18_21-16-15z.1558samp.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion scenes/cornell_ceiling_light.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ EMITTANCE 0
CAMERA
RES 800 800
FOVY 45
ITERATIONS 10
ITERATIONS 5000
DEPTH 8
FILE cornell
EYE 0.0 5 10.5
Expand Down
36 changes: 34 additions & 2 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ int lastLoopIterations = 0;
bool ui_showGbuffer = false;
bool ui_denoise = false;
int ui_filterSize = 80;
int lastFilterSize = 80;
float ui_colorWeight = 0.45f;
float ui_normalWeight = 0.35f;
float ui_positionWeight = 0.2f;
Expand Down Expand Up @@ -118,14 +119,30 @@ void saveImage() {
// CHECKITOUT
img.savePNG(filename);
//img.saveHDR(filename); // Save a Radiance HDR file

image imgDenoised(width, height);

for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
int index = x + (y * width);
glm::vec3 pix = renderState->imageDenoised[index];
imgDenoised.setPixel(width - 1 - x, y, glm::vec3(pix));
}
}
ss << "_denoised";
filename = ss.str();
imgDenoised.savePNG(filename);
}

void runCuda() {
if (lastLoopIterations != ui_iterations) {
lastLoopIterations = ui_iterations;
camchanged = true;
}

if (lastFilterSize != ui_filterSize) {
lastFilterSize = ui_filterSize;
camchanged = true;
}
if (camchanged) {
iteration = 0;
Camera &cam = renderState->camera;
Expand Down Expand Up @@ -160,12 +177,27 @@ void runCuda() {
if (iteration < ui_iterations) {
iteration++;

// start timer
cudaEvent_t start, stop;
cudaEventCreate(&start);
cudaEventCreate(&stop);
cudaEventRecord(start);

// execute the kernel
int frame = 0;
pathtrace(frame, iteration);

// time
cudaEventRecord(stop);
cudaEventSynchronize(stop);
float milliseconds = 0.f;
cudaEventElapsedTime(&milliseconds, start, stop);
std::cout << "Iteration " << iteration << ": " << milliseconds << " ms" << std::endl;
}

if (ui_showGbuffer) {
if (ui_denoise) {
showDenoiser(pbo_dptr);
} else if (ui_showGbuffer) {
showGBuffer(pbo_dptr);
} else {
showImage(pbo_dptr, iteration);
Expand Down
Loading