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 3: Alexander Chan #9

Open
wants to merge 4 commits into
base: master
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -558,3 +558,5 @@ xcuserdata
*.xccheckout
*.moved-aside
*.xcuserstate

build-8.0/
Expand Down
83 changes: 78 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,86 @@
![445000 spp, 11 hours](img/joseph_suzie_445000.png)

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)
* Alexander Chan
* Tested on: Windows 10 Version 1803, i7-5820k @ 3.70 GHz 16GB, GTX 1080 @ 1620 MHz 8GB (Personal Computer)

Click on the images for full resolution.

## Summary
A physically based pathtracer written in CUDA. Supports the following:
* Diffuse and perfectly specular reflective materials
* Refractive materials with controllable dispersion
* .obj loading for meshes
* Scene kd-tree with SAH for acceleration
* Texture mapping
* Normal mapping
* Antialiasing
* Stream compaction for early terminating rays

## Features

#### Refraction with Fresnel
Refractive materials are with Fresnel. The proportion of reflected and refracted light is computed using the actual Fresnel equations. A random number from 0 to 1 is generated, and if it is less than the proportion of reflected light, the ray is scattered via specular reflection, otherwise it is scattered via refraction. See the [textures](#textures) section as well as the [final](#more-renders) section for renders.

#### Dispersion
In real life, light of different wavelengths are refracted by different amounts. A classic example is a prism, where white light is split up into a rainbow, because the longer wavelengths of light (red) are bent less than shorter wavelengths of light (blue). Here's the same scene rendered with and without dispersion. All the materials used are colorless, and all the color comes from dispersion.

| Dispersion = 0 | Dispersion = 0.44 |
|---------------|------------------|
|![](img/nodisp.png) | ![](img/disp.png)|

The banner image at the top was rendered with 45000 samples and took 12 hours. The two images above are at 7500 samples and took approximately 2 hours each.

Here's a comparison of different dispersion coefficients. Each of these renders are at 6000 samples and rendered in approximately one hour.

| Dispersion = 0 | Dispersion = 0.1 |
|:-:|:-:|
|![](img/specular_refraction_dragon_disp0.png)|![](img/specular_refraction_dragon_disp.1.png)|
| **Dispersion = 0.5** | **Dispersion = 1** |
|![](img/specular_refraction_dragon_disp.5.png)|![](img/specular_refraction_dragon_disp1.png)|

Colored refractive materials can also be dispersive. Here's a comparison of clear dispersive and non dispersive dragons as well as yellow dispersive and non dispersive dragons.

|![](img/specular_refraction_dragon_disp0.png)|![](img/specular_refraction_dragon_disp.5.png)|
|:-:|:-:|
|![](img/specular_refraction_dragon_yellow_disp0.png)|![](img/specular_refraction_dragon_yellow_disp.5.png)|

Dispersion does not cause each iteration to take more time, but rendering with a high dispersion may take more iterations to reach the same level of convergence.

#### Meshes
Mesh rendering is implemented using a triangle geometry. When a mesh is loaded via tinyobj, its vertex positions, normals, and uv coordinates are assembled into Geoms. Because of the large number of triangles that even simple meshes may have, rendering a scene containing a mesh without the use of an acceleration structure is incredibly slow.

#### Acceleration structure
To render large amounts of geometry, like those present in meshes, a kd-tree is used to accelerate ray intersection testing. After the scene is loaded, a kd-tree is built on the CPU, using either the split method by median of longest axis, or the surface area heuristic. Performance comparison for these two heuristics follow. The kd-tree is flattened on the CPU, then copied to the GPU. Traversal on the GPU uses a stack. As kd-tree nodes in the flattened tree can contain variable amounts of geometry, each node contains an index into a geometry array. This geometry array is sorted so that all the primitives in the same node are contiguous in memory. Much of the implementation is based on PBRT and previous code written for a raytracer and a CPU pathtracer.

![](img/kdtree-performance.png)

The surface area heuristic is about 32 times faster on a 5000 primitive scene (Stanford bunny). On a 100k primitive scene (Stanford dragon), the SAH method was a little more than twice as slow as the 5000 prim scene, and the median split method didn't even finish one iteration (rendering with no acceleration structure wasn't tested, as one iteration never finished even for the 5000 primitive scene). Having some acceleration structure is better than none, but having a good split heuristic while constructing the tree makes a big difference.

#### Textures
Diffuse textures and normal maps are supported using the `TEX` and `NOR` attributes when defining materials. As textures are loaded, their data is added onto a flat array containing every texture. Each material stores an offset to the array to where its texture starts, along with the texture width to correctly compute the location in the array of a given pixel. Both normal maps and diffuse textures are stored in the same array. UV mapping is implemented for cubes, spheres, and meshes.

