Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 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
fa270e5
Update INSTRUCTION.md
HummaWhite Sep 16, 2023
0f1be54
Added a section for optimization
wayne-wu Sep 18, 2023
c5d6523
Update INSTRUCTION.md
HummaWhite Sep 19, 2023
be9cde2
warp up
Sep 24, 2023
a36835a
camera control
Sep 24, 2023
4d4dd84
strange artifact
Sep 24, 2023
c0e380e
fix strange artifact
Sep 25, 2023
a4ca3cd
thrust::remove_if compaction
Sep 26, 2023
d68fd9e
reflection
Sep 26, 2023
8142a61
add triangle intersection and try to add bvh
Sep 26, 2023
e40cac3
minor change
Sep 26, 2023
0c7b5af
load obj
Sep 27, 2023
9b06fd8
slow path tracer
Sep 28, 2023
f462a65
BVH need to improve
Sep 28, 2023
1c1c3be
BVH worked
Sep 29, 2023
75204a5
BVH axis improve
Sep 30, 2023
6c6f3dd
refract
Sep 30, 2023
a5bd2ab
material sort and compaction
Sep 30, 2023
13df4b4
cache first frame
Sep 30, 2023
22aa0e5
add cuda texture
Oct 3, 2023
2a0c1b3
texture
Oct 4, 2023
2fb8f2c
env map
Oct 4, 2023
e88af57
bump map
Oct 4, 2023
ab908cf
try to implement SSS
Oct 6, 2023
5d12b6c
thin lens camera
Oct 6, 2023
e63d584
add some mesh
Oct 7, 2023
92103c1
denoiser
Oct 17, 2023
3ecb86f
only denoise last frame
Oct 17, 2023
402beef
add timer, filtersize, debug mode
Oct 20, 2023
fd59025
handle conflict
Oct 20, 2023
96eef3f
Update INSTRUCTION.md
LichengCAO Oct 20, 2023
e642a71
update ReadMe.md
Oct 21, 2023
9d3f92c
fix conflict
Oct 21, 2023
bad3d4e
Update README.md
LichengCAO Oct 21, 2023
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
83 changes: 31 additions & 52 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,58 +62,37 @@ set(GLM_ROOT_DIR "external")
find_package(GLM REQUIRED)
include_directories(${GLM_INCLUDE_DIRS})

set(headers
src/main.h
src/image.h
src/interactions.h
src/intersections.h
src/glslUtility.hpp
src/pathtrace.h
src/scene.h
src/sceneStructs.h
src/preview.h
src/utilities.h
)

set(sources
src/main.cpp
src/stb.cpp
src/image.cpp
src/glslUtility.cpp
src/pathtrace.cu
src/scene.cpp
src/preview.cpp
src/utilities.cpp
)

set(imgui
imgui/imconfig.h
imgui/imgui.cpp
imgui/imgui.h
imgui/imgui_draw.cpp
imgui/imgui_internal.h
imgui/imgui_widgets.cpp
imgui/imgui_demo.cpp
imgui/imgui_impl_glfw.cpp
imgui/imgui_impl_glfw.h
imgui/imgui_impl_opengl2.cpp
imgui/imgui_impl_opengl2.h
imgui/imgui_impl_opengl3.cpp
imgui/imgui_impl_opengl3.h
)

list(SORT headers)
list(SORT sources)
list(SORT imgui)

source_group(Headers FILES ${headers})
source_group(Sources FILES ${sources})
source_group(imgui FILES ${imgui})

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

cuda_add_executable(${CMAKE_PROJECT_NAME} ${sources} ${headers} ${imgui})

# https://stackoverflow.com/questions/47910256/cmake-how-to-normalize-paths
file(TO_CMAKE_PATH "${CMAKE_SOURCE_DIR}/scenes" SCENE_PATH)
add_definitions(-DSCENE_PATH="${SCENE_PATH}/")
add_definitions(-DROOT_PATH="${CMAKE_SOURCE_DIR}")

file(GLOB SRC_FILES
"${PROJECT_SOURCE_DIR}/src/*.c"
"${PROJECT_SOURCE_DIR}/src/*.cpp"
"${PROJECT_SOURCE_DIR}/src/*.cc"
"${PROJECT_SOURCE_DIR}/src/*.cu"
"${PROJECT_SOURCE_DIR}/src/ImGui/*.cpp"
)

