Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
1b453f6
+ Base naive pathtracing implementation with antialiasing and Gaussia…
mmerchante Sep 30, 2017
13c6991
+ Device texture management and sampling
mmerchante Oct 1, 2017
a454877
+ More texture management
mmerchante Oct 2, 2017
eb3aa22
+ Normal mapping
mmerchante Oct 2, 2017
b485393
+ Filmic tonemapping with vignetting
mmerchante Oct 2, 2017
7405dd5
* Refactoring, perfect dielectric material
mmerchante Oct 2, 2017
2e87cd0
+ Simple thin walled translucence
mmerchante Oct 2, 2017
6167771
+ Mesh support, no acceleration yet.
mmerchante Oct 2, 2017
bad29fd
+ Mesh with kd-tree
mmerchante Oct 2, 2017
d88d506
* ignores
mmerchante Oct 2, 2017
ddb3e96
+ Meshes
mmerchante Oct 2, 2017
ae2c46a
+ Proper mesh instancing
mmerchante Oct 2, 2017
87847e3
+ Origami scene
mmerchante Oct 2, 2017
3c54e98
+ Raw images
mmerchante Oct 2, 2017
55319ef
+ Gif
mmerchante Oct 2, 2017
5d44bc9
Update README.md
mmerchante Oct 3, 2017
d19c2ad
* Images
mmerchante Oct 3, 2017
28e7bc3
Merge branch 'master' of https://github.com/mmerchante/Project3-CUDA-…
mmerchante Oct 3, 2017
4f5d409
Update README.md
mmerchante Oct 3, 2017
bc1119a
Update README.md
mmerchante Oct 3, 2017
29c51cc
+ Images
mmerchante Oct 3, 2017
b5eb399
+ Images
mmerchante Oct 3, 2017
21f93f0
Update README.md
mmerchante Oct 3, 2017
49f6225
Update README.md
mmerchante Oct 3, 2017
9d97512
+ Images
mmerchante Oct 3, 2017
824cfee
Merge branch 'master' of https://github.com/mmerchante/Project3-CUDA-…
mmerchante Oct 3, 2017
b38dc4f
Update README.md
mmerchante Oct 3, 2017
4aae337
Update README.md
mmerchante Oct 3, 2017
693a597
+ Images
mmerchante Oct 3, 2017
bf15a79
+ Images
mmerchante Oct 3, 2017
c1413d9
Update README.md
mmerchante Oct 3, 2017
401d2b1
Update README.md
mmerchante Oct 3, 2017
0e6b48d
Update README.md
mmerchante Oct 3, 2017
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
5 changes: 2 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ build
.LSOverride

# Icon must end with two \r
Icon
Icon


# Thumbnails
._*
Expand Down Expand Up @@ -189,7 +190,6 @@ install_manifest.txt
*.slo
*.lo
*.o
*.obj

# Precompiled Headers
*.gch
Expand Down Expand Up @@ -276,7 +276,6 @@ artifacts/
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
Expand Down
113 changes: 107 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,114 @@
![](img/origami.2000spp.1589.5s.png)

2000 spp, 26 minutes


CUDA Path Tracer
================

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

* Mariano Merchante
* Tested on
* Microsoft Windows 10 Pro
* Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz, 2601 Mhz, 4 Core(s), 8 Logical Processor(s)
* 32.0 GB RAM
* NVIDIA GeForce GTX 1070 (mobile version)

![](img/dragon.2000spp.205.302s.png)

2000 spp, 3.3 minutes.

## Details
This project implements a physically based pathtracer through the use of CUDA and GPU hardware. It has basic material and scene handling and supports meshes while keeping an interactive framerate. The main features are:

* Brute force path tracing
* Diffuse, perfectly specular reflective and transmissive materials
* An approximated translucence brdf for thin walled materials such as paper
* Filmic tonemapping with user editable vignetting
* Depth of Field with arbitrary aperture shape
* Texture mapping and one procedural texture
* Normal mapping
* Mesh loading with an accelerated kd-tree structure that runs in GPU
* Antialiasing
* Gaussian filtering of path samples

![](img/buddha.2000spp.336.25s.png)

2000 spp, 6 minutes.

## Feature description and analysis

### Core path tracer
The brute force algorithm uses a sequence of compute kernels that intersect and accumulate samples from the scene. After each iteration, it compacts and discards paths that either don't intersect anything or don't contribute to light transport. However, it is a naive path tracing algorithm, as it doesn't use direct lighting nor any multiple importance scheme, given that I felt that they were secondary to the excercise of designing a robust renderer in GPU. I will probably implement this in the future.

### Multiple BxDFs
Apart from the common materials, the purely diffuse material supports a translucence attribute that lets the material transmit light through thin walled geometry, such as triangles. You can see an example in the following figure.

