Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(Charles) Zixin Zhang #19

Open
wants to merge 18 commits into
base: main
Choose a base branch
from
6 changes: 3 additions & 3 deletions INSTRUCTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ You will need to implement the following features:
* See notes on diffuse/specular in `scatterRay` and on imperfect specular below.
* Path continuation/termination using Stream Compaction from Project 2.
* After you have a [basic pathtracer up and running](img/REFERENCE_cornell.5000samp.png),
implement a means of making rays/pathSegments/intersections contiguous in memory by material type. This should be easily toggleable.
implement a means of making rays/pathSegments/intersections contiguous in memory by material type. This should be easily toggleable.
* Consider the problems with coloring every path segment in a buffer and performing BSDF evaluation using one big shading kernel: different materials/BSDF evaluations within the kernel will take different amounts of time to complete.
* Sort the rays/path segments so that rays/paths interacting with the same material are contiguous in memory before shading. How does this impact performance? Why?
* A toggleable option to cache the first bounce intersections for re-use across all subsequent iterations. Provide performance benefit analysis across different max ray depths.
Expand Down Expand Up @@ -149,8 +149,8 @@ For each extra feature, you must provide the following analysis:

You'll be working in the following files. Look for important parts of the code:

* Search for `CHECKITOUT`.
* You'll have to implement parts labeled with `TODO`. (But don't let these constrain you - you have free rein!)
* Search for `CHECKITOUT`. (`interactions.h`, `intersections.h` and `main.cpp`)
* You'll have to implement parts labeled with `TODO`. (But don't let these constrain you - you have free rein!) (`interactions.h`, `pathtrace.cu`)

* `src/pathtrace.cu`: path tracing kernels, device functions, and calling code
* `pathtraceInit` initializes the path tracer state - it should copy scene data (e.g. geometry, materials) from `Scene`.
Expand Down
44 changes: 38 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,45 @@
CUDA Path Tracer
================

**University of Pennsylvania, CIS 565: GPU Programming and Architecture, Project 3**
![](img/Demo.png)

* (TODO) YOUR NAME HERE
* Tested on: (TODO) Windows 22, i7-2222 @ 2.22GHz 22GB, GTX 222 222MB (Moore 2222 Lab)

### (TODO: Your README)

*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.
## Sorting by Material

5000 iteration with a simple Cornell scene:

![](img/sorting.png)

Sorting by material worsened the performance when using the simple Cornell scene. I think that it is because the scene has so few materials that sorting itself would negatively affect the performance. I predict that if the scene is complex with lots of materials, sorting would improve the performance.

## Caching the First Bounce

5000 iteration with a simple Cornell scene:

![](img/caching.png)

Caching the first bounce gives us a huge performance boost as shown in the figure. Without considering anti-aliasing, it is critical that we cache the first bounce so that later iterations can reuse it whenever they need.

## Anti-aliasing

Visual comparision:

![](img/AA.gif)

Performance comparison:

![](img/AA.png)

# Notes

Changes to scene files:

- Use FOVYH for half angle vertical field of view

### Notes to myself

ATTENTION:

1. read access violation when using thrust::remove_if. Fix: use thrust::device as the first parameter to indicate the correct execution policy because dev_paths is in device memory

Binary file added img/AA.gif
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/AA.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/Demo.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/caching.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/sorting.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/stuck.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions scenes/cornell.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ EMITTANCE 0

// Camera
CAMERA
RES 800 800
FOVY 45
RES 1920 1080
FOVYH 45
ITERATIONS 5000
DEPTH 8
FILE cornell
Expand Down Expand Up @@ -114,4 +114,4 @@ sphere
material 4
TRANS -1 4 -1
ROTAT 0 0 0
SCALE 3 3 3
SCALE 6 6 6
149 changes: 149 additions & 0 deletions scenes/newScene.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
// Emissive material (light)
MATERIAL 0
RGB 1 1 1
SPECEX 0
SPECRGB 0 0 0
REFL 0
REFR 0
REFRIOR 0
EMITTANCE 5

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

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

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

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

// Camera
CAMERA
RES 1920 1080
FOVYH 45
ITERATIONS 5000
DEPTH 8
FILE cornell
EYE 0.0 5 10.5
LOOKAT 0 5 0
UP 0 1 0


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

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

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

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

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

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

// Sphere
OBJECT 6
sphere
material 4
TRANS -1 2 2
ROTAT 0 0 0
SCALE 3 3 3

// Sphere
OBJECT 7
sphere
material 1
TRANS -1 4 0
ROTAT 0 0 0
SCALE 3 3 3

// Sphere
OBJECT 8
sphere
material 3
TRANS -1 5 -1
ROTAT 0 0 0
SCALE 3 3 3

// Sphere
OBJECT 9
sphere
material 2
TRANS 0 4 -1
ROTAT 0 0 0
SCALE 3 3 3

// Sphere
OBJECT 10
sphere
material 4
TRANS 1 2 2
ROTAT 0 0 0
SCALE 3 3 3
2 changes: 1 addition & 1 deletion scenes/sphere.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ EMITTANCE 5
// Camera
CAMERA
RES 800 800
FOVY 45
FOVYH 45
ITERATIONS 5000
DEPTH 8
FILE sphere
Expand Down
30 changes: 28 additions & 2 deletions src/interactions.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// ray scattering functions
#pragma once

