diff --git a/README.md b/README.md index f044c821..d0883d62 100644 --- a/README.md +++ b/README.md @@ -3,11 +3,160 @@ 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) +**[Repo link](https://github.com/IwakuraRein/Nagi)** -### (TODO: Your README) +- Alex Fu + + - [LinkedIn](https://www.linkedin.com/in/alex-fu-b47b67238/) + - [Twitter](https://twitter.com/AlexFu8304) + - [Personal Website](https://thecger.com/) -*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. +Tested on: Windows 10, i7-10750H @ 2.60GHz, 16GB, GTX 3060 6GB +## Feature + +A real-time path tracing denoiser. Reference: [*Spatiotemporal variance-guided filtering: real-time reconstruction for path-traced global illumination*](https://dl.acm.org/doi/10.1145/3105762.3105770). + + + +## G-Buffer optimization + +![](./img/gbuffer.png) + +In order to better represent the geometries of reflection, I blend the geometries according to material types: + +Diffuse material: + +* Albedo buffer: store first bounce albedo + +* Normal buffer: store first bounce normal + +* Depth buffer: store first bounce depth + +Glossy Material: + +- Albedo buffer: blend the first and second bounce albedo + +- Normal buffer: store first bounce normal + +- Depth buffer: store first bounce depth + +Specular Material: + +* Albedo buffer: blend the albedo until hits non-specular material + +* Normal buffer: store the first non-specular material's normal + +* Dpeth buffer: accumulate the depth until hits non-specular material + +This denoiser is based on SVGF so there is another buffer storing the square luma. + +The square luma is calculated by: + +$SqrLuma = (\{ 0.299, 0.587, 0.114 \} \cdot ( Color \div (Albedo + \epsilon ))^2$ + +Also notice that the final albedo buffer is the blend of all spp's albedo buffer. + +## Denoiser + +![](./img/denoiser.png) + +The denoiser is essentially a bilateral wavelet filter. Its weight can be denoted by: + +$W = W_Z \cdot W_N \cdot W_L$ + +where + +$W_Z = \exp(-\frac{|Z(p) - Z(q)|}{\sigma_Z + \epsilon})$ + +$W_N = \mathrm{max}(0, N(p) \cdot N(q))^{\sigma_N}$ + +$W_L = \exp(-\frac{|L(p) - L(q)|}{\sigma_L \cdot Dev + \epsilon})$ + +Where the luminance $L$ is calculated by + +$L = Color \div (Albedo + \epsilon )$ + +The deviation $Dev$ is calculated by: + +$\mathrm{clamp}(g_{3 \times 3}(\sqrt{|SqrLuma(p)-(\{ 0.299, 0.587, 0.114 \}\cdot L(p))^2|}), \epsilon, 1)$ + +where $g_{3 \times 3}$ is the 3X3 gaussian filter. + +In practice, the filter size is 5X5, $\sigma_Z$ is 1, $\sigma_N$ is 64, and $\sigma_L$ is 4. The image will be iteratively denoised 4 times, with the dilation of 1, 2, 4, and 8. + +To stabilize the preview, the GUI will blend the last result and the current result. + +## Comapre to Gaussian Filter + + + + + + + + + + +
wavelet filtergaussian filter
+ +The results of wavelet filter and gaussian filter look similar. However, the computation of wavelet filter is less. + +## Performance Analysis + +As shown in the demonstration video, it took 64 iterations for generating a plausible result for an inner scene. + +### Performance impacted by resolutions + +![](./img/resolutions.png) + +![](./img/resolutions2.png) + +### Performance impacted by luminance weight + +![](./img/Wl.png) + +By introducing the luminance weight, the filter will be aware of the edges between light and dark, thus better preserving the edges of shadows and light sources. + +Also, introducing the deviation term further improves the edge preservation and can decrease the blurring as the rendering result converges. With more and more samples, the $Dev$ and $W_L$ will become closer to zero. + +### Performance impacted by wavelet filter + +By adding dilations, wavelet filters can a have larger reception field than normal filters with similar computational costs. + + + + + + + + + + +
5x5 wavelet filter, 4 times, 4.96ms9x9 normal filter, 5ms
+ +At the same time cost, the wavelet filter generates better result. + +### Performance impacted by filter size + + + + + + + + + + +
9x9 wavelet filter, 4 times, 18.5ms7x7 wavelet filter, 4 times, 10.9ms
+ + + + + + + + + + +
5x5 wavelet filter, 4 times, 4.96ms3x3 wavelet filter, 4 times, 2ms
diff --git a/img/3x3_wavelet.png b/img/3x3_wavelet.png new file mode 100644 index 00000000..526b0e88 Binary files /dev/null and b/img/3x3_wavelet.png differ diff --git a/img/5x5_wavelet.png b/img/5x5_wavelet.png new file mode 100644 index 00000000..eda3f570 Binary files /dev/null and b/img/5x5_wavelet.png differ diff --git a/img/7x7_wavelet.png b/img/7x7_wavelet.png new file mode 100644 index 00000000..9bbf7512 Binary files /dev/null and b/img/7x7_wavelet.png differ diff --git a/img/9x9_normal.png b/img/9x9_normal.png new file mode 100644 index 00000000..a0ac544f Binary files /dev/null and b/img/9x9_normal.png differ diff --git a/img/9x9_wavelet.png b/img/9x9_wavelet.png new file mode 100644 index 00000000..77c1e444 Binary files /dev/null and b/img/9x9_wavelet.png differ diff --git a/img/Wl.png b/img/Wl.png new file mode 100644 index 00000000..36b51063 Binary files /dev/null and b/img/Wl.png differ diff --git a/img/albedo.png b/img/albedo.png new file mode 100644 index 00000000..5ce4c93e Binary files /dev/null and b/img/albedo.png differ diff --git a/img/denoiser.png b/img/denoiser.png new file mode 100644 index 00000000..a0a410e9 Binary files /dev/null and b/img/denoiser.png differ diff --git a/img/depth.png b/img/depth.png new file mode 100644 index 00000000..eeb0f151 Binary files /dev/null and b/img/depth.png differ diff --git a/img/gaussian.png b/img/gaussian.png new file mode 100644 index 00000000..a80777ca Binary files /dev/null and b/img/gaussian.png differ diff --git a/img/gbuffer.png b/img/gbuffer.png new file mode 100644 index 00000000..12050646 Binary files /dev/null and b/img/gbuffer.png differ diff --git a/img/header.png b/img/header.png new file mode 100644 index 00000000..ab86eee2 Binary files /dev/null and b/img/header.png differ diff --git a/img/normal.png b/img/normal.png new file mode 100644 index 00000000..5748d743 Binary files /dev/null and b/img/normal.png differ diff --git a/img/resolutions.png b/img/resolutions.png new file mode 100644 index 00000000..eee9acbf Binary files /dev/null and b/img/resolutions.png differ diff --git a/img/resolutions2.png b/img/resolutions2.png new file mode 100644 index 00000000..68ba5b4c Binary files /dev/null and b/img/resolutions2.png differ diff --git a/img/wavelet.png b/img/wavelet.png new file mode 100644 index 00000000..58e3cad0 Binary files /dev/null and b/img/wavelet.png differ