diff --git a/.gitignore b/.gitignore
index 89942d9..a6e3629 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,7 @@
*.vcxproj
*.xcodeproj
build
+build2015
# Created by https://www.gitignore.io/api/linux,osx,sublimetext,windows,jetbrains,vim,emacs,cmake,c++,cuda,visualstudio,webstorm,eclipse,xcode
diff --git a/README.md b/README.md
index 110697c..70b2185 100644
--- a/README.md
+++ b/README.md
@@ -1,13 +1,112 @@
-CUDA Path Tracer
-================
+CUDA Path tracer
+======================
-**University of Pennsylvania, CIS 565: GPU Programming and Architecture, Project 3**
+**University of Pennsylvania, CIS 565: GPU Programming and Architecture, Project 2**
-* (TODO) YOUR NAME HERE
-* Tested on: (TODO) Windows 22, i7-2222 @ 2.22GHz 22GB, GTX 222 222MB (Moore 2222 Lab)
+* Akshay Shah
+* Tested on: Windows 10, i7-5700HQ @ 2.70GHz 16GB, GTX 970M 6GB (Personal Computer)
-### (TODO: Your README)
+### GPU Path Tracer
-*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.
+CUDA Summary
+------------
+The below analysis and results have been performed on a scene with the cornell box that has all the material types and two light sources.
+
+
+
+
+
+Most of the time was spent in the main path trace loop to check intersection after a ray was shot. `shadeMaterial` captures the next highest device time due to the computation of refraction and other complex materials types such as the Oren-Nayar microfacet and Blinn Microfacet Model. The `launch_closure_by_value` function is part of thrust's `remove_if` stream compaction. The amount of time that is spent in here(stream compaction) is well received in terms of total time saved.
+
+
+
+The above image indicates the total time spent in each device function with corresponding number of launches. To reduce the total time spent in `shadeMaterial`, separate BRDF function calls could be made to avoid branches inside `shadeMaterial` itself and let class definitions do their job.
+
+Analysis
+--------
+
+
+
+The above image shows a comparison of time taken in the `computeIntersection` function with different techniques
+- No caching first ray bounce
+- Caching first ray bounce
+- Sorting the rays and intersections by material type
+
+The reason for a longer time for sorting could be that, there are not enough materials in the scene (and the scene is also not large enough. Maybe a scene as large as at least 1000 objects) that the rays show a significant change by sorting them by material.
+
+
+
+The above image shows a comparison of time taken with and without stream compaction. There is a significant change when `thrust::remove_if` is used to weed out rays that have finished bouncing in the scene i.e., rays that have `remainingBounces` 0 will be removed from the pool of "threads".
+
+Output
+------
+
+Anti-Aliasing
+-------------
+The following image shows an example of stochastic anti-aliasing that was used in the path tracer to clean out the jaggies.
+
+
+
+REFRACTION
+----------
+
+The refractive indices of the glass spheres are 1.5
+Each of them has also been approximated for glass using Schlick's method.
+
+
+
+DOF (Depth of Field)
+--------------------
+
+
+
+
+
+MATERIALS
+---------
+The following image shows a material comparison between two diffuse materials:
+- Lambertian diffuse
+- Oren-Nayar diffuse
+
+The Oren-Nayar diffuse material in the render below has a roughness value of 20
+
+
+
+MIRROR
+------
+
+
+
+Blinn Microfacet
+----------------
+
+The following render displays the Blinn Microfacet model with an exponent of 10 in this particular example.
+
+
+
+Just things
+-----------
+A render of UFO looking saucers with refractive properties. >.<
+
+
+
+
+
+
+
+##### BLOOPERS
+
+When trying to add Stratified sampling to sample diffuse hemispheres.
+
+
+
+When trying to add Halton sequences to sample diffuse hemispheres.
+
+
+
+
+
+Trying to add refraction
+
+
diff --git a/img/StochasticAA.PNG b/img/StochasticAA.PNG
new file mode 100644
index 0000000..213a470
Binary files /dev/null and b/img/StochasticAA.PNG differ
diff --git a/img/cuda_summary.PNG b/img/cuda_summary.PNG
new file mode 100644
index 0000000..083103b
Binary files /dev/null and b/img/cuda_summary.PNG differ
diff --git a/img/cuda_summary1.PNG b/img/cuda_summary1.PNG
new file mode 100644
index 0000000..a26cdf3
Binary files /dev/null and b/img/cuda_summary1.PNG differ
diff --git a/img/streamcompact.png b/img/streamcompact.png
new file mode 100644
index 0000000..190210b
Binary files /dev/null and b/img/streamcompact.png differ
diff --git a/img/total_time.png b/img/total_time.png
new file mode 100644
index 0000000..cefc410
Binary files /dev/null and b/img/total_time.png differ
diff --git a/renders/cornell.2016-10-04_14-38-00z.1024samp.png b/renders/cornell.2016-10-04_14-38-00z.1024samp.png
new file mode 100644
index 0000000..9a5eabd
Binary files /dev/null and b/renders/cornell.2016-10-04_14-38-00z.1024samp.png differ
diff --git a/renders/cornell.2016-10-04_14-38-00z.512samp.png b/renders/cornell.2016-10-04_14-38-00z.512samp.png
new file mode 100644
index 0000000..37deae8
Binary files /dev/null and b/renders/cornell.2016-10-04_14-38-00z.512samp.png differ
diff --git a/renders/cornell.2016-10-04_14-39-40z.1024samp.png b/renders/cornell.2016-10-04_14-39-40z.1024samp.png
new file mode 100644
index 0000000..5cdb515
Binary files /dev/null and b/renders/cornell.2016-10-04_14-39-40z.1024samp.png differ
diff --git a/renders/cornell.2016-10-04_14-39-40z.512samp.png b/renders/cornell.2016-10-04_14-39-40z.512samp.png
new file mode 100644
index 0000000..79430c4
Binary files /dev/null and b/renders/cornell.2016-10-04_14-39-40z.512samp.png differ
diff --git a/renders/cornell.2016-10-04_14-46-16z.1024samp.png b/renders/cornell.2016-10-04_14-46-16z.1024samp.png
new file mode 100644
index 0000000..c2821c0
Binary files /dev/null and b/renders/cornell.2016-10-04_14-46-16z.1024samp.png differ
diff --git a/renders/cornell.2016-10-04_14-46-16z.1536samp.png b/renders/cornell.2016-10-04_14-46-16z.1536samp.png
new file mode 100644
index 0000000..c7f517a
Binary files /dev/null and b/renders/cornell.2016-10-04_14-46-16z.1536samp.png differ
diff --git a/renders/cornell.2016-10-04_14-46-16z.512samp.png b/renders/cornell.2016-10-04_14-46-16z.512samp.png
new file mode 100644
index 0000000..cda3c0f
Binary files /dev/null and b/renders/cornell.2016-10-04_14-46-16z.512samp.png differ
diff --git a/renders/cornell.2016-10-04_15-40-22z.1samp.png b/renders/cornell.2016-10-04_15-40-22z.1samp.png
new file mode 100644
index 0000000..9436227
Binary files /dev/null and b/renders/cornell.2016-10-04_15-40-22z.1samp.png differ
diff --git a/renders/cornell.2016-10-04_15-40-35z.3samp.png b/renders/cornell.2016-10-04_15-40-35z.3samp.png
new file mode 100644
index 0000000..1b46eff
Binary files /dev/null and b/renders/cornell.2016-10-04_15-40-35z.3samp.png differ
diff --git a/renders/cornell.2016-10-04_18-08-15z.512samp.png b/renders/cornell.2016-10-04_18-08-15z.512samp.png
new file mode 100644
index 0000000..babadcd
Binary files /dev/null and b/renders/cornell.2016-10-04_18-08-15z.512samp.png differ
diff --git a/renders/cornell.2016-10-04_18-08-52z.512samp.png b/renders/cornell.2016-10-04_18-08-52z.512samp.png
new file mode 100644
index 0000000..a407c9d
Binary files /dev/null and b/renders/cornell.2016-10-04_18-08-52z.512samp.png differ
diff --git a/renders/cornell.2016-10-04_18-10-56z.1024samp.png b/renders/cornell.2016-10-04_18-10-56z.1024samp.png
new file mode 100644
index 0000000..e2b8ef7
Binary files /dev/null and b/renders/cornell.2016-10-04_18-10-56z.1024samp.png differ
diff --git a/renders/cornell.2016-10-04_18-10-56z.1536samp.png b/renders/cornell.2016-10-04_18-10-56z.1536samp.png
new file mode 100644
index 0000000..bd3a515
Binary files /dev/null and b/renders/cornell.2016-10-04_18-10-56z.1536samp.png differ
diff --git a/renders/cornell.2016-10-04_18-10-56z.2048samp.png b/renders/cornell.2016-10-04_18-10-56z.2048samp.png
new file mode 100644
index 0000000..4201198
Binary files /dev/null and b/renders/cornell.2016-10-04_18-10-56z.2048samp.png differ
diff --git a/renders/cornell.2016-10-04_18-10-56z.512samp.png b/renders/cornell.2016-10-04_18-10-56z.512samp.png
new file mode 100644
index 0000000..a5a15a0
Binary files /dev/null and b/renders/cornell.2016-10-04_18-10-56z.512samp.png differ
diff --git a/renders/cornell.2016-10-04_18-21-53z.1024samp.png b/renders/cornell.2016-10-04_18-21-53z.1024samp.png
new file mode 100644
index 0000000..31aa064
Binary files /dev/null and b/renders/cornell.2016-10-04_18-21-53z.1024samp.png differ
diff --git a/renders/cornell.2016-10-04_18-21-53z.512samp.png b/renders/cornell.2016-10-04_18-21-53z.512samp.png
new file mode 100644
index 0000000..e6a3ea2
Binary files /dev/null and b/renders/cornell.2016-10-04_18-21-53z.512samp.png differ
diff --git a/renders/cornell.2016-10-04_18-27-24z.512samp.png b/renders/cornell.2016-10-04_18-27-24z.512samp.png
new file mode 100644
index 0000000..e6a3ea2
Binary files /dev/null and b/renders/cornell.2016-10-04_18-27-24z.512samp.png differ
diff --git a/renders/cornell.2016-10-04_18-28-40z.1024samp.png b/renders/cornell.2016-10-04_18-28-40z.1024samp.png
new file mode 100644
index 0000000..a057a77
Binary files /dev/null and b/renders/cornell.2016-10-04_18-28-40z.1024samp.png differ
diff --git a/renders/cornell.2016-10-04_18-28-40z.512samp.png b/renders/cornell.2016-10-04_18-28-40z.512samp.png
new file mode 100644
index 0000000..7ccd15b
Binary files /dev/null and b/renders/cornell.2016-10-04_18-28-40z.512samp.png differ
diff --git a/renders/cornell.2016-10-04_19-04-04z.1024samp.png b/renders/cornell.2016-10-04_19-04-04z.1024samp.png
new file mode 100644
index 0000000..8787901
Binary files /dev/null and b/renders/cornell.2016-10-04_19-04-04z.1024samp.png differ
diff --git a/renders/cornell.2016-10-04_19-04-04z.512samp.png b/renders/cornell.2016-10-04_19-04-04z.512samp.png
new file mode 100644
index 0000000..785e506
Binary files /dev/null and b/renders/cornell.2016-10-04_19-04-04z.512samp.png differ
diff --git a/renders/cornell.2016-10-04_19-14-36z.1024samp.png b/renders/cornell.2016-10-04_19-14-36z.1024samp.png
new file mode 100644
index 0000000..0254105
Binary files /dev/null and b/renders/cornell.2016-10-04_19-14-36z.1024samp.png differ
diff --git a/renders/cornell.2016-10-04_19-14-36z.512samp.png b/renders/cornell.2016-10-04_19-14-36z.512samp.png
new file mode 100644
index 0000000..16d12fd
Binary files /dev/null and b/renders/cornell.2016-10-04_19-14-36z.512samp.png differ
diff --git a/renders/cornell.2016-10-04_19-27-36z.512samp.png b/renders/cornell.2016-10-04_19-27-36z.512samp.png
new file mode 100644
index 0000000..7ccd15b
Binary files /dev/null and b/renders/cornell.2016-10-04_19-27-36z.512samp.png differ
diff --git a/renders/cornell.2016-10-04_19-30-09z.1024samp.png b/renders/cornell.2016-10-04_19-30-09z.1024samp.png
new file mode 100644
index 0000000..a057a77
Binary files /dev/null and b/renders/cornell.2016-10-04_19-30-09z.1024samp.png differ
diff --git a/renders/cornell.2016-10-04_19-30-09z.512samp.png b/renders/cornell.2016-10-04_19-30-09z.512samp.png
new file mode 100644
index 0000000..7ccd15b
Binary files /dev/null and b/renders/cornell.2016-10-04_19-30-09z.512samp.png differ
diff --git a/renders/cornell.2016-10-04_19-31-53z.1024samp.png b/renders/cornell.2016-10-04_19-31-53z.1024samp.png
new file mode 100644
index 0000000..a057a77
Binary files /dev/null and b/renders/cornell.2016-10-04_19-31-53z.1024samp.png differ
diff --git a/renders/cornell.2016-10-04_19-31-53z.1536samp.png b/renders/cornell.2016-10-04_19-31-53z.1536samp.png
new file mode 100644
index 0000000..e3a4a5c
Binary files /dev/null and b/renders/cornell.2016-10-04_19-31-53z.1536samp.png differ
diff --git a/renders/cornell.2016-10-04_19-31-53z.512samp.png b/renders/cornell.2016-10-04_19-31-53z.512samp.png
new file mode 100644
index 0000000..7ccd15b
Binary files /dev/null and b/renders/cornell.2016-10-04_19-31-53z.512samp.png differ
diff --git a/renders/cornell.2016-10-04_19-43-00z.11samp.png b/renders/cornell.2016-10-04_19-43-00z.11samp.png
new file mode 100644
index 0000000..3f644ae
Binary files /dev/null and b/renders/cornell.2016-10-04_19-43-00z.11samp.png differ
diff --git a/renders/cornell.2016-10-04_19-44-20z.512samp.png b/renders/cornell.2016-10-04_19-44-20z.512samp.png
new file mode 100644
index 0000000..7574219
Binary files /dev/null and b/renders/cornell.2016-10-04_19-44-20z.512samp.png differ
diff --git a/renders/cornell.2016-10-04_19-51-57z.512samp.png b/renders/cornell.2016-10-04_19-51-57z.512samp.png
new file mode 100644
index 0000000..7ccd15b
Binary files /dev/null and b/renders/cornell.2016-10-04_19-51-57z.512samp.png differ
diff --git a/renders/cornell.2016-10-04_19-51-57z.680samp.png b/renders/cornell.2016-10-04_19-51-57z.680samp.png
new file mode 100644
index 0000000..273b3e9
Binary files /dev/null and b/renders/cornell.2016-10-04_19-51-57z.680samp.png differ
diff --git a/renders/cornell.2016-10-04_20-16-53z.59samp.png b/renders/cornell.2016-10-04_20-16-53z.59samp.png
new file mode 100644
index 0000000..d2ec3f1
Binary files /dev/null and b/renders/cornell.2016-10-04_20-16-53z.59samp.png differ
diff --git a/renders/cornell.2016-10-04_20-17-41z.512samp.png b/renders/cornell.2016-10-04_20-17-41z.512samp.png
new file mode 100644
index 0000000..9683d99
Binary files /dev/null and b/renders/cornell.2016-10-04_20-17-41z.512samp.png differ
diff --git a/renders/cornell.2016-10-04_20-18-29z.76samp.png b/renders/cornell.2016-10-04_20-18-29z.76samp.png
new file mode 100644
index 0000000..d2ec3f1
Binary files /dev/null and b/renders/cornell.2016-10-04_20-18-29z.76samp.png differ
diff --git a/renders/cornell.2016-10-04_20-26-18z.512samp.png b/renders/cornell.2016-10-04_20-26-18z.512samp.png
new file mode 100644
index 0000000..3ddfdeb
Binary files /dev/null and b/renders/cornell.2016-10-04_20-26-18z.512samp.png differ
diff --git a/renders/cornell.2016-10-04_20-31-24z.512samp.png b/renders/cornell.2016-10-04_20-31-24z.512samp.png
new file mode 100644
index 0000000..a58a76d
Binary files /dev/null and b/renders/cornell.2016-10-04_20-31-24z.512samp.png differ
diff --git a/renders/cornell.2016-10-04_20-33-10z.1024samp.png b/renders/cornell.2016-10-04_20-33-10z.1024samp.png
new file mode 100644
index 0000000..efded6f
Binary files /dev/null and b/renders/cornell.2016-10-04_20-33-10z.1024samp.png differ
diff --git a/renders/cornell.2016-10-04_20-33-10z.512samp.png b/renders/cornell.2016-10-04_20-33-10z.512samp.png
new file mode 100644
index 0000000..1854471
Binary files /dev/null and b/renders/cornell.2016-10-04_20-33-10z.512samp.png differ
diff --git a/renders/cornell.2016-10-04_20-37-27z.1024samp.png b/renders/cornell.2016-10-04_20-37-27z.1024samp.png
new file mode 100644
index 0000000..1ef4972
Binary files /dev/null and b/renders/cornell.2016-10-04_20-37-27z.1024samp.png differ
diff --git a/renders/cornell.2016-10-04_20-37-27z.512samp.png b/renders/cornell.2016-10-04_20-37-27z.512samp.png
new file mode 100644
index 0000000..74c8283
Binary files /dev/null and b/renders/cornell.2016-10-04_20-37-27z.512samp.png differ
diff --git a/renders/cornell.2016-10-04_21-14-03z.49samp.png b/renders/cornell.2016-10-04_21-14-03z.49samp.png
new file mode 100644
index 0000000..bfd0cad
Binary files /dev/null and b/renders/cornell.2016-10-04_21-14-03z.49samp.png differ
diff --git a/renders/cornell.2016-10-04_21-21-56z.17samp.png b/renders/cornell.2016-10-04_21-21-56z.17samp.png
new file mode 100644
index 0000000..fb2e42c
Binary files /dev/null and b/renders/cornell.2016-10-04_21-21-56z.17samp.png differ
diff --git a/renders/cornell.2016-10-04_21-23-30z.73samp.png b/renders/cornell.2016-10-04_21-23-30z.73samp.png
new file mode 100644
index 0000000..ddda283
Binary files /dev/null and b/renders/cornell.2016-10-04_21-23-30z.73samp.png differ
diff --git a/renders/cornell.2016-10-05_00-23-42z.14samp.png b/renders/cornell.2016-10-05_00-23-42z.14samp.png
new file mode 100644
index 0000000..c9fb53d
Binary files /dev/null and b/renders/cornell.2016-10-05_00-23-42z.14samp.png differ
diff --git a/renders/cornell.2016-10-05_07-35-47z.1024samp.png b/renders/cornell.2016-10-05_07-35-47z.1024samp.png
new file mode 100644
index 0000000..a7e2823
Binary files /dev/null and b/renders/cornell.2016-10-05_07-35-47z.1024samp.png differ
diff --git a/renders/cornell.2016-10-05_07-35-47z.512samp.png b/renders/cornell.2016-10-05_07-35-47z.512samp.png
new file mode 100644
index 0000000..081e6e7
Binary files /dev/null and b/renders/cornell.2016-10-05_07-35-47z.512samp.png differ
diff --git a/renders/cornell.2016-10-05_08-21-29z.1024samp.png b/renders/cornell.2016-10-05_08-21-29z.1024samp.png
new file mode 100644
index 0000000..ed6b9a6
Binary files /dev/null and b/renders/cornell.2016-10-05_08-21-29z.1024samp.png differ
diff --git a/renders/cornell.2016-10-05_08-21-29z.512samp.png b/renders/cornell.2016-10-05_08-21-29z.512samp.png
new file mode 100644
index 0000000..bd264d0
Binary files /dev/null and b/renders/cornell.2016-10-05_08-21-29z.512samp.png differ
diff --git a/renders/cornell.2016-10-05_18-11-09z.512samp.png b/renders/cornell.2016-10-05_18-11-09z.512samp.png
new file mode 100644
index 0000000..43b27f2
Binary files /dev/null and b/renders/cornell.2016-10-05_18-11-09z.512samp.png differ
diff --git a/renders/cornell.2016-10-05_18-15-50z.512samp.png b/renders/cornell.2016-10-05_18-15-50z.512samp.png
new file mode 100644
index 0000000..013c6a4
Binary files /dev/null and b/renders/cornell.2016-10-05_18-15-50z.512samp.png differ
diff --git a/renders/cornell.2016-10-05_18-17-34z.512samp.png b/renders/cornell.2016-10-05_18-17-34z.512samp.png
new file mode 100644
index 0000000..367caf6
Binary files /dev/null and b/renders/cornell.2016-10-05_18-17-34z.512samp.png differ
diff --git a/renders/cornell.2016-10-05_18-18-36z.1024samp.png b/renders/cornell.2016-10-05_18-18-36z.1024samp.png
new file mode 100644
index 0000000..24bf679
Binary files /dev/null and b/renders/cornell.2016-10-05_18-18-36z.1024samp.png differ
diff --git a/renders/cornell.2016-10-05_18-18-36z.512samp.png b/renders/cornell.2016-10-05_18-18-36z.512samp.png
new file mode 100644
index 0000000..13243cc
Binary files /dev/null and b/renders/cornell.2016-10-05_18-18-36z.512samp.png differ
diff --git a/renders/cornell.2016-10-05_22-28-18z.512samp.png b/renders/cornell.2016-10-05_22-28-18z.512samp.png
new file mode 100644
index 0000000..e4e6a3f
Binary files /dev/null and b/renders/cornell.2016-10-05_22-28-18z.512samp.png differ
diff --git a/renders/cornell.2016-10-05_22-28-18z.619samp.png b/renders/cornell.2016-10-05_22-28-18z.619samp.png
new file mode 100644
index 0000000..8149511
Binary files /dev/null and b/renders/cornell.2016-10-05_22-28-18z.619samp.png differ
diff --git a/renders/cornell.2016-10-06_15-23-53z.1024samp.png b/renders/cornell.2016-10-06_15-23-53z.1024samp.png
new file mode 100644
index 0000000..07e32fe
Binary files /dev/null and b/renders/cornell.2016-10-06_15-23-53z.1024samp.png differ
diff --git a/renders/cornell.2016-10-06_15-23-53z.512samp.png b/renders/cornell.2016-10-06_15-23-53z.512samp.png
new file mode 100644
index 0000000..f600d3b
Binary files /dev/null and b/renders/cornell.2016-10-06_15-23-53z.512samp.png differ
diff --git a/renders/cornell.2016-10-06_15-29-53z.512samp.png b/renders/cornell.2016-10-06_15-29-53z.512samp.png
new file mode 100644
index 0000000..642a0d2
Binary files /dev/null and b/renders/cornell.2016-10-06_15-29-53z.512samp.png differ
diff --git a/renders/cornell.2016-10-06_15-31-38z.1024samp.png b/renders/cornell.2016-10-06_15-31-38z.1024samp.png
new file mode 100644
index 0000000..3d6847e
Binary files /dev/null and b/renders/cornell.2016-10-06_15-31-38z.1024samp.png differ
diff --git a/renders/cornell.2016-10-06_15-31-38z.512samp.png b/renders/cornell.2016-10-06_15-31-38z.512samp.png
new file mode 100644
index 0000000..cd18af7
Binary files /dev/null and b/renders/cornell.2016-10-06_15-31-38z.512samp.png differ
diff --git a/renders/cornell.2016-10-06_15-33-06z.512samp.png b/renders/cornell.2016-10-06_15-33-06z.512samp.png
new file mode 100644
index 0000000..68a4e55
Binary files /dev/null and b/renders/cornell.2016-10-06_15-33-06z.512samp.png differ
diff --git a/renders/cornell.2016-10-06_15-33-59z.512samp.png b/renders/cornell.2016-10-06_15-33-59z.512samp.png
new file mode 100644
index 0000000..d501204
Binary files /dev/null and b/renders/cornell.2016-10-06_15-33-59z.512samp.png differ
diff --git a/renders/cornell.2016-10-06_15-36-10z.1024samp.png b/renders/cornell.2016-10-06_15-36-10z.1024samp.png
new file mode 100644
index 0000000..617a6ad
Binary files /dev/null and b/renders/cornell.2016-10-06_15-36-10z.1024samp.png differ
diff --git a/renders/cornell.2016-10-06_15-36-10z.512samp.png b/renders/cornell.2016-10-06_15-36-10z.512samp.png
new file mode 100644
index 0000000..bfbd605
Binary files /dev/null and b/renders/cornell.2016-10-06_15-36-10z.512samp.png differ
diff --git a/renders/cornell.2016-10-06_15-39-49z.275samp.png b/renders/cornell.2016-10-06_15-39-49z.275samp.png
new file mode 100644
index 0000000..ce87b75
Binary files /dev/null and b/renders/cornell.2016-10-06_15-39-49z.275samp.png differ
diff --git a/renders/cornell.2016-10-06_15-40-38z.512samp.png b/renders/cornell.2016-10-06_15-40-38z.512samp.png
new file mode 100644
index 0000000..15174ab
Binary files /dev/null and b/renders/cornell.2016-10-06_15-40-38z.512samp.png differ
diff --git a/renders/cornell.2016-10-06_15-41-51z.1024samp.png b/renders/cornell.2016-10-06_15-41-51z.1024samp.png
new file mode 100644
index 0000000..037fd8e
Binary files /dev/null and b/renders/cornell.2016-10-06_15-41-51z.1024samp.png differ
diff --git a/renders/cornell.2016-10-06_15-41-51z.1536samp.png b/renders/cornell.2016-10-06_15-41-51z.1536samp.png
new file mode 100644
index 0000000..fd16a4b
Binary files /dev/null and b/renders/cornell.2016-10-06_15-41-51z.1536samp.png differ
diff --git a/renders/cornell.2016-10-06_15-41-51z.512samp.png b/renders/cornell.2016-10-06_15-41-51z.512samp.png
new file mode 100644
index 0000000..cafe8c2
Binary files /dev/null and b/renders/cornell.2016-10-06_15-41-51z.512samp.png differ
diff --git a/renders/cornell.2016-10-06_15-51-49z.1024samp.png b/renders/cornell.2016-10-06_15-51-49z.1024samp.png
new file mode 100644
index 0000000..a7f4d94
Binary files /dev/null and b/renders/cornell.2016-10-06_15-51-49z.1024samp.png differ
diff --git a/renders/cornell.2016-10-06_15-51-49z.512samp.png b/renders/cornell.2016-10-06_15-51-49z.512samp.png
new file mode 100644
index 0000000..a42a9ec
Binary files /dev/null and b/renders/cornell.2016-10-06_15-51-49z.512samp.png differ
diff --git a/renders/cornell.2016-10-06_15-54-47z.146samp.png b/renders/cornell.2016-10-06_15-54-47z.146samp.png
new file mode 100644
index 0000000..638594a
Binary files /dev/null and b/renders/cornell.2016-10-06_15-54-47z.146samp.png differ
diff --git a/renders/cornell.2016-10-06_15-55-55z.103samp.png b/renders/cornell.2016-10-06_15-55-55z.103samp.png
new file mode 100644
index 0000000..9472717
Binary files /dev/null and b/renders/cornell.2016-10-06_15-55-55z.103samp.png differ
diff --git a/renders/cornell.2016-10-06_16-00-42z.1024samp.png b/renders/cornell.2016-10-06_16-00-42z.1024samp.png
new file mode 100644
index 0000000..dad98e7
Binary files /dev/null and b/renders/cornell.2016-10-06_16-00-42z.1024samp.png differ
diff --git a/renders/cornell.2016-10-06_16-00-42z.273samp.png b/renders/cornell.2016-10-06_16-00-42z.273samp.png
new file mode 100644
index 0000000..50eed7c
Binary files /dev/null and b/renders/cornell.2016-10-06_16-00-42z.273samp.png differ
diff --git a/renders/cornell.2016-10-06_16-00-42z.512samp.png b/renders/cornell.2016-10-06_16-00-42z.512samp.png
new file mode 100644
index 0000000..0381451
Binary files /dev/null and b/renders/cornell.2016-10-06_16-00-42z.512samp.png differ
diff --git a/renders/cornell.2016-10-06_16-26-29z.512samp.png b/renders/cornell.2016-10-06_16-26-29z.512samp.png
new file mode 100644
index 0000000..81425f6
Binary files /dev/null and b/renders/cornell.2016-10-06_16-26-29z.512samp.png differ
diff --git a/renders/cornell.2016-10-06_16-29-38z.512samp.png b/renders/cornell.2016-10-06_16-29-38z.512samp.png
new file mode 100644
index 0000000..28caf10
Binary files /dev/null and b/renders/cornell.2016-10-06_16-29-38z.512samp.png differ
diff --git a/renders/cornell.2016-10-06_18-41-30z.1024samp.png b/renders/cornell.2016-10-06_18-41-30z.1024samp.png
new file mode 100644
index 0000000..f7fe969
Binary files /dev/null and b/renders/cornell.2016-10-06_18-41-30z.1024samp.png differ
diff --git a/renders/cornell.2016-10-06_18-41-30z.512samp.png b/renders/cornell.2016-10-06_18-41-30z.512samp.png
new file mode 100644
index 0000000..a73a058
Binary files /dev/null and b/renders/cornell.2016-10-06_18-41-30z.512samp.png differ
diff --git a/renders/cornell.2016-10-06_18-43-11z.186samp.png b/renders/cornell.2016-10-06_18-43-11z.186samp.png
new file mode 100644
index 0000000..bc6f0dc
Binary files /dev/null and b/renders/cornell.2016-10-06_18-43-11z.186samp.png differ
diff --git a/renders/cornell.2016-10-06_18-43-21z.90samp.png b/renders/cornell.2016-10-06_18-43-21z.90samp.png
new file mode 100644
index 0000000..2af089c
Binary files /dev/null and b/renders/cornell.2016-10-06_18-43-21z.90samp.png differ
diff --git a/renders/cornell.2016-10-06_18-45-21z.512samp.png b/renders/cornell.2016-10-06_18-45-21z.512samp.png
new file mode 100644
index 0000000..0cf4f80
Binary files /dev/null and b/renders/cornell.2016-10-06_18-45-21z.512samp.png differ
diff --git a/renders/cornell.2016-10-06_18-46-31z.434samp.png b/renders/cornell.2016-10-06_18-46-31z.434samp.png
new file mode 100644
index 0000000..d9e2c79
Binary files /dev/null and b/renders/cornell.2016-10-06_18-46-31z.434samp.png differ
diff --git a/renders/cornell.2016-10-06_18-48-40z.1024samp.png b/renders/cornell.2016-10-06_18-48-40z.1024samp.png
new file mode 100644
index 0000000..037fd8e
Binary files /dev/null and b/renders/cornell.2016-10-06_18-48-40z.1024samp.png differ
diff --git a/renders/cornell.2016-10-06_18-48-40z.1033samp.png b/renders/cornell.2016-10-06_18-48-40z.1033samp.png
new file mode 100644
index 0000000..466dcf6
Binary files /dev/null and b/renders/cornell.2016-10-06_18-48-40z.1033samp.png differ
diff --git a/renders/cornell.2016-10-06_18-48-40z.512samp.png b/renders/cornell.2016-10-06_18-48-40z.512samp.png
new file mode 100644
index 0000000..cafe8c2
Binary files /dev/null and b/renders/cornell.2016-10-06_18-48-40z.512samp.png differ
diff --git a/renders/cornell.2016-10-06_18-53-26z.1024samp.png b/renders/cornell.2016-10-06_18-53-26z.1024samp.png
new file mode 100644
index 0000000..cc469ea
Binary files /dev/null and b/renders/cornell.2016-10-06_18-53-26z.1024samp.png differ
diff --git a/renders/cornell.2016-10-06_18-53-26z.512samp.png b/renders/cornell.2016-10-06_18-53-26z.512samp.png
new file mode 100644
index 0000000..1843648
Binary files /dev/null and b/renders/cornell.2016-10-06_18-53-26z.512samp.png differ
diff --git a/renders/cornell.2016-10-10_02-17-23z.1389samp.png b/renders/cornell.2016-10-10_02-17-23z.1389samp.png
new file mode 100644
index 0000000..66e484c
Binary files /dev/null and b/renders/cornell.2016-10-10_02-17-23z.1389samp.png differ
diff --git a/renders/cornell.2016-10-10_02-19-17z.1391samp.png b/renders/cornell.2016-10-10_02-19-17z.1391samp.png
new file mode 100644
index 0000000..5b52e7d
Binary files /dev/null and b/renders/cornell.2016-10-10_02-19-17z.1391samp.png differ
diff --git a/renders/cornell.2016-10-10_02-22-22z.1386samp.png b/renders/cornell.2016-10-10_02-22-22z.1386samp.png
new file mode 100644
index 0000000..1f4000b
Binary files /dev/null and b/renders/cornell.2016-10-10_02-22-22z.1386samp.png differ
diff --git a/renders/cornell.2016-10-10_02-27-37z.5000samp.png b/renders/cornell.2016-10-10_02-27-37z.5000samp.png
new file mode 100644
index 0000000..ce44b95
Binary files /dev/null and b/renders/cornell.2016-10-10_02-27-37z.5000samp.png differ
diff --git a/renders/cornell.2016-10-10_02-27-37z.5000sampCopy.png b/renders/cornell.2016-10-10_02-27-37z.5000sampCopy.png
new file mode 100644
index 0000000..01b71b9
Binary files /dev/null and b/renders/cornell.2016-10-10_02-27-37z.5000sampCopy.png differ
diff --git a/renders/cornell.2016-10-10_02-39-08z.5000samp.png b/renders/cornell.2016-10-10_02-39-08z.5000samp.png
new file mode 100644
index 0000000..b969e6b
Binary files /dev/null and b/renders/cornell.2016-10-10_02-39-08z.5000samp.png differ
diff --git a/renders/cornell.2016-10-10_02-51-02z.1871samp.png b/renders/cornell.2016-10-10_02-51-02z.1871samp.png
new file mode 100644
index 0000000..7b689d0
Binary files /dev/null and b/renders/cornell.2016-10-10_02-51-02z.1871samp.png differ
diff --git a/renders/cornell.2016-10-10_03-01-09z.1125samp.png b/renders/cornell.2016-10-10_03-01-09z.1125samp.png
new file mode 100644
index 0000000..9991ca3
Binary files /dev/null and b/renders/cornell.2016-10-10_03-01-09z.1125samp.png differ
diff --git a/renders/cornell.2016-10-10_03-05-09z.171samp.png b/renders/cornell.2016-10-10_03-05-09z.171samp.png
new file mode 100644
index 0000000..4c50660
Binary files /dev/null and b/renders/cornell.2016-10-10_03-05-09z.171samp.png differ
diff --git a/renders/cornell.2016-10-10_03-08-31z.708samp.png b/renders/cornell.2016-10-10_03-08-31z.708samp.png
new file mode 100644
index 0000000..6f76e00
Binary files /dev/null and b/renders/cornell.2016-10-10_03-08-31z.708samp.png differ
diff --git a/renders/cornell.2016-10-10_03-09-50z.1702samp.png b/renders/cornell.2016-10-10_03-09-50z.1702samp.png
new file mode 100644
index 0000000..7c65794
Binary files /dev/null and b/renders/cornell.2016-10-10_03-09-50z.1702samp.png differ
diff --git a/renders/cornell.2016-10-10_03-12-52z.1899samp.png b/renders/cornell.2016-10-10_03-12-52z.1899samp.png
new file mode 100644
index 0000000..33dcdbe
Binary files /dev/null and b/renders/cornell.2016-10-10_03-12-52z.1899samp.png differ
diff --git a/renders/cornell.2016-10-10_03-15-15z.1024samp.png b/renders/cornell.2016-10-10_03-15-15z.1024samp.png
new file mode 100644
index 0000000..6e6aaf9
Binary files /dev/null and b/renders/cornell.2016-10-10_03-15-15z.1024samp.png differ
diff --git a/renders/cornell.2016-10-10_03-19-06z.1490samp.png b/renders/cornell.2016-10-10_03-19-06z.1490samp.png
new file mode 100644
index 0000000..4ccca3f
Binary files /dev/null and b/renders/cornell.2016-10-10_03-19-06z.1490samp.png differ
diff --git a/renders/cornell.2016-10-10_03-22-14z.184samp.png b/renders/cornell.2016-10-10_03-22-14z.184samp.png
new file mode 100644
index 0000000..fb95395
Binary files /dev/null and b/renders/cornell.2016-10-10_03-22-14z.184samp.png differ
diff --git a/renders/cornell.2016-10-10_03-25-17z.1701samp.png b/renders/cornell.2016-10-10_03-25-17z.1701samp.png
new file mode 100644
index 0000000..79e7f7f
Binary files /dev/null and b/renders/cornell.2016-10-10_03-25-17z.1701samp.png differ
diff --git a/renders/cornell.2016-10-10_03-55-56z.5000samp.png b/renders/cornell.2016-10-10_03-55-56z.5000samp.png
new file mode 100644
index 0000000..c536edc
Binary files /dev/null and b/renders/cornell.2016-10-10_03-55-56z.5000samp.png differ
diff --git a/renders/custom.2016-10-05_18-36-41z.512samp.png b/renders/custom.2016-10-05_18-36-41z.512samp.png
new file mode 100644
index 0000000..4271fd1
Binary files /dev/null and b/renders/custom.2016-10-05_18-36-41z.512samp.png differ
diff --git a/renders/custom.2016-10-05_18-39-01z.512samp.png b/renders/custom.2016-10-05_18-39-01z.512samp.png
new file mode 100644
index 0000000..4271fd1
Binary files /dev/null and b/renders/custom.2016-10-05_18-39-01z.512samp.png differ
diff --git a/renders/custom.2016-10-10_02-48-09z.87samp.png b/renders/custom.2016-10-10_02-48-09z.87samp.png
new file mode 100644
index 0000000..d2ec3f1
Binary files /dev/null and b/renders/custom.2016-10-10_02-48-09z.87samp.png differ
diff --git a/renders/old/cornell.2016-10-01_18-47-20z.2126samp.png b/renders/old/cornell.2016-10-01_18-47-20z.2126samp.png
new file mode 100644
index 0000000..61624d9
Binary files /dev/null and b/renders/old/cornell.2016-10-01_18-47-20z.2126samp.png differ
diff --git a/renders/old/cornell.2016-10-02_05-57-45z.1577samp.png b/renders/old/cornell.2016-10-02_05-57-45z.1577samp.png
new file mode 100644
index 0000000..fdeceb5
Binary files /dev/null and b/renders/old/cornell.2016-10-02_05-57-45z.1577samp.png differ
diff --git a/renders/old/cornell.2016-10-02_06-12-16z.2296samp.png b/renders/old/cornell.2016-10-02_06-12-16z.2296samp.png
new file mode 100644
index 0000000..6e9be36
Binary files /dev/null and b/renders/old/cornell.2016-10-02_06-12-16z.2296samp.png differ
diff --git a/renders/old/cornell.2016-10-02_06-30-37z.20samp.png b/renders/old/cornell.2016-10-02_06-30-37z.20samp.png
new file mode 100644
index 0000000..0f9e2ad
Binary files /dev/null and b/renders/old/cornell.2016-10-02_06-30-37z.20samp.png differ
diff --git a/renders/old/cornell.2016-10-02_14-55-15z.12samp.png b/renders/old/cornell.2016-10-02_14-55-15z.12samp.png
new file mode 100644
index 0000000..d2ec3f1
Binary files /dev/null and b/renders/old/cornell.2016-10-02_14-55-15z.12samp.png differ
diff --git a/renders/old/cornell.2016-10-02_14-57-48z.11samp.png b/renders/old/cornell.2016-10-02_14-57-48z.11samp.png
new file mode 100644
index 0000000..d2ec3f1
Binary files /dev/null and b/renders/old/cornell.2016-10-02_14-57-48z.11samp.png differ
diff --git a/renders/old/cornell.2016-10-02_15-05-07z.7samp.png b/renders/old/cornell.2016-10-02_15-05-07z.7samp.png
new file mode 100644
index 0000000..d2ec3f1
Binary files /dev/null and b/renders/old/cornell.2016-10-02_15-05-07z.7samp.png differ
diff --git a/renders/old/cornell.2016-10-02_15-06-11z.9samp.png b/renders/old/cornell.2016-10-02_15-06-11z.9samp.png
new file mode 100644
index 0000000..d2ec3f1
Binary files /dev/null and b/renders/old/cornell.2016-10-02_15-06-11z.9samp.png differ
diff --git a/renders/old/cornell.2016-10-02_15-11-30z.23samp.png b/renders/old/cornell.2016-10-02_15-11-30z.23samp.png
new file mode 100644
index 0000000..fd74534
Binary files /dev/null and b/renders/old/cornell.2016-10-02_15-11-30z.23samp.png differ
diff --git a/renders/old/cornell.2016-10-02_15-13-54z.3samp.png b/renders/old/cornell.2016-10-02_15-13-54z.3samp.png
new file mode 100644
index 0000000..6e35d5a
Binary files /dev/null and b/renders/old/cornell.2016-10-02_15-13-54z.3samp.png differ
diff --git a/renders/old/cornell.2016-10-02_15-17-17z.57samp.png b/renders/old/cornell.2016-10-02_15-17-17z.57samp.png
new file mode 100644
index 0000000..5ddb7ee
Binary files /dev/null and b/renders/old/cornell.2016-10-02_15-17-17z.57samp.png differ
diff --git a/renders/old/cornell.2016-10-02_15-29-45z.28samp.png b/renders/old/cornell.2016-10-02_15-29-45z.28samp.png
new file mode 100644
index 0000000..0a1541c
Binary files /dev/null and b/renders/old/cornell.2016-10-02_15-29-45z.28samp.png differ
diff --git a/renders/old/cornell.2016-10-02_15-35-13z.2012samp.png b/renders/old/cornell.2016-10-02_15-35-13z.2012samp.png
new file mode 100644
index 0000000..8ddfa3e
Binary files /dev/null and b/renders/old/cornell.2016-10-02_15-35-13z.2012samp.png differ
diff --git a/renders/old/cornell.2016-10-02_22-02-26z.2028samp.png b/renders/old/cornell.2016-10-02_22-02-26z.2028samp.png
new file mode 100644
index 0000000..9dc9f14
Binary files /dev/null and b/renders/old/cornell.2016-10-02_22-02-26z.2028samp.png differ
diff --git a/renders/old/cornell.2016-10-02_23-18-02z.4430samp.png b/renders/old/cornell.2016-10-02_23-18-02z.4430samp.png
new file mode 100644
index 0000000..3e7914d
Binary files /dev/null and b/renders/old/cornell.2016-10-02_23-18-02z.4430samp.png differ
diff --git a/renders/old/sphere.2016-09-29_02-54-56z.54samp.png b/renders/old/sphere.2016-09-29_02-54-56z.54samp.png
new file mode 100644
index 0000000..6f3fcfa
Binary files /dev/null and b/renders/old/sphere.2016-09-29_02-54-56z.54samp.png differ
diff --git a/renders/old/sphere.2016-09-29_02-59-19z.19samp.png b/renders/old/sphere.2016-09-29_02-59-19z.19samp.png
new file mode 100644
index 0000000..6f3fcfa
Binary files /dev/null and b/renders/old/sphere.2016-09-29_02-59-19z.19samp.png differ
diff --git a/renders/old/sphere.2016-09-29_20-04-15z.63samp.png b/renders/old/sphere.2016-09-29_20-04-15z.63samp.png
new file mode 100644
index 0000000..6f3fcfa
Binary files /dev/null and b/renders/old/sphere.2016-09-29_20-04-15z.63samp.png differ
diff --git a/renders/sampled/cornell.2016-10-04_14-29-47z.128samp.png b/renders/sampled/cornell.2016-10-04_14-29-47z.128samp.png
new file mode 100644
index 0000000..29b2d6d
Binary files /dev/null and b/renders/sampled/cornell.2016-10-04_14-29-47z.128samp.png differ
diff --git a/renders/sampled/cornell.2016-10-04_14-29-47z.192samp.png b/renders/sampled/cornell.2016-10-04_14-29-47z.192samp.png
new file mode 100644
index 0000000..2d95a72
Binary files /dev/null and b/renders/sampled/cornell.2016-10-04_14-29-47z.192samp.png differ
diff --git a/renders/sampled/cornell.2016-10-04_14-29-47z.256samp.png b/renders/sampled/cornell.2016-10-04_14-29-47z.256samp.png
new file mode 100644
index 0000000..fd434ee
Binary files /dev/null and b/renders/sampled/cornell.2016-10-04_14-29-47z.256samp.png differ
diff --git a/renders/sampled/cornell.2016-10-04_14-29-47z.320samp.png b/renders/sampled/cornell.2016-10-04_14-29-47z.320samp.png
new file mode 100644
index 0000000..9cf59d1
Binary files /dev/null and b/renders/sampled/cornell.2016-10-04_14-29-47z.320samp.png differ
diff --git a/renders/sampled/cornell.2016-10-04_14-29-47z.384samp.png b/renders/sampled/cornell.2016-10-04_14-29-47z.384samp.png
new file mode 100644
index 0000000..36dbdc4
Binary files /dev/null and b/renders/sampled/cornell.2016-10-04_14-29-47z.384samp.png differ
diff --git a/renders/sampled/cornell.2016-10-04_14-29-47z.448samp.png b/renders/sampled/cornell.2016-10-04_14-29-47z.448samp.png
new file mode 100644
index 0000000..f6d4d77
Binary files /dev/null and b/renders/sampled/cornell.2016-10-04_14-29-47z.448samp.png differ
diff --git a/renders/sampled/cornell.2016-10-04_14-29-47z.512samp.png b/renders/sampled/cornell.2016-10-04_14-29-47z.512samp.png
new file mode 100644
index 0000000..3bdbe93
Binary files /dev/null and b/renders/sampled/cornell.2016-10-04_14-29-47z.512samp.png differ
diff --git a/renders/sampled/cornell.2016-10-04_14-29-47z.64samp.png b/renders/sampled/cornell.2016-10-04_14-29-47z.64samp.png
new file mode 100644
index 0000000..fb5df1d
Binary files /dev/null and b/renders/sampled/cornell.2016-10-04_14-29-47z.64samp.png differ
diff --git a/renders/unsampled/cornell.2016-10-04_14-31-25z.128samp.png b/renders/unsampled/cornell.2016-10-04_14-31-25z.128samp.png
new file mode 100644
index 0000000..013e6dd
Binary files /dev/null and b/renders/unsampled/cornell.2016-10-04_14-31-25z.128samp.png differ
diff --git a/renders/unsampled/cornell.2016-10-04_14-31-25z.192samp.png b/renders/unsampled/cornell.2016-10-04_14-31-25z.192samp.png
new file mode 100644
index 0000000..30b2f7c
Binary files /dev/null and b/renders/unsampled/cornell.2016-10-04_14-31-25z.192samp.png differ
diff --git a/renders/unsampled/cornell.2016-10-04_14-31-25z.256samp.png b/renders/unsampled/cornell.2016-10-04_14-31-25z.256samp.png
new file mode 100644
index 0000000..bbec9ed
Binary files /dev/null and b/renders/unsampled/cornell.2016-10-04_14-31-25z.256samp.png differ
diff --git a/renders/unsampled/cornell.2016-10-04_14-31-25z.320samp.png b/renders/unsampled/cornell.2016-10-04_14-31-25z.320samp.png
new file mode 100644
index 0000000..3df6a8d
Binary files /dev/null and b/renders/unsampled/cornell.2016-10-04_14-31-25z.320samp.png differ
diff --git a/renders/unsampled/cornell.2016-10-04_14-31-25z.384samp.png b/renders/unsampled/cornell.2016-10-04_14-31-25z.384samp.png
new file mode 100644
index 0000000..3ad40ef
Binary files /dev/null and b/renders/unsampled/cornell.2016-10-04_14-31-25z.384samp.png differ
diff --git a/renders/unsampled/cornell.2016-10-04_14-31-25z.448samp.png b/renders/unsampled/cornell.2016-10-04_14-31-25z.448samp.png
new file mode 100644
index 0000000..1c84a37
Binary files /dev/null and b/renders/unsampled/cornell.2016-10-04_14-31-25z.448samp.png differ
diff --git a/renders/unsampled/cornell.2016-10-04_14-31-25z.512samp.png b/renders/unsampled/cornell.2016-10-04_14-31-25z.512samp.png
new file mode 100644
index 0000000..79430c4
Binary files /dev/null and b/renders/unsampled/cornell.2016-10-04_14-31-25z.512samp.png differ
diff --git a/renders/unsampled/cornell.2016-10-04_14-31-25z.64samp.png b/renders/unsampled/cornell.2016-10-04_14-31-25z.64samp.png
new file mode 100644
index 0000000..798bc15
Binary files /dev/null and b/renders/unsampled/cornell.2016-10-04_14-31-25z.64samp.png differ
diff --git a/scenes/cornell.txt b/scenes/cornell.txt
index 83ff820..d1f7377 100644
--- a/scenes/cornell.txt
+++ b/scenes/cornell.txt
@@ -6,7 +6,7 @@ SPECRGB 0 0 0
REFL 0
REFR 0
REFRIOR 0
-EMITTANCE 5
+EMITTANCE 10
// Diffuse white
MATERIAL 1
@@ -43,11 +43,52 @@ MATERIAL 4
RGB .98 .98 .98
SPECEX 0
SPECRGB .98 .98 .98
+REFL 0
+REFR 1
+REFRIOR 2.5
+EMITTANCE 0
+
+// Specular white
+MATERIAL 5
+RGB .98 .98 .98
+SPECEX 0
+SPECRGB .98 .98 .98
REFL 1
REFR 0
REFRIOR 0
EMITTANCE 0
+// microfacet white
+MATERIAL 6
+RGB .4 0 .98
+SPECEX 0
+SPECRGB 1 1 1
+REFL 0
+REFR 0
+REFRIOR 0
+EMITTANCE 0
+ROUGH 300
+
+// diffuse not white
+MATERIAL 7
+RGB .4 0 .98
+SPECEX 0
+SPECRGB .98 .98 .98
+REFL 0
+REFR 0
+REFRIOR 0
+EMITTANCE 0
+
+// blinn phong?
+MATERIAL 8
+RGB .4 0 .98
+SPECEX 10.2
+SPECRGB .98 .98 .98
+REFL 0
+REFR 0
+REFRIOR 0
+EMITTANCE 0
+
// Camera
CAMERA
RES 800 800
@@ -58,6 +99,8 @@ FILE cornell
EYE 0.0 5 10.5
LOOKAT 0 5 0
UP 0 1 0
+LENSRADIUS 0.2
+FOCALDIST 5
// Ceiling light
@@ -111,7 +154,23 @@ SCALE .01 10 10
// Sphere
OBJECT 6
sphere
-material 4
-TRANS -1 4 -1
+material 7
+TRANS 2 4 -1.5
+ROTAT 0 0 0
+SCALE 3 3 3
+
+// Sphere
+OBJECT 7
+sphere
+material 8
+TRANS -2 4 -1.5
+ROTAT 0 0 0
+SCALE 3 3 3
+
+// Sphere
+OBJECT 8
+sphere
+material 0
+TRANS 0 2 4
ROTAT 0 0 0
SCALE 3 3 3
diff --git a/scenes/customLightsAndMaterials.txt b/scenes/customLightsAndMaterials.txt
new file mode 100644
index 0000000..9e524d4
--- /dev/null
+++ b/scenes/customLightsAndMaterials.txt
@@ -0,0 +1,188 @@
+MATERIAL 0 //white diffuse
+RGB 1 1 1
+SPECEX 0
+SPECRGB 1 1 1
+REFL 0
+REFR 0
+REFRIOR 0
+EMITTANCE 0
+
+MATERIAL 1 //red diffuse
+RGB .63 .06 .04
+SPECEX 0
+SPECRGB 1 1 1
+REFL 0
+REFR 0
+REFRIOR 0
+EMITTANCE 0
+
+MATERIAL 2 //green diffuse
+RGB .15 .48 .09
+SPECEX 0
+SPECRGB 1 1 1
+REFL 0
+REFR 0
+REFRIOR 0
+EMITTANCE 0
+
+MATERIAL 3 //red glossy
+RGB .63 .06 .04
+SPECEX 0
+SPECRGB 1 1 1
+REFL 0
+REFR 0
+REFRIOR 2
+EMITTANCE 0
+
+MATERIAL 4 //white glossy
+RGB 1 1 1
+SPECEX 0
+SPECRGB 1 1 1
+REFL 0
+REFR 0
+REFRIOR 2
+EMITTANCE 0
+
+MATERIAL 5 //glass
+RGB 0 0 0
+SPECEX 0
+SPECRGB 1 1 1
+REFL 0
+REFR 1
+REFRIOR 2.2
+EMITTANCE 0
+
+MATERIAL 6 //green glossy
+RGB .98 .98 .98
+SPECEX 0
+SPECRGB 1 1 1
+REFL 0
+REFR 1
+REFRIOR 1.33
+EMITTANCE 0
+
+MATERIAL 7 //light
+RGB 1 1 1
+SPECEX 0
+SPECRGB 0 0 0
+REFL 0
+REFR 0
+REFRIOR 0
+EMITTANCE 1
+
+MATERIAL 8 //light
+RGB 1 1 1
+SPECEX 0
+SPECRGB 0 0 0
+REFL 0
+REFR 0
+REFRIOR 0
+EMITTANCE 15
+
+// microfacet white
+MATERIAL 9
+RGB .4 .8 .98
+SPECEX 0
+SPECRGB 1 1 1
+ROUGH 300
+REFL 0
+REFR 0
+REFRIOR 0
+EMITTANCE 0
+
+// diffuse not white
+MATERIAL 10
+RGB .4 0 .98
+SPECEX 0
+SPECRGB .98 .98 .98
+REFL 0
+REFR 0
+REFRIOR 0
+EMITTANCE 0
+
+// blinn phong?
+MATERIAL 11
+RGB .4 0 .98
+SPECEX 100.2
+SPECRGB .98 .98 .98
+REFL 0
+REFR 0
+REFRIOR 0
+EMITTANCE 0
+
+// Camera
+CAMERA
+RES 800 800
+FOVY 45
+ITERATIONS 5000
+DEPTH 8
+FILE cornell
+EYE 0.0 5 10.5
+LOOKAT 0 5 0
+UP 0 1 0
+LENSRADIUS 0.8
+FOCALDIST 5
+
+OBJECT 0
+cube
+material 0
+TRANS 0 0 0
+ROTAT 0 0 90
+SCALE .01 10 10
+
+OBJECT 1
+cube
+material 0
+TRANS 0 5 -5
+ROTAT 0 90 0
+SCALE .01 10 10
+
+OBJECT 2
+cube
+material 0
+TRANS 0 10 0
+ROTAT 0 0 90
+SCALE .01 10 10
+
+OBJECT 3
+cube
+material 1
+TRANS -5 5 0
+ROTAT 0 0 0
+SCALE .01 10 10
+
+OBJECT 4
+cube
+material 2
+TRANS 5 5 0
+ROTAT 0 0 0
+SCALE .01 10 10
+
+OBJECT 5
+sphere
+material 9
+TRANS 0 2 0
+ROTAT 0 180 0
+SCALE 2.5 2.5 2.5
+
+OBJECT 6
+sphere
+material 10
+TRANS 2 2 2
+ROTAT 0 180 0
+SCALE 2.5 2.5 2.5
+
+OBJECT 7
+sphere
+material 6
+TRANS -2 2 -2
+ROTAT 0 180 0
+SCALE 2.5 2.5 2.5
+
+
+OBJECT 8
+cube
+material 8
+TRANS 0 10 0
+ROTAT 0 0 90
+SCALE .3 3 3
\ No newline at end of file
diff --git a/scenes/veach.txt b/scenes/veach.txt
new file mode 100644
index 0000000..ba86c79
--- /dev/null
+++ b/scenes/veach.txt
@@ -0,0 +1,186 @@
+MATERIAL 0
+RGB 1 1 1
+SPECEX 0
+SPECRGB 0 0 0
+REFL 0
+REFR 0
+REFRIOR 0
+EMITTANCE 16
+
+MATERIAL 1
+RGB 1 1 1
+SPECEX 0
+SPECRGB 0 0 0
+REFL 0
+REFR 0
+REFRIOR 0
+EMITTANCE 8
+
+MATERIAL 2
+RGB 1 1 1
+SPECEX 0
+SPECRGB 0 0 0
+REFL 0
+REFR 0
+REFRIOR 0
+EMITTANCE 4
+
+MATERIAL 3
+RGB 1 1 1
+SPECEX 0
+SPECRGB 0 0 0
+REFL 0
+REFR 0
+REFRIOR 0
+EMITTANCE 2
+
+MATERIAL 4
+RGB 1 1 1
+SPECEX 0
+SPECRGB 0 0 0
+REFL 0
+REFR 0
+REFRIOR 0
+EMITTANCE 1
+
+// infinity plane
+MATERIAL 5
+RGB .98 .98 .98
+SPECEX 0
+SPECRGB 0 0 0
+REFL 0
+REFR 0
+REFRIOR 0
+EMITTANCE 0
+
+MATERIAL 6
+RGB 1 1 1
+SPECEX 40
+SPECRGB .98 .98 .98
+REFL 0
+REFR 0
+REFRIOR 0
+EMITTANCE 0
+
+MATERIAL 7
+RGB 1 1 1
+SPECEX 156
+SPECRGB .98 .98 .98
+REFL 0
+REFR 0
+REFRIOR 0
+EMITTANCE 0
+
+MATERIAL 8
+RGB 1 1 1
+SPECEX 625
+SPECRGB .98 .98 .98
+REFL 0
+REFR 0
+REFRIOR 0
+EMITTANCE 0
+
+MATERIAL 9
+RGB 1 1 1
+SPECEX 2500
+SPECRGB .98 .98 .98
+REFL 0
+REFR 0
+REFRIOR 0
+EMITTANCE 0
+
+MATERIAL 10
+RGB 1 1 1
+SPECEX 10000
+SPECRGB .98 .98 .98
+REFL 0
+REFR 0
+REFRIOR 0
+EMITTANCE 0
+
+CAMERA
+RES 800 600
+FOVY 20
+ITERATIONS 5000
+DEPTH 8
+FILE veach
+EYE 0.0 5 15
+LOOKAT 0 5 0
+UP 0 1 0
+
+OBJECT 0
+sphere
+material 0
+TRANS -5 8 0
+ROTAT 0 0 0
+SCALE .1 .1 .1
+
+OBJECT 1
+sphere
+material 0
+TRANS -2.5 8 0
+ROTAT 0 0 0
+SCALE .45 .45 .45
+
+OBJECT 2
+sphere
+material 0
+TRANS 0 8 0
+ROTAT 0 0 0
+SCALE .8 .8 .8
+
+OBJECT 3
+sphere
+material 0
+TRANS 2.5 8 0
+ROTAT 0 0 0
+SCALE 1.15 1.15 1.15
+
+OBJECT 4
+sphere
+material 0
+TRANS 5 8 0
+ROTAT 0 0 0
+SCALE 1.5 1.5 1.5
+
+OBJECT 5
+cube
+material 5
+TRANS 0 0 0
+ROTAT 20 0 0
+SCALE 100 .01 100
+
+OBJECT 6
+cube
+material 6
+TRANS 0 2 4.6
+ROTAT 18 0 0
+SCALE 10 .1 1
+
+OBJECT 7
+cube
+material 7
+TRANS 0 2.5 3.4
+ROTAT 23 0 0
+SCALE 10 .1 1
+
+OBJECT 8
+cube
+material 8
+TRANS 0 3.2 2.3
+ROTAT 28 0 0
+SCALE 10 .1 1
+
+OBJECT 9
+cube
+material 9
+TRANS 0 4 1
+ROTAT 36 0 0
+SCALE 10 .1 1
+
+OBJECT 10
+cube
+material 10
+TRANS 0 5 0
+ROTAT 45 0 0
+SCALE 10 .1 1
\ No newline at end of file
diff --git a/src/interactions.h b/src/interactions.h
index 5ce3628..8087c0b 100644
--- a/src/interactions.h
+++ b/src/interactions.h
@@ -1,5 +1,5 @@
#pragma once
-
+#include
#include "intersections.h"
// CHECKITOUT
@@ -7,15 +7,105 @@
* Computes a cosine-weighted random direction in a hemisphere.
* Used for diffuse lighting.
*/
+
__host__ __device__
glm::vec3 calculateRandomDirectionInHemisphere(
- glm::vec3 normal, thrust::default_random_engine &rng) {
- thrust::uniform_real_distribution u01(0, 1);
+glm::vec3 normal, thrust::default_random_engine &rng) {
+
+ thrust::uniform_real_distribution u01(0, 1);
+
+ float up = sqrt(u01(rng)); // cos(theta)
+ float over = sqrt(1 - up * up); // sin(theta)
+ float around = u01(rng) * TWO_PI;
+
+ // Find a direction that is not the normal based off of whether or not the
+ // normal's components are all equal to sqrt(1/3) or whether or not at
+ // least one component is less than sqrt(1/3). Learned this trick from
+ // Peter Kutz.
+
+ glm::vec3 directionNotNormal;
+ if (abs(normal.x) < SQRT_OF_ONE_THIRD) {
+ directionNotNormal = glm::vec3(1, 0, 0);
+ }
+ else if (abs(normal.y) < SQRT_OF_ONE_THIRD) {
+ directionNotNormal = glm::vec3(0, 1, 0);
+ }
+ else {
+ directionNotNormal = glm::vec3(0, 0, 1);
+ }
+
+ // Use not-normal direction to generate two perpendicular directions
+ glm::vec3 perpendicularDirection1 =
+ glm::normalize(glm::cross(normal, directionNotNormal));
+ glm::vec3 perpendicularDirection2 =
+ glm::normalize(glm::cross(normal, perpendicularDirection1));
+
+ return up * normal
+ + cos(around) * over * perpendicularDirection1
+ + sin(around) * over * perpendicularDirection2;
+}
+
+__host__ __device__ float RadicalInverse(int n, int base) {
+ float val = 0;
+ float invBase = 1.f / base, invBi = invBase;
+ while (n > 0) {
+ int d_i = n % base;
+ val += d_i * invBi;
+ n *= invBase;
+ invBi *= invBase;
+ }
+ return val;
+}
+
+__host__ __device__ glm::ivec2 sampleStratified(int iter, int strata) {
+ glm::ivec2 uv(0);
+ uv.x = iter % strata;
+ uv.y = iter / strata;
+ return uv;
+}
+
+__host__ __device__ glm::vec2 sampleHalton(int iter) {
+ glm::vec2 uv(0);
+ uv.x = RadicalInverse(iter, 2);
+ uv.y = RadicalInverse(iter, 3);
+ return uv;
+}
+
+__host__ __device__ float VanDerCorput(int n, int scramble) {
+ n = (n << 16) | (n >> 16);
+ n = ((n & 0x00ff00ff) << 8) | ((n & 0xff00ff00) >> 8);
+ n = ((n & 0x0f0f0f0f) << 4) | ((n & 0xf0f0f0f0) >> 4);
+ n = ((n & 0x33333333) << 2) | ((n & 0xcccccccc) >> 2);
+ n = ((n & 0x55555555) << 1) | ((n & 0xaaaaaaaa) >> 1);
+ n ^= scramble;
+ return ((n >> 8) & 0xffffffff) / (float)(1 << 24);
+}
+
+__host__ __device__ float Sobol2(int n, int scramble) {
+ for (int v = 1 << 31; n != 0; n >> 1, v ^= v >> 1)
+ if (n & 0x1) scramble ^= v;
+ return ((scramble >> 8) & 0xffffffff) / (float)(1 << 24);
+}
- float up = sqrt(u01(rng)); // cos(theta)
- float over = sqrt(1 - up * up); // sin(theta)
- float around = u01(rng) * TWO_PI;
+__host__ __device__ glm::ivec2 sample02(int iter) {
+ glm::ivec2 uv(0);
+ uv.x = VanDerCorput(4, 1);
+ uv.y = Sobol2(4, 1);
+ return uv;
+}
+__host__ __device__
+glm::vec3 calculateRandomDirectionInHemisphereExponent(
+ glm::vec3 normal, thrust::default_random_engine &rng, float exponent) {
+
+ thrust::uniform_real_distribution u01(0, 1);
+
+ float theta = glm::acos(powf(u01(rng), 1 / (exponent + 1)));
+
+ float up = glm::cos(theta);
+ float over = glm::sin(theta);
+ float around = u01(rng) * TWO_PI;
+
// Find a direction that is not the normal based off of whether or not the
// normal's components are all equal to sqrt(1/3) or whether or not at
// least one component is less than sqrt(1/3). Learned this trick from
@@ -41,6 +131,30 @@ glm::vec3 calculateRandomDirectionInHemisphere(
+ sin(around) * over * perpendicularDirection2;
}
+__host__ __device__ float CosTheta(glm::vec3 wi, glm::vec3 n) {
+ return glm::dot(n, wi);
+}
+
+__host__ __device__ float SinTheta(glm::vec3 wi, glm::vec3 n) {
+ return sqrtf(glm::max(0.f, 1.f - CosTheta(wi, n) * CosTheta(wi, n)));
+}
+
+__host__ __device__ float CosPhi(glm::vec3 wi, glm::vec3 n) {
+ float sintheta = SinTheta(wi, n);
+ if (sintheta == 0.f) return 1.f;
+ return glm::clamp(wi.x / sintheta, -1.f, 1.f);
+}
+
+__host__ __device__ float SinPhi(glm::vec3 wi, glm::vec3 n) {
+ float sintheta = SinTheta(wi, n);
+ if (sintheta == 0.f) return 1.f;
+ return glm::clamp(wi.y / sintheta, -1.f, 1.f);
+}
+
+__host__ __device__ float AbsCosTheta(glm::vec3 wi, glm::vec3 n) {
+ return glm::abs(CosTheta(wi, n));
+}
+
/**
* Scatter a ray with some probabilities according to the material properties.
* For example, a diffuse surface scatters in a cosine-weighted hemisphere.
@@ -72,8 +186,79 @@ void scatterRay(
glm::vec3 intersect,
glm::vec3 normal,
const Material &m,
- thrust::default_random_engine &rng) {
- // TODO: implement this.
+ thrust::default_random_engine &rng,
+ int iter,
+ int depth) {
+ thrust::uniform_real_distribution u01(0, 1);
+
// A basic implementation of pure-diffuse shading will just call the
// calculateRandomDirectionInHemisphere defined above.
-}
+ if (m.hasReflective > 0.f) {
+ pathSegment.ray.direction = glm::reflect(pathSegment.ray.direction, normal);
+ pathSegment.color *= m.specular.color;
+ }
+ else if (m.hasRefractive > 0.f) {
+ //using schlicks approximation
+
+ float ior = m.indexOfRefraction;
+ //normal vs ray dir
+ float CosTheta = glm::dot(normal, pathSegment.ray.direction);
+ //change based on entering or exiting the refractive object
+ if (CosTheta < 0.f) ior = 1.f / ior;
+
+ float R0 = powf((1 - ior) / (1 + ior), 2.f);
+ //schlicks coeff
+ float RTheta = R0 + (1 - R0) * powf((1.f - glm::abs(CosTheta)), 5.f);
+
+ if (RTheta < u01(rng))
+ pathSegment.ray.direction = glm::normalize(glm::refract(pathSegment.ray.direction, normal, ior));
+ else
+ pathSegment.ray.direction = glm::normalize(glm::reflect(pathSegment.ray.direction, normal));
+
+ pathSegment.color *= m.specular.color;
+ }
+ else if (m.diffuseRoughness > 0.f ) {
+ //microfacet sample_f
+ glm::vec3 wi = pathSegment.ray.direction;
+
+ pathSegment.ray.direction = glm::normalize(calculateRandomDirectionInHemisphere(normal, rng));
+ glm::vec3 wo = pathSegment.ray.direction;
+ float sinThetaI = SinTheta(wi, normal);
+ float sinThetaO = SinTheta(wo, normal);
+ // Compute cosine term of Oren-Nayar model
+ glm::vec3 tangent = glm::normalize(glm::cross(normal, wi));
+ float maxCos = 0;
+ if (sinThetaI > 1e-4 && sinThetaO > 1e-4) {
+ float sinPhiI = SinTheta(wi, tangent), cosPhiI = CosTheta(wi, tangent);
+ float sinPhiO = SinTheta(wo, tangent), cosPhiO = CosTheta(wo, tangent);
+ float dCos = cosPhiI * cosPhiO + sinPhiI * sinPhiO;
+ maxCos = glm::max(0.f, dCos);
+ }
+
+ // Compute sine and tangent terms of Oren-Nayar model
+ float sinAlpha, tanBeta;
+ if (AbsCosTheta(wi, normal) > AbsCosTheta(wo, normal)) {
+ sinAlpha = sinThetaO;
+ tanBeta = sinThetaI / AbsCosTheta(wi, normal);
+ }
+ else {
+ sinAlpha = sinThetaI;
+ tanBeta = sinThetaO / AbsCosTheta(wo, normal);
+ }
+ //roughness
+ float sigma = glm::radians(m.diffuseRoughness);
+ float A = 1.f - ((sigma*sigma) / (2.f *(sigma*sigma + 0.33f)));
+ float B = 0.45f * (sigma*sigma) / (sigma*sigma + 0.09f);
+ pathSegment.color *= (A + B * maxCos * sinAlpha * tanBeta);
+ }
+ else if (m.specular.exponent > 0.f) {
+ pathSegment.ray.direction = glm::normalize(calculateRandomDirectionInHemisphereExponent(normal, rng, m.specular.exponent));
+ pathSegment.color *= m.specular.color;
+ }
+ else {
+ pathSegment.ray.direction = glm::normalize(calculateRandomDirectionInHemisphere(normal, rng));
+ }
+ pathSegment.color *= m.color * glm::abs(glm::dot(normal, pathSegment.ray.direction));
+ pathSegment.ray.origin = intersect + (1e-3f * pathSegment.ray.direction);
+ pathSegment.remainingBounces--;
+}
\ No newline at end of file
diff --git a/src/main.cpp b/src/main.cpp
index fe8e85e..dbb9cef 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,6 +1,7 @@
#include "main.h"
#include "preview.h"
#include
+#include
static std::string startTimeString;
@@ -134,8 +135,16 @@ void runCuda() {
// execute the kernel
int frame = 0;
+ auto begin = std::chrono::high_resolution_clock::now();
pathtrace(pbo_dptr, frame, iteration);
-
+ //if (iteration % 512 == 0) saveImage();
+ auto end = std::chrono::high_resolution_clock::now();
+ std::cout << std::chrono::duration_cast(end - begin).count() << " ms" << std::endl;
+ if (iteration == 128) {
+ pathtraceFree();
+ cudaDeviceReset();
+ exit(EXIT_SUCCESS);
+ }
// unmap buffer object
cudaGLUnmapBufferObject(pbo);
} else {
@@ -144,6 +153,7 @@ void runCuda() {
cudaDeviceReset();
exit(EXIT_SUCCESS);
}
+
}
void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods) {
diff --git a/src/pathtrace.cu b/src/pathtrace.cu
index c1ec122..f24a423 100644
--- a/src/pathtrace.cu
+++ b/src/pathtrace.cu
@@ -1,5 +1,7 @@
+#define _USE_MATH_DEFINES
#include
#include
+#include
#include
#include
#include
@@ -14,6 +16,11 @@
#include "intersections.h"
#include "interactions.h"
+#define DOF 1
+#define CACHE_FIRSTBOUNCE 1
+#define MATERIAL_SORT 0
+#define ENABLE_AA 1
+
#define ERRORCHECK 1
#define FILENAME (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
@@ -73,6 +80,9 @@ static Geom * dev_geoms = NULL;
static Material * dev_materials = NULL;
static PathSegment * dev_paths = NULL;
static ShadeableIntersection * dev_intersections = NULL;
+static ShadeableIntersection * dev_intersections_cache = NULL;
+static int * dev_materialIds1 = NULL;
+static int * dev_materialIds2 = NULL;
// TODO: static variables for device memory, any extra info you need, etc
// ...
@@ -94,8 +104,18 @@ void pathtraceInit(Scene *scene) {
cudaMalloc(&dev_intersections, pixelcount * sizeof(ShadeableIntersection));
cudaMemset(dev_intersections, 0, pixelcount * sizeof(ShadeableIntersection));
+
+ // TODO: initialize any extra device memeory you need
+
+ cudaMalloc(&dev_materialIds1, pixelcount * sizeof(int));
+ cudaMemset(dev_materialIds1, 0, pixelcount * sizeof(int));
+
+ cudaMalloc(&dev_materialIds2, pixelcount * sizeof(int));
+ cudaMemset(dev_materialIds2, 0, pixelcount * sizeof(int));
+
+ cudaMalloc(&dev_intersections_cache, pixelcount * sizeof(ShadeableIntersection));
+ cudaMemset(dev_intersections_cache, 0, pixelcount * sizeof(ShadeableIntersection));
- // TODO: initialize any extra device memeory you need
checkCUDAError("pathtraceInit");
}
@@ -106,11 +126,30 @@ void pathtraceFree() {
cudaFree(dev_geoms);
cudaFree(dev_materials);
cudaFree(dev_intersections);
- // TODO: clean up any extra device memory you created
-
+
+ cudaFree(dev_materialIds1);
+ cudaFree(dev_materialIds2);
+ cudaFree(dev_intersections_cache);
checkCUDAError("pathtraceFree");
}
+__host__ __device__ glm::vec2 ConcentricSampleDisk(float u1, float u2) {
+ float r, theta;
+ float sx = 2 * u1 - 1;
+ float sy = 2 * u2 - 1;
+ if (sx == 0 && sy == 0) return glm::vec2(0);
+
+ if (std::abs(sx) > std::abs(sy)) {
+ r = sx;
+ theta = (M_PI * 0.25f) * (sy / sx);
+ }
+ else {
+ r = sy;
+ theta = (M_PI * 0.5f) - (M_PI * 0.25f) * (sx / sy);
+ }
+ return r * glm::vec2(std::cos(theta), std::sin(theta));
+}
+
/**
* Generate PathSegments with rays from the camera through the screen into the
* scene, which is the first bounce of rays.
@@ -129,20 +168,48 @@ __global__ void generateRayFromCamera(Camera cam, int iter, int traceDepth, Path
PathSegment & segment = pathSegments[index];
segment.ray.origin = cam.position;
- segment.color = glm::vec3(1.0f, 1.0f, 1.0f);
+ segment.color = glm::vec3(1.0f, 1.0f, 1.0f);
+
+ thrust::default_random_engine rng = makeSeededRandomEngine(iter, index, 0);
+ thrust::uniform_real_distribution u01(0, 1);
+ glm::vec2 jitter(u01(rng), u01(rng));
+
+ float sx, sy;
+ if (ENABLE_AA){
+ //stochastic aa
+ sx = (float)x + jitter.x;
+ sy = (float)y + jitter.y;
+ }
+ else{
+ sx = (float)x;
+ sy = (float)y;
- // TODO: implement antialiasing by jittering the ray
- segment.ray.direction = glm::normalize(cam.view
- - cam.right * cam.pixelLength.x * ((float)x - (float)cam.resolution.x * 0.5f)
- - cam.up * cam.pixelLength.y * ((float)y - (float)cam.resolution.y * 0.5f)
+ }
+
+ segment.ray.direction = glm::normalize(
+ cam.view
+ - cam.right * cam.pixelLength.x * (sx - (float)cam.resolution.x * 0.5f)
+ - cam.up * cam.pixelLength.y * (sy - (float)cam.resolution.y * 0.5f)
);
+ if (DOF && cam.lensRadius > 0.f) {
+ glm::vec2 lens = ConcentricSampleDisk(u01(rng), u01(rng));
+ lens.x *= cam.lensRadius;
+ lens.y *= cam.lensRadius;
+
+ float ft = glm::abs(cam.focalDistance / segment.ray.direction.z);
+ glm::vec3 Pfocus = segment.ray.origin + segment.ray.direction * ft;
+
+ segment.ray.origin += lens.x * cam.right + lens.y * cam.up;
+ segment.ray.direction = glm::normalize(Pfocus - segment.ray.origin);
+ }
+
segment.pixelIndex = index;
segment.remainingBounces = traceDepth;
}
}
-// TODO:
+//
// computeIntersections handles generating ray intersections ONLY.
// Generating new rays is handled in your shader(s).
// Feel free to modify the code below.
@@ -208,6 +275,7 @@ __global__ void computeIntersections(
intersections[path_index].t = t_min;
intersections[path_index].materialId = geoms[hit_geom_index].materialid;
intersections[path_index].surfaceNormal = normal;
+ intersections[path_index].intersectPoint = intersect_point;
}
}
}
@@ -221,48 +289,44 @@ __global__ void computeIntersections(
// Note that this shader does NOT do a BSDF evaluation!
// Your shaders should handle that - this can allow techniques such as
// bump mapping.
-__global__ void shadeFakeMaterial (
- int iter
- , int num_paths
+
+__global__ void shadeMaterial(
+ int iter
+ , int depth
+ , int num_paths
, ShadeableIntersection * shadeableIntersections
, PathSegment * pathSegments
, Material * materials
- )
+)
{
- int idx = blockIdx.x * blockDim.x + threadIdx.x;
- if (idx < num_paths)
- {
- ShadeableIntersection intersection = shadeableIntersections[idx];
- if (intersection.t > 0.0f) { // if the intersection exists...
- // Set up the RNG
- // LOOK: this is how you use thrust's RNG! Please look at
- // makeSeededRandomEngine as well.
- thrust::default_random_engine rng = makeSeededRandomEngine(iter, idx, 0);
- thrust::uniform_real_distribution u01(0, 1);
-
- Material material = materials[intersection.materialId];
- glm::vec3 materialColor = material.color;
-
- // If the material indicates that the object was a light, "light" the ray
- if (material.emittance > 0.0f) {
- pathSegments[idx].color *= (materialColor * material.emittance);
- }
- // Otherwise, do some pseudo-lighting computation. This is actually more
- // like what you would expect from shading in a rasterizer like OpenGL.
- // TODO: replace this! you should be able to start with basically a one-liner
- else {
- float lightTerm = glm::dot(intersection.surfaceNormal, glm::vec3(0.0f, 1.0f, 0.0f));
- pathSegments[idx].color *= (materialColor * lightTerm) * 0.3f + ((1.0f - intersection.t * 0.02f) * materialColor) * 0.7f;
- pathSegments[idx].color *= u01(rng); // apply some noise because why not
- }
- // If there was no intersection, color the ray black.
- // Lots of renderers use 4 channel color, RGBA, where A = alpha, often
- // used for opacity, in which case they can indicate "no opacity".
- // This can be useful for post-processing and image compositing.
- } else {
- pathSegments[idx].color = glm::vec3(0.0f);
- }
- }
+ int idx = blockIdx.x * blockDim.x + threadIdx.x;
+ if (idx < num_paths)
+ {
+ ShadeableIntersection intersection = shadeableIntersections[idx];
+ if (pathSegments[idx].remainingBounces > 0 && intersection.t > 0.0f) { // if the intersection exists...
+ // Set up the RNG
+ thrust::default_random_engine rng = makeSeededRandomEngine(iter, idx, 0);
+ thrust::uniform_real_distribution u01(0, 1);
+
+ Material material = materials[intersection.materialId];
+ glm::vec3 materialColor = material.color;
+
+ // If the material indicates that the object was a light, "light" the ray
+ if (material.emittance > 0.0f) {
+ pathSegments[idx].color *= (materialColor * material.emittance);
+ pathSegments[idx].remainingBounces = 0;
+ }
+ // Otherwise, do some pseudo-lighting computation. This is actually more
+ // like what you would expect from shading in a rasterizer like OpenGL.
+ else {
+ scatterRay(pathSegments[idx], intersection.intersectPoint, intersection.surfaceNormal, material, makeSeededRandomEngine(iter, idx, 0), iter, depth);
+ }
+ }
+ else {
+ pathSegments[idx].color = glm::vec3(0.0f);
+ pathSegments[idx].remainingBounces = 0;
+ }
+ }
}
// Add the current iteration's output to the overall image
@@ -270,124 +334,191 @@ __global__ void finalGather(int nPaths, glm::vec3 * image, PathSegment * iterati
{
int index = (blockIdx.x * blockDim.x) + threadIdx.x;
- if (index < nPaths)
+ if (index < nPaths && iterationPaths[index].remainingBounces == 0)
{
- PathSegment iterationPath = iterationPaths[index];
- image[iterationPath.pixelIndex] += iterationPath.color;
+ image[iterationPaths[index].pixelIndex] += iterationPaths[index].color;
}
}
+struct terminatePath
+{
+ __host__ __device__
+ bool operator()(const PathSegment& pathSeg)
+ {
+ return (pathSeg.remainingBounces == 0);
+ }
+};
+
+__global__ void kernSetMaterialIds(int nPaths, int* dev_materialIds1, int* dev_materialIds2, ShadeableIntersection* dev_intersections) {
+ int index = (blockIdx.x * blockDim.x) + threadIdx.x;
+ if (index >= nPaths) return;
+
+ dev_materialIds1[index] = dev_materialIds2[index] = dev_intersections[index].materialId;
+}
+
/**
* Wrapper for the __global__ call that sets up the kernel calls and does a ton
* of memory management
*/
void pathtrace(uchar4 *pbo, int frame, int iter) {
- const int traceDepth = hst_scene->state.traceDepth;
- const Camera &cam = hst_scene->state.camera;
- const int pixelcount = cam.resolution.x * cam.resolution.y;
+ const int traceDepth = hst_scene->state.traceDepth;
+ const Camera &cam = hst_scene->state.camera;
+ const int pixelcount = cam.resolution.x * cam.resolution.y;
// 2D block for generating ray from camera
- const dim3 blockSize2d(8, 8);
- const dim3 blocksPerGrid2d(
- (cam.resolution.x + blockSize2d.x - 1) / blockSize2d.x,
- (cam.resolution.y + blockSize2d.y - 1) / blockSize2d.y);
+ const dim3 blockSize2d(8, 8);
+ const dim3 blocksPerGrid2d(
+ (cam.resolution.x + blockSize2d.x - 1) / blockSize2d.x,
+ (cam.resolution.y + blockSize2d.y - 1) / blockSize2d.y);
// 1D block for path tracing
const int blockSize1d = 128;
- ///////////////////////////////////////////////////////////////////////////
-
- // Recap:
- // * Initialize array of path rays (using rays that come out of the camera)
- // * You can pass the Camera object to that kernel.
- // * Each path ray must carry at minimum a (ray, color) pair,
- // * where color starts as the multiplicative identity, white = (1, 1, 1).
- // * This has already been done for you.
- // * For each depth:
- // * Compute an intersection in the scene for each path ray.
- // A very naive version of this has been implemented for you, but feel
- // free to add more primitives and/or a better algorithm.
- // Currently, intersection distance is recorded as a parametric distance,
- // t, or a "distance along the ray." t = -1.0 indicates no intersection.
- // * Color is attenuated (multiplied) by reflections off of any object
- // * TODO: Stream compact away all of the terminated paths.
- // You may use either your implementation or `thrust::remove_if` or its
- // cousins.
- // * Note that you can't really use a 2D kernel launch any more - switch
- // to 1D.
- // * TODO: Shade the rays that intersected something or didn't bottom out.
- // That is, color the ray by performing a color computation according
- // to the shader, then generate a new ray to continue the ray path.
- // We recommend just updating the ray's PathSegment in place.
- // Note that this step may come before or after stream compaction,
- // since some shaders you write may also cause a path to terminate.
- // * Finally, add this iteration's results to the image. This has been done
- // for you.
-
- // TODO: perform one iteration of path tracing
-
- generateRayFromCamera <<>>(cam, iter, traceDepth, dev_paths);
+ ///////////////////////////////////////////////////////////////////////////
+
+ // Recap:
+ // * Initialize array of path rays (using rays that come out of the camera)
+ // * You can pass the Camera object to that kernel.
+ // * Each path ray must carry at minimum a (ray, color) pair,
+ // * where color starts as the multiplicative identity, white = (1, 1, 1).
+ // * This has already been done for you.
+ // * For each depth:
+ // * Compute an intersection in the scene for each path ray.
+ // A very naive version of this has been implemented for you, but feel
+ // free to add more primitives and/or a better algorithm.
+ // Currently, intersection distance is recorded as a parametric distance,
+ // t, or a "distance along the ray." t = -1.0 indicates no intersection.
+ // * Color is attenuated (multiplied) by reflections off of any object
+ // * TODO: Stream compact away all of the terminated paths.
+ // You may use either your implementation or `thrust::remove_if` or its
+ // cousins.
+ // * Note that you can't really use a 2D kernel launch any more - switch
+ // to 1D.
+ // * TODO: Shade the rays that intersected something or didn't bottom out.
+ // That is, color the ray by performing a color computation according
+ // to the shader, then generate a new ray to continue the ray path.
+ // We recommend just updating the ray's PathSegment in place.
+ // Note that this step may come before or after stream compaction,
+ // since some shaders you write may also cause a path to terminate.
+ // * Finally, add this iteration's results to the image. This has been done
+ // for you.
+
+ // TODO: perform one iteration of path tracing
+ cudaEvent_t start, stop;
+ cudaEventCreate(&start);
+ cudaEventCreate(&stop);
+ generateRayFromCamera << > >(cam, iter, traceDepth, dev_paths);
checkCUDAError("generate camera ray");
int depth = 0;
PathSegment* dev_path_end = dev_paths + pixelcount;
int num_paths = dev_path_end - dev_paths;
+ int pathsFlight = num_paths;
// --- PathSegment Tracing Stage ---
// Shoot ray into scene, bounce between objects, push shading chunks
-
- bool iterationComplete = false;
+ float computeMilliseconds = 0.f, time = 0.f, sortMilliseconds = 0.f;
+ bool iterationComplete = false;
while (!iterationComplete) {
- // clean shading chunks
- cudaMemset(dev_intersections, 0, pixelcount * sizeof(ShadeableIntersection));
-
- // tracing
- dim3 numblocksPathSegmentTracing = (num_paths + blockSize1d - 1) / blockSize1d;
- computeIntersections <<>> (
- depth
- , num_paths
- , dev_paths
- , dev_geoms
- , hst_scene->geoms.size()
- , dev_intersections
- );
- checkCUDAError("trace one bounce");
- cudaDeviceSynchronize();
- depth++;
-
-
- // TODO:
- // --- Shading Stage ---
- // Shade path segments based on intersections and generate new rays by
- // evaluating the BSDF.
- // Start off with just a big kernel that handles all the different
- // materials you have in the scenefile.
- // TODO: compare between directly shading the path segments and shading
- // path segments that have been reshuffled to be contiguous in memory.
-
- shadeFakeMaterial<<>> (
- iter,
- num_paths,
- dev_intersections,
- dev_paths,
- dev_materials
- );
- iterationComplete = true; // TODO: should be based off stream compaction results.
- }
+ // clean shading chunks
+ cudaMemset(dev_intersections, 0, pixelcount * sizeof(ShadeableIntersection));
+ cudaEventRecord(start);
+ // tracing
+ dim3 numblocksPathSegmentTracing = (num_paths + blockSize1d - 1) / blockSize1d;
+ if (CACHE_FIRSTBOUNCE && (iter == 1 && depth == 0) || depth > 0) {
+
+ computeIntersections << > > (
+ depth
+ , num_paths
+ , dev_paths
+ , dev_geoms
+ , hst_scene->geoms.size()
+ , dev_intersections
+ );
+ }
+ if (!CACHE_FIRSTBOUNCE)
+ computeIntersections << > > (
+ depth
+ , num_paths
+ , dev_paths
+ , dev_geoms
+ , hst_scene->geoms.size()
+ , dev_intersections
+ );
+
+ if (CACHE_FIRSTBOUNCE && iter == 1 && depth == 0) {
+ cudaMemcpy(dev_intersections_cache, dev_intersections, pixelcount * sizeof(ShadeableIntersection), cudaMemcpyDeviceToDevice);
+ }
+ else if (CACHE_FIRSTBOUNCE && iter > 1 && depth == 0) {
+ cudaMemcpy(dev_intersections, dev_intersections_cache, pixelcount * sizeof(ShadeableIntersection), cudaMemcpyDeviceToDevice);
+ }
- // Assemble this iteration and apply it to the image
- dim3 numBlocksPixels = (pixelcount + blockSize1d - 1) / blockSize1d;
- finalGather<<>>(num_paths, dev_image, dev_paths);
+ checkCUDAError("trace one bounce");
+ cudaDeviceSynchronize();
+ depth++;
+ cudaEventRecord(stop);
+ cudaEventSynchronize(stop);
+ cudaEventElapsedTime(&computeMilliseconds, start, stop);
+ time += computeMilliseconds;
+
+ //
+ // --- Shading Stage ---
+ // Shade path segments based on intersections and generate new rays by
+ // evaluating the BSDF.
+ // Start off with just a big kernel that handles all the different
+ // materials you have in the scenefile.
+ // TODO: compare between directly shading the path segments and shading
+ // path segments that have been reshuffled to be contiguous in memory.
+
+ //need two different device variables
+ if (MATERIAL_SORT){
+ cudaEventRecord(start);
+ kernSetMaterialIds << > >(num_paths, dev_materialIds1, dev_materialIds2, dev_intersections);
+ checkCUDAError("set material ids");
+ thrust::sort_by_key(thrust::device, dev_materialIds1, dev_materialIds1 + num_paths, dev_paths);
+ thrust::sort_by_key(thrust::device, dev_materialIds2, dev_materialIds2 + num_paths, dev_intersections);
+ cudaEventRecord(stop);
+ cudaEventSynchronize(stop);
+ cudaEventElapsedTime(&sortMilliseconds, start, stop);
+ time += sortMilliseconds;
+ }
- ///////////////////////////////////////////////////////////////////////////
+ shadeMaterial << > > (
+ iter,
+ depth,
+ num_paths,
+ dev_intersections,
+ dev_paths,
+ dev_materials
+ );
- // Send results to OpenGL buffer for rendering
- sendImageToPBO<<>>(pbo, cam.resolution, iter, dev_image);
+ dim3 numBlocksPixels = (num_paths + blockSize1d - 1) / blockSize1d;
+ finalGather << > >(num_paths, dev_image, dev_paths);
- // Retrieve image from GPU
- cudaMemcpy(hst_scene->state.image.data(), dev_image,
- pixelcount * sizeof(glm::vec3), cudaMemcpyDeviceToHost);
+
+ PathSegment* newPathEnd = thrust::remove_if(
+ thrust::device,
+ dev_paths,
+ dev_paths + num_paths,
+ terminatePath());
+ num_paths = newPathEnd - dev_paths;
- checkCUDAError("pathtrace");
-}
+
+ iterationComplete = depth >= traceDepth || num_paths == 0;
+ }
+ std::cout << "compute intersection took: " << computeMilliseconds << " ms" << std::endl;
+ std::cout << "sort intersection took: " << computeMilliseconds << " ms" << std::endl;
+ std::cout << "total time: " << time << " ms" << std::endl;
+ ///////////////////////////////////////////////////////////////////////////
+
+ // Send results to OpenGL buffer for rendering
+ sendImageToPBO << > >(pbo, cam.resolution, iter, dev_image);
+
+
+ // Retrieve image from GPU
+ cudaMemcpy(hst_scene->state.image.data(), dev_image,
+ pixelcount * sizeof(glm::vec3), cudaMemcpyDeviceToHost);
+
+ checkCUDAError("pathtrace");
+}
\ No newline at end of file
diff --git a/src/scene.cpp b/src/scene.cpp
index cbae043..41855a2 100644
--- a/src/scene.cpp
+++ b/src/scene.cpp
@@ -109,7 +109,7 @@ int Scene::loadCamera() {
state.iterations = atoi(tokens[1].c_str());
} else if (strcmp(tokens[0].c_str(), "DEPTH") == 0) {
state.traceDepth = atoi(tokens[1].c_str());
- } else if (strcmp(tokens[0].c_str(), "FILE") == 0) {
+ } else if (strcmp(tokens[0].c_str(), "FILE") == 0) {
state.imageName = tokens[1];
}
}
@@ -124,7 +124,12 @@ int Scene::loadCamera() {
camera.lookAt = glm::vec3(atof(tokens[1].c_str()), atof(tokens[2].c_str()), atof(tokens[3].c_str()));
} else if (strcmp(tokens[0].c_str(), "UP") == 0) {
camera.up = glm::vec3(atof(tokens[1].c_str()), atof(tokens[2].c_str()), atof(tokens[3].c_str()));
- }
+ } else if (strcmp(tokens[0].c_str(), "LENSRADIUS") == 0) {
+ camera.lensRadius = atof(tokens[1].c_str());
+ }
+ else if (strcmp(tokens[0].c_str(), "FOCALDIST") == 0) {
+ camera.focalDistance = atof(tokens[1].c_str());
+ }
utilityCore::safeGetline(fp_in, line);
}
@@ -174,7 +179,9 @@ int Scene::loadMaterial(string materialid) {
newMaterial.specular.color = specColor;
} else if (strcmp(tokens[0].c_str(), "REFL") == 0) {
newMaterial.hasReflective = atof(tokens[1].c_str());
- } else if (strcmp(tokens[0].c_str(), "REFR") == 0) {
+ } else if (strcmp(tokens[0].c_str(), "ROUGH") == 0) {
+ newMaterial.diffuseRoughness = atof(tokens[1].c_str());
+ } else if (strcmp(tokens[0].c_str(), "REFR") == 0) {
newMaterial.hasRefractive = atof(tokens[1].c_str());
} else if (strcmp(tokens[0].c_str(), "REFRIOR") == 0) {
newMaterial.indexOfRefraction = atof(tokens[1].c_str());
diff --git a/src/sceneStructs.h b/src/sceneStructs.h
index b38b820..e16c8d9 100644
--- a/src/sceneStructs.h
+++ b/src/sceneStructs.h
@@ -38,6 +38,7 @@ struct Material {
float hasRefractive;
float indexOfRefraction;
float emittance;
+ float diffuseRoughness;
};
struct Camera {
@@ -49,6 +50,8 @@ struct Camera {
glm::vec3 right;
glm::vec2 fov;
glm::vec2 pixelLength;
+ float lensRadius;
+ float focalDistance;
};
struct RenderState {
@@ -70,6 +73,7 @@ struct PathSegment {
// 1) color contribution computation
// 2) BSDF evaluation: generate a new ray
struct ShadeableIntersection {
+ glm::vec3 intersectPoint;
float t;
glm::vec3 surfaceNormal;
int materialId;