Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
8421472
Remove unused freeglut copyrights
shehzan10 Jan 16, 2021
a79ca55
Update CUDA Computes List
shehzan10 Sep 10, 2021
78e028a
Retab
shehzan10 Sep 10, 2021
c03780d
Update instructions for Fall 2021
shehzan10 Sep 18, 2021
80ad206
Add vulkan option
shehzan10 Sep 18, 2021
cc3da39
Add sample readmes for inspiration
shehzan10 Sep 19, 2021
784f5ca
Merge pull request #1 from CIS565-Fall-2021/update-instructions-2021
shehzan10 Sep 21, 2021
6d7e696
Added Imgui Integration Files
codeplay9800 Sep 19, 2022
8462d52
Updated Instruction.md
codeplay9800 Sep 19, 2022
c44fccb
Update Instruction.md
codeplay9800 Sep 19, 2022
7165f5c
Merge branch 'main' into Integrate_Imgui
codeplay9800 Sep 19, 2022
26e8bf3
Imgui Integrated
codeplay9800 Sep 20, 2022
3dac24e
Added GUIDataContainer Class
codeplay9800 Sep 20, 2022
e666e6a
Removed ImGUI Cmake
codeplay9800 Sep 21, 2022
5000086
Update INSTRUCTION.md
shehzan10 Sep 21, 2022
98f098c
Fix a bug that causes MouseOverImGuiWindow() to not work
dw218192 Sep 22, 2022
16d6638
Merge pull request #1 from dw218192/patch-1
codeplay9800 Sep 22, 2022
bd3573f
finish part of part_1
FridaWang Sep 25, 2022
8502743
merge conflicts
FridaWang Sep 25, 2022
797885c
finish part1
FridaWang Sep 25, 2022
8ca143f
finish refraction
FridaWang Sep 29, 2022
451686a
finish DOF
FridaWang Sep 29, 2022
b8a2aad
finish motion blur(fake)
FridaWang Sep 30, 2022
855e910
fix dof
FridaWang Sep 30, 2022
0905ed9
finish loading obj (w/o bounding box)
FridaWang Oct 5, 2022
b034c4f
finish obj loading with bounding box
FridaWang Oct 6, 2022
43d17ed
update readme
FridaWang Oct 9, 2022
25e9919
Update README.md
FridaWang Oct 9, 2022
f00b929
Update README.md
FridaWang Oct 10, 2022
690140d
Update README.md
FridaWang Oct 10, 2022
063251b
Update README.md
FridaWang Oct 10, 2022
02890ab
add performance img
FridaWang Oct 21, 2022
8cdeaec
Merge branch 'main' of github.com:FridaWang/Project3-CUDA-Path-Tracer
FridaWang Oct 21, 2022
ac47730
Update README.md
FridaWang Oct 22, 2022
05b7bf6
Update README.md
FridaWang Oct 22, 2022
0e989e7
Update README.md
FridaWang Oct 22, 2022
a33a85e
Update INSTRUCTION.md
FridaWang Oct 22, 2022
82af501
tiny fix
FridaWang Oct 22, 2022
2d5b174
Update main.cpp
FridaWang Oct 22, 2022
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
26 changes: 25 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,19 @@ set(headers
src/sceneStructs.h
src/preview.h
src/utilities.h
src/ImGui/imconfig.h

src/ImGui/imgui.h
src/ImGui/imconfig.h
src/ImGui/imgui_impl_glfw.h
src/ImGui/imgui_impl_opengl3.h
src/ImGui/imgui_impl_opengl3_loader.h
src/ImGui/imgui_internal.h
src/ImGui/imstb_rectpack.h
src/ImGui/imstb_textedit.h
src/ImGui/imstb_truetype.h

src/tiny_obj_loader.h
)