file(GLOB H_FILES
"${PROJECT_SOURCE_DIR}/src/ImGui/*.h"
"${PROJECT_SOURCE_DIR}/src/tinyobj/*.h"
"${PROJECT_SOURCE_DIR}/src/*.h"
"${PROJECT_SOURCE_DIR}/src/*.hpp"
"${PROJECT_SOURCE_DIR}/src/*.cuh"
)
list(SORT SRC_FILES)
list(SORT H_FILES)

#set(SRC_INCLUDE
# ${PROJECT_SOURCE_DIR}
#)

cuda_add_executable(${CMAKE_PROJECT_NAME} ${SRC_FILES} ${H_FILES})

target_link_libraries(${CMAKE_PROJECT_NAME}
${LIBRARIES}
#stream_compaction # TODO: uncomment if using your stream compaction
)
)
21 changes: 21 additions & 0 deletions CMakePresets.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"version": 2,
"configurePresets": [
{
"name": "windows-default",
"displayName": "Windows x64 Debug",
"description": "面向具有 Visual Studio 开发环境的 Windows。",
"generator": "Ninja",
"binaryDir": "${sourceDir}/out/build/${presetName}",
"architecture": {
"value": "x64",
"strategy": "external"
},
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}"
},
"vendor": { "microsoft.com/VisualStudioSettings/CMake/1.0": { "hostOS": [ "Windows" ] } }
}
]
}
17 changes: 13 additions & 4 deletions INSTRUCTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ Project 4 CUDA Denoiser - Instructions
=======================================

This is due **Friday October 20th** at 11:59pm EST.

**Summary:**

In this project, you'll implement a pathtracing denoiser that uses geometry buffers (G-buffers) to guide a smoothing filter.
Expand Down Expand Up @@ -85,12 +84,16 @@ Requirements

**Ask in Ed for clarifications.**


## Part 1 - Read!


One meta-goal for this project is to help you gain some experience in reading technical papers and implementing their concepts. This is an important skill in graphics software engineering, and will also be helpful for your final projects.


For part one, try to skim the paper, and then read through it in depth a couple times: https://jo.dreggn.org/home/2010_atrous.pdf


Try to look up anything that you don't understand, and feel free to discuss with your fellow students on Ed. We were also able to locate presentation slides for this paper that may be helpful: https://www.highperformancegraphics.org/previous/www_2010/media/RayTracing_I/HPG2010_RayTracing_I_Dammertz.pdf

This paper is also helpful in that it includes a code sample illustrating some of the math, although not
Expand Down Expand Up @@ -164,8 +167,10 @@ Implement methods to store positions and normals more compactly. Two places to s

Be sure to provide performance comparison numbers between optimized and unoptimized implementations.


## Comparing A-trous and Gaussian filtering


Dammertz-et-al mention in their section 2.2 that A-trous filtering is a means for approximating gaussian filtering. Implement gaussian filtering and compare with A-trous to see if one method is significantly faster. Also note any visual differences in your results.

## Shared Memory Filtering
Expand All @@ -175,12 +180,16 @@ Filtering techniques can be somewhat memory-expensive - for each pixel, the tech
Be sure to provide performance comparison numbers between implementations with and without shared memory.
Also pay attention to how shared memory use impacts the block size for your kernels, and how this may change as the filter width changes.


## Implement Temporal Sampling


High-performance raytracers in dynamic applications (like games, or real-time visualization engines) now often use temporal sampling, borrowing and repositioning samples from previous frames so that each frame effectively only computes 1 sample-per-pixel but can denoise from many frames.


This will require additional buffers, as well as reprojection code to move samples from where they were in a previous frame to the current frame.


Note that our basic pathtracer doesn't do animation, so you will also need to implement some kind of dynamic aspect in your scene - this may be as simple as an automated panning camera, or as complex as translating models.

See https://research.nvidia.com/publication/2017-07_Spatiotemporal-Variance-Guided-Filtering%3A for more details.
Expand All @@ -197,9 +206,9 @@ The template of the comment section of your pull request is attached below, you