|![](img/textures.png)|![](img/textures-alt.png)|
|---------------|------------------|
|![](img/normal.png)|![](img/mesh_texture.png)|


#### Antialiasing
First rays emitted from the camera are uniformly jittered within each pixel so that each first bounce is not the same.

### (TODO: Your README)
## More renders
Finally, here are more renders to show correctness. Note that I turned up the emittance of the light to 8 from 5, so these may look brighter than reference renders.

*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.
|![](img/diffuse_blue_dragon.png)|![](img/specular_reflection_dragon.png)|
|---------------|------------------|
|![](img/specular_refraction_dragon_disp0.png)|![](img/specular_refraction_dragon_blue.png)|
|![](img/vanilla_1.png)|![](img/vanilla_specular.png)|

## References
* tinyobj loader
* PBRT v3
* Emily Vo (Dispersion)
Binary file added img/diffuse_blue_dragon.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/disp.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/joseph_suzie_445000.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/kdtree-performance.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/mesh_texture.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/nodisp.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/normal.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/specular_reflection.15000.5min.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/specular_reflection_dragon.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/specular_refraction_dragon_blue.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/specular_refraction_dragon_disp.1.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/specular_refraction_dragon_disp.5.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/specular_refraction_dragon_disp0.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/specular_refraction_dragon_disp1.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/specular_refraction_dragon_yellow_disp.5.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/specular_refraction_dragon_yellow_disp0.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/textures-alt.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/textures.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/vanilla_1.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/vanilla_specular.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
179 changes: 179 additions & 0 deletions scenes/2tex-test.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
// Emissive material (light)
MATERIAL 0
RGB 1 1 1
SPECEX 0
SPECRGB 0 0 0
REFL 0
REFR 0
REFRIOR 0
DISP 0
EMITTANCE 8
TEX NONE
NOR NONE

// Diffuse white
MATERIAL 1
RGB .98 .98 .98
SPECEX 0
SPECRGB 0 0 0
REFL 0
REFR 0
REFRIOR 0
DISP 0
EMITTANCE 0
TEX NONE
NOR NONE

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

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

// Specular white
MATERIAL 4
RGB .98 .98 .98
SPECEX 0
SPECRGB .98 .98 .98
REFL 1
REFR 1
REFRIOR 1.3
DISP 0
EMITTANCE 0
TEX NONE
NOR NONE

// Diffraction
MATERIAL 5
RGB .98 .98 .98
SPECEX 0
SPECRGB .98 .98 .98
REFL 1
REFR 1
REFRIOR 1.3
DISP 0
EMITTANCE 0
TEX NONE
NOR NONE

// Checkerboard
MATERIAL 6
RGB .98 .98 .98
SPECEX 0
SPECRGB .98 .98 .98
REFL 0
REFR 0
REFRIOR 0
DISP 0
EMITTANCE 0
TEX ../scenes/textures/checkerboard.png
NOR NONE

// Grid
MATERIAL 7
RGB .98 .98 .98
SPECEX 0
SPECRGB .98 .98 .98
REFL 0
REFR 0
REFRIOR 0
DISP 0
EMITTANCE 0
TEX ../scenes/textures/grid.jpg
NOR NONE

// Camera
CAMERA
RES 800 800
FOVY 45
ITERATIONS 50000
DEPTH 8
FILE cornell
EYE 0.0 5 10.5
LOOKAT 0 5 0
UP 0 1 0


// Ceiling light
OBJECT 0
cube
material 0
TRANS 0 10 0
ROTAT 0 0 0
SCALE 3 .3 3

// Floor
OBJECT 1
cube
material 6
TRANS 0 0 0
ROTAT 0 0 0
SCALE 10 .01 10

// Ceiling
OBJECT 2
cube
material 1
TRANS 0 10 0
ROTAT 0 0 90
SCALE .01 10 10

// Back wall
OBJECT 3
cube
material 7
TRANS 0 5 -5
ROTAT 0 90 0
SCALE .01 10 10

// Left wall
OBJECT 4
cube
material 2
TRANS -5 5 0
ROTAT 0 0 0
SCALE .01 10 10

// Right wall
OBJECT 5
cube
material 3
TRANS 5 5 0
ROTAT 0 0 0
SCALE .01 10 10

// Sphere
OBJECT 6
sphere
material 5
TRANS 0 4 1
ROTAT 0 0 0
SCALE 4 4 4

// TEST MESH
OBJECT 7
sphere
material 6
TRANS 1 4 -2
ROTAT 0 0 0
SCALE 2 2 2
Loading