set(sources
Expand All @@ -84,6 +97,16 @@ set(sources
src/scene.cpp
src/preview.cpp
src/utilities.cpp

src/ImGui/imgui.cpp
src/ImGui/imgui_demo.cpp
src/ImGui/imgui_draw.cpp
src/ImGui/imgui_impl_glfw.cpp
src/ImGui/imgui_impl_opengl3.cpp
src/ImGui/imgui_tables.cpp
src/ImGui/imgui_widgets.cpp

src/tiny_obj_loader.cpp
)

list(SORT headers)
Expand All @@ -92,10 +115,11 @@ list(SORT sources)
source_group(Headers FILES ${headers})
source_group(Sources FILES ${sources})

#add_subdirectory(src/ImGui)
#add_subdirectory(stream_compaction) # TODO: uncomment if using your stream compaction

cuda_add_executable(${CMAKE_PROJECT_NAME} ${sources} ${headers})
target_link_libraries(${CMAKE_PROJECT_NAME}
${LIBRARIES}
#stream_compaction # TODO: uncomment if using your stream compaction
)
)
382 changes: 131 additions & 251 deletions INSTRUCTION.md

Large diffs are not rendered by default.

82 changes: 75 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,81 @@
CUDA Path Tracer
CUDA Denoiser For CUDA Path Tracer
================