* [Repo Link](https://link-to-your-repo)
* (Briefly) Mentions features that you've completed. Especially those bells and whistles you want to highlight
* Feature 0
* Feature 1
* ...
* Feature 0
* Feature 1
* ...
* Feedback on the project itself, if any.

References
Expand Down
65 changes: 60 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,66 @@ 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)
* Licheng CAO
* [LinkedIn](https://www.linkedin.com/in/licheng-cao-6a523524b/)
* Tested on: Windows 10, i7-10870H @ 2.20GHz 32GB, GTX 3060 6009MB

### (TODO: Your README)
Result
====
* Here are the denoiser results. The outcome is generally deemed acceptable when the sample count is approximately 64.

*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.
|number of samples| 1 | 4 | 16 | 64 | 128|
|:--:|:--:|:--:|:--:|:--:|:--:|
|original|![o1](md_img/o1samp.png)|![o4](md_img/o4samp.png)|![o16](md_img/o16samp.png)|![o64](md_img/o64samp.png)|![o128](md_img/o128samp.png)|
|denoised|![d1](md_img/d1samp.png)|![d4](md_img/d4samp.png)|![d16](md_img/d16samp.png)|![d64](md_img/d64samp.png)|![d128](md_img/d128samp.png)|

Filter
===
* The images below illustrate the storage of g-buffers. As evident in the "1 sample" row, artifacts are present in the storage of normals and positions due to ray jittering for anti-aliasing. To mitigate this, I employ interpolation, combining the output of the previous g-buffer with the current frame's intersection results in my application.

|filter| normal | position | A-trous without weighting |
|:--:|:--:|:--:|:--:|
|1 sample|![n](md_img/norm1samp.png)|![p](md_img/pos1samp.png)|![b](md_img/blur1samp.png)|
|100 sample|![n](md_img/norm.png)|![p](md_img/pos.png)|![b](md_img/blur.png)|


Analysis
===
## Resolution
* Based on the table, it's evident that rendering time increases as the resolution is raised. However, the time dedicated to denoising remains relatively consistent across varying resolutions.

|resolution|400x400|600*600|800x800|
|:---:|:---:|:---:|:---:|
|origin render time(ms)| 5.43| 8.93 |16.28 |
|denoise render time(ms)| 6.15| 10.41| 16.85|

## Filter size
* As anticipated, the render time increases when the filter size is enlarged, as the denoiser has to process more iterations to generate the final result. It's worth noting that neither excessively large nor excessively small filter sizes tend to yield satisfactory results.

|filter size|1|2|3|4|5|
|:---:|:---:|:---:|:---:|:---:|:---:|
|render time(ms)|16.18 | 16.46| 18.18| 19.97| 21.77|
|result| ![f1](md_img/filter1.png)|![f2](md_img/filter2.png) |![f3](md_img/filter3.png) |![f4](md_img/filter4.png) |![f5](md_img/filter5.png) |

## Material
* Utilizing image color as a filter input can sometimes lead to excessive blurring of the result. Inspired by [HummaWhite](https://github.com/HummaWhite), I opted to employ the light incident on the surface, rather than the output color, as the filter input. This approach allowed me to apply the texture after denoising, resulting in a significantly improved outcome.

|origin|origin denoise|apply texture after denoise|
|:---:|:---:|:---:|
|![o](md_img/o100samp.png)|![od](md_img/col100samp.png)|![c4](md_img/tex100samp.png)|

## Scene
* The intensity of the lighting can indeed impact the denoiser's output. In the case of the cornelbox scene featuring a large ceiling light, we observed that just 4 samples were sufficient to produce a high-quality result. This result matched or even exceeded the quality of the output from the standard cornelbox scene with 8 samples.

|normal (4 samples)| normal (8 samples)| ceiling light (4 samples)|
|:---:|:---:|:---:|
|![c4](md_img/c4samp.png)|![c8](md_img/c8samp.png)|![cl4](md_img/cl4samp.png)|

Third Party
============
### Code
* [tinyobjloader](https://github.com/tinyobjloader/tinyobjloader)
* [imgui](https://github.com/ocornut/imgui)
* [stb_image](https://github.com/nothings/stb/blob/master/stb_image.h)
### Assets
* [planet](https://www.turbosquid.com/3d-models/3d-stylized-planet-system-4k-free-1973128)
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
Loading