![](img/translucent.png)

Notice how the paper is translucent on the back of the origami piece.

All materials both sample a direction and evaluate the brdf function, returning a pdf for the Monte Carlo simulation. Note that the kernel is an uber shader and decides which sampling function to call depending on material type.

Wavefront rendering should vastly improve the shading step, reducing divergence and decoupling code better.

### Mesh acceleration structure
Meshes are implemented and accelerated with the use of a flattened, stack based kd-tree that is constructed in CPU and then uploaded to the GPU. It's implementation is very similar to PBRT's v3 approach, with the main difference being that triangle data is flattened and placed close to the nodes, so that there are absolutely no indirections while traversing the tree. This improved performance drastically; for example, a 30k teapot took approximately 10 minutes to do 230 samples per pixel without acceleration, and when enabling the kd-tree, the renderer can do 1000 samples in merely 2 minutes for a 100k dragon, for example. More analysis is required, and I want to experiment with different ways to structure the tree nodes.

However, I didn't implement an acceleration structure for the scene, and this is very noticeable on the origami scene. The meshes are very low poly and a 2000spp render takes around half an hour, while a 100k Stanford dragon render takes ~3 minutes. Due to the design of my implementation, it should be straightforward to adapt it for arbitrary geometry.

### Antialiasing
The camera samples are randomly selected inside the pixel's area with a uniform distribution. In the future, a precomputed cache of stratified, multi-jittered samples would be ideal to reduce variance.

### Depth of Field
Depending on both the camera aperture and focal distance, camera rays are perturbed inside a [0,1] square, scaled and centered by the aperture radius. An aperture shape texture is also needed, which defines the contribution of each sample and generates different effects. Because the texture is also colored, things like chromatic aberration can be easily approximated.

![](img/dof.png)

Samples that fall outside the shape simply don't contribute, making this approach rather inefficient. An improvement of this algorithm would be precomputing a cache of samples that have positive contribution to the depth of field phenomena.

### Sample Filtering
To reduce aliasing artifacts that arise from averaging AA samples inside a pixel, I implemented a Gaussian filter step that gathers samples with a specific radius and averages them smoothly, reducing jaggies that may arise on certain situations. It is also helpful in terms of reducing noise. Compare the aliasing artifacts that appear near the area light shape. This happens even with antialiasing, because of the box blur generated from averaging inside a pixel.

![](img/nofilter.png)

Render without filtering

![](img/filtered.png)

Render with a filtering radius of 2 pixels.

An interesting problem that appeared while designing the filtering step is the need to gather close samples, or using gather-as-you-scatter strategies to prevent having a separate step. In the future, such strategies would improve performance drastically, as the current implementation suffers with big filter radii (although in practice, a radius of 2 is more than enough).

### Filmic tonemapping
After the filtering step is done, there's one last pass that normalizes the filter samples, does gamma correction, adds vignetting and modifies the result colors to have a more filmic aesthetic. The specific implementation is based on John Hable's tonemapping operator for Uncharted, which can be seen here: http://filmicworlds.com/blog/filmic-tonemapping-operators/

Because the tonemapping pass does gamma correction, all textures and color input is transformed into linear space before the rendering starts.

![](img/tonemapping.png)

Notice how the dark colors are crushed and the highlights are emphasized, and the borders are obscured. The vignetting function is completely custom and is not based on any physical property apart from aesthetic.

A straightforward optimization of the current implementation would be adding LUT textures to reduce the amount of arithmetic operations done on this kernel.

### Textures

Texture mapping, normal mapping and a procedural mandelbrot texture are supported. A flat array of textures is uploaded to the GPU, and materials have a texture descriptor with texture offset, width&height, repeat factor, etc. In the future I plan to implement bilinear filtering and possibly some mip-mapping strategy to improve memory access.

![](img/textures.png)


* (TODO) YOUR NAME HERE
* Tested on: (TODO) Windows 22, i7-2222 @ 2.22GHz 22GB, GTX 222 222MB (Moore 2222 Lab)
![](img/mandelbrot.png)

### (TODO: Your README)
## Conclusion and future work
This small project is but an excercise in physically based rendering in a GPU with interactive framerates, and it is very much incomplete. A non exhaustive list of improvements would be:

*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.
* Sample cache with offset rotation to prevent correlation
* Multiple importance sampling strategies for reducing variance
* Cook Torrance BRDF with GGX distribution
* Kd-tree construction in the GPU
* Scene kd-tree (should be very straightforward)
* Denoising filters to reduce variance by using sample information such as normal, material type, etc.
* Temporal reprojection for reusing data when the camera moves