#include "intersections.h"
Expand Down Expand Up @@ -50,7 +51,7 @@ glm::vec3 calculateRandomDirectionInHemisphere(
*
* The visual effect you want is to straight-up add the diffuse and specular
* components. You can do this in a few ways. This logic also applies to
* combining other types of materias (such as refractive).
* combining other types of materials (such as refractive).
*
* - Always take an even (50/50) split between a each effect (a diffuse bounce
* and a specular bounce), but divide the resulting color of either branch
Expand All @@ -72,8 +73,33 @@ void scatterRay(
glm::vec3 intersect,
glm::vec3 normal,
const Material &m,
thrust::default_random_engine &rng) {
thrust::default_random_engine &rng)
{
// TODO: implement this.
// A basic implementation of pure-diffuse shading will just call the
// calculateRandomDirectionInHemisphere defined above.
pathSegment.ray.origin = intersect + EPSILON * normal;
if (m.hasReflective)
{
// specular
glm::vec3 reflectedDir = glm::reflect(glm::normalize(pathSegment.ray.direction),
normal);
glm::vec3 reflectedColor = m.specular.color;
pathSegment.ray.direction = reflectedDir;
pathSegment.color *= reflectedColor;
}
else if (m.hasRefractive)
{

}
else {
// diffuse
glm::vec3 diffuseDir = glm::normalize(calculateRandomDirectionInHemisphere(normal, rng));
glm::vec3 diffuseColor = m.color;
pathSegment.ray.direction = diffuseDir;
pathSegment.color *= diffuseColor;
}

pathSegment.color = glm::clamp(pathSegment.color, glm::vec3(0.0f), glm::vec3(1.0f));
pathSegment.remainingBounces--;
}
15 changes: 4 additions & 11 deletions src/intersections.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// ray intersection functions
#pragma once

#include <glm/glm.hpp>
Expand All @@ -20,14 +21,6 @@ __host__ __device__ inline unsigned int utilhash(unsigned int a) {
}

// CHECKITOUT
/**
* Compute a point at parameter value `t` on ray `r`.
* Falls slightly short so that it doesn't intersect the object it's hitting.
*/
__host__ __device__ glm::vec3 getPointOnRay(Ray r, float t) {
return r.origin + (t - .0001f) * glm::normalize(r.direction);
}

/**
* Multiplies a mat4 and a vec4 and returns a vec3 clipped from the vec4.
*/
Expand Down Expand Up @@ -82,7 +75,7 @@ __host__ __device__ float boxIntersectionTest(Geom box, Ray r,
tmin_n = tmax_n;
outside = false;
}
intersectionPoint = multiplyMV(box.transform, glm::vec4(getPointOnRay(q, tmin), 1.0f));
intersectionPoint = multiplyMV(box.transform, glm::vec4(q.evaluate(tmin), 1.0f));
normal = glm::normalize(multiplyMV(box.invTranspose, glm::vec4(tmin_n, 0.0f)));
return glm::length(r.origin - intersectionPoint);
}
Expand Down Expand Up @@ -131,8 +124,8 @@ __host__ __device__ float sphereIntersectionTest(Geom sphere, Ray r,
t = max(t1, t2);
outside = false;
}

glm::vec3 objspaceIntersection = getPointOnRay(rt, t);
glm::vec3 objspaceIntersection = rt.evaluate(t);

intersectionPoint = multiplyMV(sphere.transform, glm::vec4(objspaceIntersection, 1.f));
normal = glm::normalize(multiplyMV(sphere.invTranspose, glm::vec4(objspaceIntersection, 0.f)));
Expand Down
13 changes: 13 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#include "preview.h"
#include <cstring>

// this is a global variable with internal linkage
// thus can only be seen and used in this file
static std::string startTimeString;

// For camera controls
Expand Down Expand Up @@ -31,6 +33,7 @@ int height;
//-------------------------------

int main(int argc, char** argv) {
// Used for naming image files
startTimeString = currentTimeString();

if (argc < 2) {
Expand Down Expand Up @@ -75,6 +78,7 @@ int main(int argc, char** argv) {
return 0;
}

// Save an image in Project3-CUDA-Path-Tracer/build/
void saveImage() {
float samples = iteration;
// output image file
Expand All @@ -90,6 +94,8 @@ void saveImage() {

std::string filename = renderState->imageName;
std::ostringstream ss;
// Every image will get a different filename based on current
// time on the author's machine
ss << filename << "." << startTimeString << "." << samples << "samp";
filename = ss.str();

Expand All @@ -98,8 +104,11 @@ void saveImage() {
//img.saveHDR(filename); // Save a Radiance HDR file
}

clock_t start, stop;

void runCuda() {
if (camchanged) {
start = clock();
iteration = 0;
Camera &cam = renderState->camera;
cameraPosition.x = zoom * sin(phi) * sin(theta);
Expand Down Expand Up @@ -142,6 +151,10 @@ void runCuda() {
saveImage();
pathtraceFree();
cudaDeviceReset();
stop = clock();
double timer_seconds = ((double)(stop - start)) / CLOCKS_PER_SEC;
std::cerr << "took " << timer_seconds << " seconds.\n";

exit(EXIT_SUCCESS);
}
}
Expand Down
Loading