Skip to content

Project3: Licheng Cao #6

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

Open
wants to merge 26 commits into
base: main
Choose a base branch
from
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
85 changes: 31 additions & 54 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,60 +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
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
)

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

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
)

list(SORT headers)
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})

# 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" ] } }
}
]
}
94 changes: 89 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,95 @@ CUDA Path Tracer

**University of Pennsylvania, CIS 565: GPU Programming and Architecture, Project 3**

* (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
==============
<p align="center">
<img src="img/cornell.2023-10-07_01-28-25z.5000samp.png"/>
</p>

Features
============
### Textures

* [texture.cuh](https://github.com/LichengCAO/Project3-CUDA-Path-Tracer/blob/main/src/texture.cuh) and [texture.cu](https://github.com/LichengCAO/Project3-CUDA-Path-Tracer/blob/main/src/texture.cu) are used to handle textures with CUDA. I applied bump mapping and texture mapping to help me render meshes. And other textures like roughness maps can also be loaded to help render meshes as long as the shading parts supports that material attribute.

|bump map| base map | result|
|:-----:|:-----:|:-----:|
|![cornell 2023-10-07_19-59-50z 15000samp](https://github.com/LichengCAO/Project3-CUDA-Path-Tracer/assets/81556019/d0817e69-5939-4977-9019-f7b15b9bb4a9)|![cornell 2023-10-07_19-57-15z 15000samp](https://github.com/LichengCAO/Project3-CUDA-Path-Tracer/assets/81556019/eeebc17e-e80a-442e-bb39-6d786f454d12)|![cornell 2023-10-07_20-01-36z 15000samp](https://github.com/LichengCAO/Project3-CUDA-Path-Tracer/assets/81556019/1d9c0b60-5853-43e0-9b01-51a4ad7d1404)|


### Depth of field
* To achieve depth of field (DOF) effects, I referred to [PBRT 6.2.3](https://www.pbr-book.org/3ed-2018/Camera_Models/Projective_Camera_Models#TheThinLensModelandDepthofField) and successfully implemented the thin lens model. This implementation significantly contributes to generating high-quality output images for the ray tracer.

|without DOF| with DOF |
|:-----:|:-----:|
|![cornell 2023-10-07_21-03-23z 5000samp](https://github.com/LichengCAO/Project3-CUDA-Path-Tracer/assets/81556019/8f99d738-7b82-436d-b432-8619ac922788)|![cornell 2023-10-07_21-05-11z 5000samp](https://github.com/LichengCAO/Project3-CUDA-Path-Tracer/assets/81556019/eb988061-bf35-40c6-ac31-df668a1022e8)|


### .obj loading and BVH tree
* I employed the tinyobjloader library to efficiently load meshes into the scene. Additionally, I implemented a Bounding Volume Hierarchy (BVH) to optimize ray-mesh intersection tests, thereby enhancing the rendering performance.
* The BVH tree is built on CPU based on [PBRT 4.3.1](https://www.pbr-book.org/3ed-2018/Primitives_and_Intersection_Acceleration/Bounding_Volume_Hierarchies).
* During each iteration of ray bouncing, the ray undergoes a series of tests. Initially, it checks for intersections with the bounding boxes in the scene. If an intersection with a bounding box occurs, the ray proceeds to check for intersections with the child nodes of that bounding box. This process continues until the ray finds the nearest intersection with a triangle in the scene, ensuring accurate rendering of the scene's geometry.
* I utilized a stack data structure to help me implement the ray's behavior in an iterative way since GPUs don't have good support for recusive bahaviors.
* To expedite the intersection process, I introduced two crucial optimizations. First, I implemented an early termination mechanism by checking if we already have a hit point closer than the one present within the current bounding box. If such a hit point exists, we skip further examination of the current bounding box. Second, I strategically determined the order in which to test the children of a bounding box based on the parent node's split axis. This allows us to prioritize testing the child that is closer to the current ray's position, increasing the likelihood of early termination and further improving the ray tracing efficiency.
* These optimizations have significantly improved the frames per second (FPS), making the rendering process much more efficient:
<p align="center">
<img src="https://github.com/LichengCAO/Project3-CUDA-Path-Tracer/assets/81556019/baaccda6-32e1-439e-9a94-09f9f3b51324"/>
</p>

|Naive|BVH|
|:-----:|:-----:|
|![fpsNA](https://github.com/LichengCAO/Project3-CUDA-Path-Tracer/assets/81556019/0eae0a65-57ee-43ff-b9b1-69bb1cf18256)|![fps](https://github.com/LichengCAO/Project3-CUDA-Path-Tracer/assets/81556019/f3d4598b-c799-4bfe-b9da-65766349e6bd)|


### Cache first frame
* Cache first frame feature is implemented to improve fps. And the test result is shown as follow:
<p align="center">
<img src="https://github.com/LichengCAO/Project3-CUDA-Path-Tracer/assets/81556019/9a7a6978-edc5-4db1-9e07-a57a53a8d4fd"/>
</p>

* The result shows that caching first frame will slightly improve fps, especially with lower ray bounce. However, it will also introduce some artifacts if the ray is jittered by some random number for anti-aliasing as shown:

|no cache|cache first frame|
|:-----:|:-----:|
|![cornell 2023-10-07_21-03-23z 5000samp](https://github.com/LichengCAO/Project3-CUDA-Path-Tracer/assets/81556019/8f99d738-7b82-436d-b432-8619ac922788)|![cornell 2023-10-07_21-23-59z 5000samp](https://github.com/LichengCAO/Project3-CUDA-Path-Tracer/assets/81556019/a25107d3-ce6b-4b7e-b5c6-304717ac1017)|


### Reflection and Refraction
* Implementing basic reflection in ray tracing is quite straightforward. However, it's crucial to handle the Lambertian reflection model carefully.
* For the refraction, I referred [here](https://zhuanlan.zhihu.com/p/303168568) for the Schlick's approximation and the accurate fresnel evaluation and use [glm::refract](https://registry.khronos.org/OpenGL-Refpages/gl4/html/refract.xhtml) to calculate the ray direction.

|reflection| refraction |
|:-----:|:-----:|
|![sphere 2023-10-07_21-19-10z 5000samp](https://github.com/LichengCAO/Project3-CUDA-Path-Tracer/assets/81556019/a55be12d-3cea-4f83-bb7a-cd054beae718)|![refract](img/sphere.2023-10-06_22-33-00z.5000samp.png) |

### Stream compaction
* Path continuation/termination
* I used thrust::copy_if and thrust::remove_if to remove paths that hit light or nothing and record them in a output array, so that the path tracer will have less path to check after each bounce and early terminations, which results in a higher fps:

|no compaction| compaction |
|:-----:|:-----:|
|![n捕获](https://github.com/LichengCAO/Project3-CUDA-Path-Tracer/assets/81556019/bf22d5ad-94c0-431c-9d0d-a5053177a30a)|![捕获](https://github.com/LichengCAO/Project3-CUDA-Path-Tracer/assets/81556019/934e70ff-5ad1-4d02-ba06-48afe956e39d)|

* Sort materials
* I tried to sort the paths based on the material of intersections with thrust::sort_by_key, but it actually resulted in a lower fps. The reason may be that the cost of sorting overweighed the performance improvement it brings to my path tracer.

|without sort| sorted |
|:-----:|:-----:|
|![捕获](https://github.com/LichengCAO/Project3-CUDA-Path-Tracer/assets/81556019/9fc79cc6-0270-45b1-867d-52317eae8bd9)|![n捕获](https://github.com/LichengCAO/Project3-CUDA-Path-Tracer/assets/81556019/575bc562-5fe9-4cdb-9f5e-cc5ef392c732)|

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
* [bunny](https://github.com/harzival/stanford_bunny_obj_mtl_jpg/blob/master/bunny.obj)
* [planet](https://www.turbosquid.com/3d-models/3d-stylized-planet-system-4k-free-1973128)

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

Binary file added img/cornell.2023-09-25_00-34-37z.5000samp.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/cornell.2023-09-26_01-36-01z.659samp.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/cornell.2023-09-26_01-41-44z.5000samp.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/cornell.2023-09-29_04-17-59z.796samp.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/cornell.2023-09-30_17-36-08z.132samp.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/cornell.2023-10-06_22-46-04z.5000samp.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/cornell.2023-10-07_01-28-25z.5000samp.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/cornell.2023-10-07_01-44-35z.5000samp.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/sphere.2023-10-02_20-13-58z.5000samp.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/sphere.2023-10-05_23-45-30z.5000samp.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/sphere.2023-10-06_19-25-13z.5000samp.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/sphere.2023-10-06_19-28-38z.5000samp.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/sphere.2023-10-06_22-33-00z.5000samp.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions objs/plane.mtl
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
newmtl initialShadingGroup
illum 4
Kd 0.50 0.50 0.50
Ka 0.00 0.00 0.00
Tf 1.00 1.00 1.00
Ni 1.00
41 changes: 41 additions & 0 deletions scenes/brick.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
TEXTURE 0
154.JPG

TEXTURE 1
154_norm.JPG

BACKGROUND
Footprint_Court_2k.hdr

// Diffuse white
MATERIAL 0
bump 1
RGB .98 .98 .98
SPECEX 0
SPECRGB 0 0 0
REFL 0
REFR 0
REFRIOR 0
EMITTANCE 0

// Camera
CAMERA
RES 800 800
FOVY 45
ITERATIONS 5000
DEPTH 8
FILE cornell
EYE 0.0 2.5 -5
LOOKAT 0 0 0
UP 0 1 0


// Floor
MESH 0
cube.obj
material 0
TRANS 0 0 0
ROTAT 0 0 0
SCALE 1 1 1


118 changes: 118 additions & 0 deletions scenes/cow.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
// Emissive material (light)
MATERIAL 0
RGB 1 1 1
SPECEX 0
SPECRGB 0 0 0
REFL 0
REFR 0
REFRIOR 0
EMITTANCE 5

// Diffuse white
MATERIAL 1
RGB .98 .98 .98
SPECEX 0
SPECRGB 0 0 0
REFL 0
REFR 0
REFRIOR 0
EMITTANCE 0

// Diffuse red
MATERIAL 2
RGB .85 .35 .35
SPECEX 0
SPECRGB 0 0 0
REFL 0
REFR 0
REFRIOR 0
EMITTANCE 0

// Diffuse green
MATERIAL 3
RGB .35 .85 .35
SPECEX 0
SPECRGB 0 0 0
REFL 0
REFR 0
REFRIOR 0
EMITTANCE 0

// Specular white
MATERIAL 4
RGB .98 .98 .98
SPECEX 0
SPECRGB .98 .98 .98
REFL 1
REFR 0
REFRIOR 0
EMITTANCE 0

// Camera
CAMERA
RES 800 800
FOVY 45
ITERATIONS 5000
DEPTH 8
FILE cornell
EYE 0.0 2.5 -5
LOOKAT 0 2.5 0
UP 0 1 0


// Floor
MESH 0
plane.obj
material 1
TRANS 0 -2.5 0
ROTAT -90 0 0
SCALE 10 10 1

// Red wall
MESH 1
plane.obj
material 2
TRANS 5 2.5 0
ROTAT 0 -90 0
SCALE 10 10 1

// Green wall
MESH 2
plane.obj
material 3
TRANS -5 2.5 0
ROTAT 0 90 0
SCALE 10 10 1

// Back wall
MESH 3
plane.obj
material 1
TRANS 0 2.5 5
ROTAT 0 180 0
SCALE 10 10 1

// Ceiling wall
MESH 4
plane.obj
material 1
TRANS 0 7.5 0
ROTAT 90 0 0
SCALE 10 10 1

// Short cube
MESH 5
cow.obj
material 1
TRANS 0 1 0.75
ROTAT 0 30 0
SCALE 0.6 0.6 0.6

// Ceiling light
MESH 6
plane.obj
material 0
TRANS 0 7.45 0
ROTAT 90 0 0
SCALE 3 3 1

Loading