Binary file added img/buddha.2000spp.336.25s.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/dof.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/dragon.2000spp.205.302s.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/filtered.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/mandelbrot.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/nofilter.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/origami.2000spp.1589.5s.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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/raw/eurydice.gif
Binary file added img/textures.png
Binary file added img/tonemapping.png
Binary file added img/translucent.png
177 changes: 177 additions & 0 deletions scenes/buddha.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
// 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 .9 .75 .45
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
TEX_DIFFUSE ../scenes/resources/textures/checker_g.png

// Floor Reflective
MATERIAL 3
RGB .9 .9 .9
SPECEX 0
SPECRGB .75 .75 .75
REFL 1
REFR 0
REFRIOR 0
EMITTANCE 0

// Origami Material 1
MATERIAL 4
RGB .65 .25 .8
SPECEX 0
SPECRGB .98 .98 .98
REFL 1
REFR 0
REFRIOR 0
EMITTANCE 0

// Origami ORANGE
MATERIAL 5
RGB .9 .6 .2
SPECEX 0
SPECRGB .98 .98 .98
REFL 0
REFR 0
REFRIOR 0
EMITTANCE 0
TRANSLUCENCE 1.0

// Emissive Alternative
MATERIAL 6
RGB .85 .7 .25
SPECEX 0
SPECRGB .98 .98 .98
REFL 0
REFR 0
REFRIOR 0
EMITTANCE 8

// Origami LIME
MATERIAL 7
RGB .775 .85 .1
SPECEX 0
SPECRGB 0 0 0
REFL 0
REFR 0
REFRIOR 0
EMITTANCE 0
TRANSLUCENCE 1.0

// Origami BLUE
MATERIAL 8
RGB .25 .75 .85
SPECEX 0
SPECRGB .9 .95 1.15
REFL 1
REFR 1
REFRIOR 1.33
EMITTANCE 0

// Origami RED
MATERIAL 9
RGB .9 .3 .15
SPECEX 0
SPECRGB .98 .98 .98
REFL 0
REFR 0
REFRIOR 0
EMITTANCE 0
TRANSLUCENCE 1.0

// Back light
MATERIAL 10
RGB 1 1 1
SPECEX 0
SPECRGB 0 0 0
REFL 0
REFR 0
REFRIOR 0
EMITTANCE 8

// Film
FILM
GAMMA 2.2
FILTER_RADIUS 2.15
FILTER_ALPHA 3.0
VIGNETTE_START 0.35
VIGNETTE_END 1.0

// Camera
CAMERA
RES 1440 612
FOVY 15
ITERATIONS 2000
DEPTH 10
FILE buddha
APERTURE .5
DISTANCE 14.5
BOKEH ../scenes/resources/bokeh/star_alt.png
EYE 0 0 14.5
LOOKAT 0 3 -2
UP 0 1 0

// Ceiling light
OBJECT 0
cube
material 10
TRANS 0 15 -5
ROTAT -35 0 0
SCALE 15 .3 5

// Left wall
OBJECT 1
cube
material 0
TRANS -45 10 0
ROTAT 0 0 0
SCALE .01 20 20

// Right wall
OBJECT 2
cube
material 6
TRANS 45 10 0
ROTAT 0 0 0
SCALE .01 20 20

// Mesh
OBJECT 3
mesh
FILE ../scenes/resources/meshes/buddha.obj
material 4
TRANS 0 0 0
ROTAT 0 179.5 0
SCALE 6 6 6

// FLOOR
OBJECT 4
mesh
FILE ../scenes/resources/meshes/floor.obj
material 1
TRANS 0 0 0
ROTAT 0 0 0
SCALE 7 3 3
19 changes: 15 additions & 4 deletions scenes/cornell.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ REFL 0
REFR 0
REFRIOR 0
EMITTANCE 0
TEX_DIFFUSE MANDELBROT

// Diffuse green
MATERIAL 3
Expand All @@ -37,6 +38,7 @@ REFL 0
REFR 0
REFRIOR 0
EMITTANCE 0
TEX_DIFFUSE ../scenes/resources/textures/checker_g.png

// Specular white
MATERIAL 4
Expand All @@ -47,19 +49,28 @@ REFL 1
REFR 0
REFRIOR 0
EMITTANCE 0
TEX_SPECULAR ../scenes/resources/textures/checker_g.png

// Film
FILM
GAMMA 2.2
FILTER_RADIUS 1.5
FILTER_ALPHA 4.0

// Camera
CAMERA
RES 800 800
FOVY 45
ITERATIONS 5000
ITERATIONS 1000
DEPTH 8
FILE cornell
EYE 0.0 5 10.5
LOOKAT 0 5 0
APERTURE 0.25
DISTANCE 4.0
BOKEH ../scenes/resources/bokeh/chromatic.png
EYE 2.5 7.3 10.5
LOOKAT -1 5 0
UP 0 1 0


// Ceiling light
OBJECT 0
cube
Expand Down
Loading