**University of Pennsylvania, CIS 565: GPU Programming and Architecture, Project 3**
**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)
* Wenqing Wang
* [LinkedIn](https://www.linkedin.com/in/wenqingwang0910/)
* Tested on: Windows 11, i7-11370H @ 3.30GHz 16.0 GB, GTX 3050 Ti

### (TODO: Your README)
## Overview
This project implements a pathtracing denoiser that uses geometry buffers (G-buffers) to guide a smoothing filter. The impelmentation is based on the paper "Edge-Avoiding A-Trous Wavelet Transform for fast Global Illumination Filtering," by Dammertz, Sewtz, Hanika, and Lensch. The paper could be found here: https://jo.dreggn.org/home/2010_atrous.pdf

| 300 iterations |300 iterations + denoiser |
|--|--|
|![cornell 2022-10-22_00-58-24z 300samp](https://user-images.githubusercontent.com/33616958/197310311-90423e9f-5a26-4884-bb23-013639b7eb4a.png)|![cornell 2022-10-22_00-32-41z 300samp](https://user-images.githubusercontent.com/33616958/197308568-a95d1f1e-2961-47fa-8d47-9519e7b07cf0.png)|

| 1500 iterations | 300 iterations + denoiser |
|--|--|
|![cornell 2022-10-22_01-04-47z 1500samp](https://user-images.githubusercontent.com/33616958/197310320-b51ccc73-aacb-4ac7-af51-4559ce170887.png)|![cornell 2022-10-22_00-32-41z 300samp](https://user-images.githubusercontent.com/33616958/197308568-a95d1f1e-2961-47fa-8d47-9519e7b07cf0.png)|

## Features
### G-Buffers visualization
| denoised raw image | per-pixel positions (scaled down) | per-pixel normals|
|---|---|---|
|<img width="362" alt="normal_celling" src="https://user-images.githubusercontent.com/33616958/197309468-495c922a-97d3-49c1-b130-9dc9c4168711.png">|<img width="361" alt="gbuff_pos" src="https://user-images.githubusercontent.com/33616958/197309460-b139e7e1-f16c-463b-8388-c006e0eb6ee6.png">|<img width="359" alt="gbuff_nor" src="https://user-images.githubusercontent.com/33616958/197309459-3732457c-0f7d-45b2-8a81-f7f08aa563af.png">|

### A-trous w/wo G-buffer(edge voiding)
The following renders are base on 100 iterations.
| raw image | raw image + A-tour | raw image + A-tour + G-Buffer|
|---|---|---|
|![cornell 2022-10-22_00-44-51z 100samp](https://user-images.githubusercontent.com/33616958/197309666-ff18f840-c93c-4d17-8736-a5d329362ee4.png) | ![cornell 2022-10-22_00-44-28z 100samp](https://user-images.githubusercontent.com/33616958/197309679-eed15a11-d924-4a66-825e-5bba3216efe4.png) | ![cornell 2022-10-22_00-42-13z 100samp](https://user-images.githubusercontent.com/33616958/197309695-1c00f6d8-7af4-49ab-a1c6-c8adb8500a62.png) |

From the rendering above, we can see that with only A-tour implemented, the whole image is blurred out by our denoiser, which is not the denoising result we expect. To keep the denoised edges clear, we store the position, normal and albedo (color) information in the G-Buffer. In general, if the values of these attributes change dramatically between 2 pixels, we assume that an edge is present. In the third figure, we can see that after implementing the G-Buffer, the edges of the sphere, the junction of the left and right walls with the floor and ceiling are not blurred anymore. For different scenes, we can also tune the weight for each properties to get a better denoised result.

## Performance Analysis

### Denoise quality vs. Filter size
| Filter size = 40 | Filter size = 80 | Filter size = 160 |
|---|---|---|
| ![fs_40](https://user-images.githubusercontent.com/33616958/197314839-2792f1a7-17ed-45f8-b023-8857352f7405.png) | ![fs_80](https://user-images.githubusercontent.com/33616958/197314849-35d55c99-473c-4ff1-bf3f-81b83c2a9233.png) | ![fs_160](https://user-images.githubusercontent.com/33616958/197314856-686ec6de-159c-4b93-8291-724a74dc8fc4.png) |

Although increasing the size of the filter improves the effectiveness of our denoiser, the visual quality does not scale uniformly with the size of the filter. In my tests, when I scaled the filter size to 200 and above, the final denoising result was almost the same as when the filter size was equal to 160.

### Denoise quality vs. Different material type
| raw image | denoised image|
|--|--|
|![cornell 2022-10-22_02-40-43z 100samp](https://user-images.githubusercontent.com/33616958/197315971-1e56e9f0-4d23-47fe-a50e-b0b27ca40a5a.png)|![cornell 2022-10-22_02-38-38z 100samp](https://user-images.githubusercontent.com/33616958/197315967-1c470038-5c00-4dad-aee7-0d8f8cf519c1.png)|

The materials of the three spheres are refraction, pure reflection and diffuse from left to right. According to the denoising results, our denoiser has the best compatibility with diffuse materials under the same parameter Settings, and can smooth the surface of the sphere to a more ideal result even with a smaller filter size and a smaller number of iterations. However, for purely reflective materials, we can see that even if we implement the edge-voiding denoising algorithm, the edge of the reflected scene in the sphere will still be blurred. This is because for the scene reflected from the surface of the sphere, the positions and normals of the corresponding pixels are continuous on the sphere, which reduces the effect of the edge detection algorithm. For refractive materials, denoising will not only blur the scene edges refracted by the surface, but also change the appearance of the original material.



### Small light source vs. large light source
|small light source | large light source|
|--|--|
|![cornell 2022-10-22_00-46-15z 100samp](https://user-images.githubusercontent.com/33616958/197309832-c7f31d90-70a7-4963-ba0b-9171f971b80b.png)|![cornell 2022-10-22_00-44-51z 100samp](https://user-images.githubusercontent.com/33616958/197309666-ff18f840-c93c-4d17-8736-a5d329362ee4.png) |

The amount of light in the scene is another factor that can affect the effectiveness of our denoiser. Both images above are rendered with the same filter size (=80), number of iterations (=100) and G-Buffer weights, and we can see that the denoiser can provide less noisy results in the second scene. I think this is because for the same number of iterations, our scene can converge faster with a larger light source because the light ray has a higher probability of hitting the light source.

### Time vs. Resolution
![PA_time_vs_resolution](https://user-images.githubusercontent.com/33616958/197292266-36120899-5396-4cbf-b83b-f097fc451459.png)

We can see from the results in the above figure that the denoising time in general increases linearly with the increase of the scene resolution size.

### Time vs. Filter size
![PA_time_vs_filter](https://user-images.githubusercontent.com/33616958/197292281-4d207eb5-2717-4a12-98b7-90b1993e010c.png)

We can see from the results above that the denoising time in general increases logarithmically with the increase in filter size.

### Time vs. Iterations
![PA_time_vs_iter](https://user-images.githubusercontent.com/33616958/197292287-66688b4c-6b56-41bd-9e80-0c1448325591.png)

As we can see from the above results, while the overall iteration time of our path tracer increases linearly with the number of iterations, the running time of denoiser remains roughly constant (about 12 ms). From the paper we can learn that the time complexity of the A-tour algorithm is depend on filter size and scene resolution (number of pixels), but not to the properties of the pixels themselves. Therefore, the result is in line with our expectation.

## Blooper

<img width="402" alt="blooper1" src="https://user-images.githubusercontent.com/33616958/197292408-e2df1aa0-dfd8-4097-b388-eea226175315.png">

<img width="596" alt="blooper2" src="https://user-images.githubusercontent.com/33616958/197292412-5168a47b-2a45-4bae-8ced-c95d22905184.png">

*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.

8 changes: 5 additions & 3 deletions cmake/CUDAComputesList.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ IF( CUDA_COMPUTE_20
OR CUDA_COMPUTE_70
OR CUDA_COMPUTE_72
OR CUDA_COMPUTE_75
OR CUDA_COMPUTE_80
OR CUDA_COMPUTE_86
)
SET(FALLBACK OFF)
ELSE()
Expand All @@ -70,8 +72,8 @@ LIST(LENGTH COMPUTES_DETECTED_LIST COMPUTES_LEN)
IF(${COMPUTES_LEN} EQUAL 0 AND ${FALLBACK})
MESSAGE(STATUS "You can use -DCOMPUTES_DETECTED_LIST=\"AB;XY\" (semicolon separated list of CUDA Compute versions to enable the specified computes")
MESSAGE(STATUS "Individual compute versions flags are also available under CMake Advance options")
LIST(APPEND COMPUTES_DETECTED_LIST "30" "50" "60" "70")
MESSAGE(STATUS "No computes detected. Fall back to 30, 50, 60 70")
LIST(APPEND COMPUTES_DETECTED_LIST "30" "50" "60" "70" "80")
MESSAGE(STATUS "No computes detected. Fall back to 30, 50, 60, 70, 80")
ENDIF()

LIST(LENGTH COMPUTES_DETECTED_LIST COMPUTES_LEN)
Expand All @@ -90,7 +92,7 @@ MACRO(SET_COMPUTE VERSION)
ENDMACRO(SET_COMPUTE)

# Iterate over compute versions. Create variables and enable computes if needed
FOREACH(VER 20 30 32 35 37 50 52 53 60 61 62 70 72 75)
FOREACH(VER 20 30 32 35 37 50 52 53 60 61 62 70 72 75 80 86)
OPTION(CUDA_COMPUTE_${VER} "CUDA Compute Capability ${VER}" OFF)
MARK_AS_ADVANCED(CUDA_COMPUTE_${VER})
IF(${CUDA_COMPUTE_${VER}})
Expand Down
96 changes: 48 additions & 48 deletions cmake/FindGLFW.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -20,66 +20,66 @@
include(FindPackageHandleStandardArgs)

if (WIN32)
# Find include files
find_path(
GLFW_INCLUDE_DIR
NAMES GLFW/glfw3.h
PATHS
$ENV{PROGRAMFILES}/include
${GLFW_ROOT_DIR}/include
DOC "The directory where GLFW/glfw.h resides")
# Find include files
find_path(
GLFW_INCLUDE_DIR
NAMES GLFW/glfw3.h
PATHS
$ENV{PROGRAMFILES}/include
${GLFW_ROOT_DIR}/include
DOC "The directory where GLFW/glfw.h resides")

# Use glfw3.lib for static library
if (GLFW_USE_STATIC_LIBS)
set(GLFW_LIBRARY_NAME glfw3)
else()
set(GLFW_LIBRARY_NAME glfw3dll)
endif()
# Use glfw3.lib for static library
if (GLFW_USE_STATIC_LIBS)
set(GLFW_LIBRARY_NAME glfw3)
else()
set(GLFW_LIBRARY_NAME glfw3dll)
endif()

# Find library files
find_library(
GLFW_LIBRARY
NAMES ${GLFW_LIBRARY_NAME}
PATHS
$ENV{PROGRAMFILES}/lib
${GLFW_ROOT_DIR}/lib)
# Find library files
find_library(
GLFW_LIBRARY
NAMES ${GLFW_LIBRARY_NAME}
PATHS
$ENV{PROGRAMFILES}/lib
${GLFW_ROOT_DIR}/lib)

unset(GLFW_LIBRARY_NAME)
unset(GLFW_LIBRARY_NAME)
else()
# Find include files
find_path(
GLFW_INCLUDE_DIR
NAMES GLFW/glfw.h
PATHS
/usr/include
/usr/local/include
/sw/include
/opt/local/include
DOC "The directory where GL/glfw.h resides")
# Find include files
find_path(
GLFW_INCLUDE_DIR
NAMES GLFW/glfw.h
PATHS
/usr/include
/usr/local/include
/sw/include
/opt/local/include
DOC "The directory where GL/glfw.h resides")

# Find library files
# Try to use static libraries
find_library(
GLFW_LIBRARY
NAMES glfw3
PATHS
/usr/lib64
/usr/lib
/usr/local/lib64
/usr/local/lib
/sw/lib
/opt/local/lib
${GLFW_ROOT_DIR}/lib
DOC "The GLFW library")
# Find library files
# Try to use static libraries
find_library(
GLFW_LIBRARY
NAMES glfw3
PATHS
/usr/lib64
/usr/lib
/usr/local/lib64
/usr/local/lib
/sw/lib
/opt/local/lib
${GLFW_ROOT_DIR}/lib
DOC "The GLFW library")
endif()

# Handle REQUIRD argument, define *_FOUND variable
find_package_handle_standard_args(GLFW DEFAULT_MSG GLFW_INCLUDE_DIR GLFW_LIBRARY)

# Define GLFW_LIBRARIES and GLFW_INCLUDE_DIRS
if (GLFW_FOUND)
set(GLFW_LIBRARIES ${OPENGL_LIBRARIES} ${GLFW_LIBRARY})
set(GLFW_INCLUDE_DIRS ${GLFW_INCLUDE_DIR})
set(GLFW_LIBRARIES ${OPENGL_LIBRARIES} ${GLFW_LIBRARY})
set(GLFW_INCLUDE_DIRS ${GLFW_INCLUDE_DIR})
endif()

# Hide some variables
Expand Down
44 changes: 22 additions & 22 deletions cmake/FindGLM.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
# Find GLM
#
# Try to find GLM : OpenGL Mathematics.
# This module defines
# This module defines
# - GLM_INCLUDE_DIRS
# - GLM_FOUND
#
# The following variables can be set as arguments for the module.
# - GLM_ROOT_DIR : Root library directory of GLM
# - GLM_ROOT_DIR : Root library directory of GLM
#
# References:
# - https://github.com/Groovounet/glm/blob/master/util/FindGLM.cmake
Expand All @@ -18,34 +18,34 @@
include(FindPackageHandleStandardArgs)

if (WIN32)
# Find include files
find_path(
GLM_INCLUDE_DIR
NAMES glm/glm.hpp
PATHS
$ENV{PROGRAMFILES}/include
${GLM_ROOT_DIR}/include
DOC "The directory where glm/glm.hpp resides")
# Find include files
find_path(
GLM_INCLUDE_DIR
NAMES glm/glm.hpp
PATHS
$ENV{PROGRAMFILES}/include
${GLM_ROOT_DIR}/include
DOC "The directory where glm/glm.hpp resides")
else()
# Find include files
find_path(
GLM_INCLUDE_DIR
NAMES glm/glm.hpp
PATHS
/usr/include
/usr/local/include
/sw/include
/opt/local/include
${GLM_ROOT_DIR}/include
DOC "The directory where glm/glm.hpp resides")
# Find include files
find_path(
GLM_INCLUDE_DIR
NAMES glm/glm.hpp
PATHS
/usr/include
/usr/local/include
/sw/include
/opt/local/include
${GLM_ROOT_DIR}/include
DOC "The directory where glm/glm.hpp resides")
endif()

# Handle REQUIRD argument, define *_FOUND variable
find_package_handle_standard_args(GLM DEFAULT_MSG GLM_INCLUDE_DIR)

# Define GLM_INCLUDE_DIRS
if (GLM_FOUND)
set(GLM_INCLUDE_DIRS ${GLM_INCLUDE_DIR})
set(GLM_INCLUDE_DIRS ${GLM_INCLUDE_DIR})
endif()

# Hide some variables
Expand Down
27 changes: 0 additions & 27 deletions external/include/GL/Copying.txt

This file was deleted.

Loading