From fbad54498677778ea8306125faaf93cac7a2c264 Mon Sep 17 00:00:00 2001 From: David Grosman Date: Sun, 9 Oct 2016 23:22:14 -0400 Subject: [PATCH 1/8] Commit Project 3 --- img/DOF.JPG | Bin 0 -> 126352 bytes img/RefrAndRefl.JPG | Bin 0 -> 69718 bytes img/RefrOnRefl.JPG | Bin 0 -> 70960 bytes scenes/cornell.txt | 10 +- scenes/cornellDOF.txt | 139 ++++++++++ src/CMakeLists.txt | 2 + src/interactions - Copy (2).h | 191 ++++++++++++++ src/interactions - Copy.h | 159 ++++++++++++ src/interactions.h | 203 ++++++++++----- src/intersections.h | 13 - src/main.cpp | 34 ++- src/pathtrace - Copy.cu | 420 +++++++++++++++++++++++++++++++ src/pathtrace.cu | 268 +++++++++++++------- src/pathtrace.h | 2 +- src/scene.cpp | 22 +- src/sceneStructs.h | 23 +- src/timer.cu | 462 ++++++++++++++++++++++++++++++++++ src/timer.h | 81 ++++++ src/utilities.cpp | 2 +- src/utilities.h | 2 +- 20 files changed, 1848 insertions(+), 185 deletions(-) create mode 100644 img/DOF.JPG create mode 100644 img/RefrAndRefl.JPG create mode 100644 img/RefrOnRefl.JPG create mode 100644 scenes/cornellDOF.txt create mode 100644 src/interactions - Copy (2).h create mode 100644 src/interactions - Copy.h create mode 100644 src/pathtrace - Copy.cu create mode 100644 src/timer.cu create mode 100644 src/timer.h diff --git a/img/DOF.JPG b/img/DOF.JPG new file mode 100644 index 0000000000000000000000000000000000000000..02f3b905fdde9221a710c8bf94f3ab0f86ffefad GIT binary patch literal 126352 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 E0@IuskpKVy literal 0 HcmV?d00001 diff --git a/img/RefrAndRefl.JPG b/img/RefrAndRefl.JPG new file mode 100644 index 0000000000000000000000000000000000000000..9b7b220206a830fa6c6844ac25f92b3bd4abd7a6 GIT binary patch literal 69718 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 P1!UeHoD5FAb1(h}3&)$# literal 0 HcmV?d00001 diff --git a/img/RefrOnRefl.JPG b/img/RefrOnRefl.JPG new file mode 100644 index 0000000000000000000000000000000000000000..0e79e67a7a217768e8bd03bca236e8be4c89aeff GIT binary patch literal 70960 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 literal 0 HcmV?d00001 diff --git a/scenes/cornell.txt b/scenes/cornell.txt index 83ff820..41c08a7 100644 --- a/scenes/cornell.txt +++ b/scenes/cornell.txt @@ -43,9 +43,9 @@ MATERIAL 4 RGB .98 .98 .98 SPECEX 0 SPECRGB .98 .98 .98 -REFL 1 -REFR 0 -REFRIOR 0 +REFL 0 +REFR 1 +REFRIOR 1.33 EMITTANCE 0 // Camera @@ -58,6 +58,8 @@ FILE cornell EYE 0.0 5 10.5 LOOKAT 0 5 0 UP 0 1 0 +LENS_RADIUS 0.0 +FOCAL_LENGTH 0.0 // Ceiling light @@ -114,4 +116,4 @@ sphere material 4 TRANS -1 4 -1 ROTAT 0 0 0 -SCALE 3 3 3 +SCALE 3 3 3 \ No newline at end of file diff --git a/scenes/cornellDOF.txt b/scenes/cornellDOF.txt new file mode 100644 index 0000000..28c30c3 --- /dev/null +++ b/scenes/cornellDOF.txt @@ -0,0 +1,139 @@ +// 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 0 +REFR 1 +REFRIOR 1.15 +EMITTANCE 0 + +// Specular white +MATERIAL 5 +RGB .98 .98 .98 +SPECEX 0 +SPECRGB .98 .98 .98 +REFL 1 +REFR 0 +REFRIOR 0 +EMITTANCE 0 + + +// Camera +CAMERA +RES 800 800 +FOVY 45 +ITERATIONS 5000 +DEPTH 16 +FILE cornell +EYE 0.0 5 10.5 +LOOKAT 0 5 0 +UP 0 1 0 +LENS_RADIUS 0.5 +FOCAL_LENGTH 5.5 + + +// 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 5 +TRANS -1 4 -1 +ROTAT 0 0 0 +SCALE 3 3 3 + + +// Sphere +OBJECT 7 +sphere +material 4 +TRANS -1 4 4 +ROTAT 0 0 0 +SCALE 3 3 3 \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a1cb3fb..cef0957 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -15,6 +15,8 @@ set(SOURCE_FILES "preview.cpp" "utilities.cpp" "utilities.h" + "timer.cu" + "timer.h" ) cuda_add_library(src diff --git a/src/interactions - Copy (2).h b/src/interactions - Copy (2).h new file mode 100644 index 0000000..9b7e65e --- /dev/null +++ b/src/interactions - Copy (2).h @@ -0,0 +1,191 @@ +#pragma once + +#include "intersections.h" + +// CHECKITOUT +/** +* Computes a cosine-weighted random direction in a hemisphere. +* Used for diffuse lighting. +*/ +__host__ __device__ +glm::vec3 computeDiffuseDirection( +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__ +glm::vec3 computeReflectiveDirection( +const glm::vec3& normal, const glm::vec3& incident) +{ + const float cosI = glm::dot(normal, incident); + return incident - 2.0f * cosI * normal; +} + +__host__ __device__ +glm::vec3 computeRefractiveDirection( +const glm::vec3& normal, const glm::vec3& incident, +const float ni, const float nt) +{ + // Uses Snell's Law: + const float n = ni / nt; + const float cosI = -glm::dot(normal, incident); + float sinT2 = n * n * (1.0f - cosI * cosI); + if (sinT2 > 1.0) { return computeReflectiveDirection(normal, incident); } //Hack + const float cosT = sqrt(1.0 - sinT2); + return n * incident + (n * cosI - cosT) * normal; +} + +__host__ __device__ +float computeReflectance( +const glm::vec3& normal, const glm::vec3& incident, +const float ni, const float nt) +{ + const float cosI = -glm::dot(normal, incident); + float R0 = (ni - nt) / (ni + nt); + R0 *= R0; + return R0 + (1 - R0) * powf(1 - cosI, 5); +} + +/** +* Scatter a ray with some probabilities according to the material properties. +* For example, a diffuse surface scatters in a cosine-weighted hemisphere. +* A perfect specular surface scatters in the reflected ray direction. +* In order to apply multiple effects to one surface, probabilistically choose +* between them. +* +* 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). +* +* - 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 +* by its probability (0.5), to counteract the chance (0.5) of the branch +* being taken. +* - This way is inefficient, but serves as a good starting point - it +* converges slowly, especially for pure-diffuse or pure-specular. +* - Pick the split based on the intensity of each material color, and divide +* branch result by that branch's probability (whatever probability you use). +* +* This method applies its changes to the Ray parameter `ray` in place. +* It also modifies the color `color` of the ray in place. +* +* You may need to change the parameter list for your purposes! +*/ +__host__ __device__ +void scatterRay( +PathSegment & pathSegment, +glm::vec3 intersect, +glm::vec3 normal, +const Material &m, +thrust::default_random_engine &rng) +{ + const float MY_EPSILON = 1e-3f; + + Ray& outRay = pathSegment.ray; + glm::vec3& outColor = pathSegment.color; + + const bool isInwardsRay = (glm::dot(normal, outRay.direction) < 0.0f); + const float pathDir = isInwardsRay ? 1 : -1; + + if (!m.hasReflective && !m.hasRefractive) // Diffuse + { + outRay.direction = computeDiffuseDirection(normal, rng); + outColor *= glm::abs(glm::dot(outRay.direction, normal)) * m.color; + outRay.origin = intersect + pathDir * normal * MY_EPSILON; + } + else + { + float ni = 1.0f, nt = 1.0f; + { + if (isInwardsRay) + { + ni = 1.0f; + nt = m.indexOfRefraction; + } + else + { + ni = m.indexOfRefraction; + nt = 1.0f; + } + } + + float reflectance = computeReflectance(normal, outRay.direction, ni, nt); + if (m.hasReflective) + { + outRay.direction = glm::reflect(pathSegment.ray.direction, normal); + outColor *= reflectance* m.color; + outRay.origin = intersect + pathDir * normal * MY_EPSILON; + } + else if (m.hasRefractive) + { + outRay.direction = computeRefractiveDirection(normal, pathSegment.ray.direction, ni, nt); + outColor *= (1.0f - reflectance) * m.color; + outRay.origin = intersect - pathDir * normal * MY_EPSILON; + //printf("(%f,%f,%f)", outColor.r, outColor.g, outColor.b); + } + } + + + + + +} + + +//__host__ __device__ +//void scatterRay( +//Ray& ray, +//glm::vec3& color, +//glm::vec3 intersect, +//glm::vec3 normal, +//const Material &m, +//thrust::default_random_engine &rng) +//{ +// float precision_fix = 1e-4f; +// +// // TODO: partial? +// if (m.hasReflective < 0.5f) +// { +// // Diffuse only +// ray.direction = calculateRandomDirectionInHemisphere(normal, rng); +// ray.origin = intersect + precision_fix * normal; +// color *= m.color; +// } +// else +// { +// // Reflection only +// ray.direction = glm::reflect(ray.direction, normal); +// ray.origin = intersect + precision_fix * normal; +// color *= m.color; +// } +//} \ No newline at end of file diff --git a/src/interactions - Copy.h b/src/interactions - Copy.h new file mode 100644 index 0000000..a13117e --- /dev/null +++ b/src/interactions - Copy.h @@ -0,0 +1,159 @@ +#pragma once + +#include "intersections.h" + +// CHECKITOUT +/** + * Computes a cosine-weighted random direction in a hemisphere. + * Used for diffuse lighting. + */ +__host__ __device__ +glm::vec3 computeDiffuseDirection( +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__ +glm::vec3 computeReflectiveDirection( +const glm::vec3& normal, const glm::vec3& incident) +{ + const float cosI = glm::dot(normal, incident); + return incident - 2.0f * cosI * normal; +} + +__host__ __device__ +glm::vec3 computeRefractiveDirection( +const glm::vec3& normal, const glm::vec3& incident, +const float ni, const float nt) +{ + // Uses Snell's Law: + const float n = ni / nt; + const float cosI = -glm::dot(normal, incident); + float sinT2 = n * n * (1.0f - cosI * cosI); + if (sinT2 > 1.0) { return computeReflectiveDirection(normal, incident); } //Hack + const float cosT = sqrt(1.0 - sinT2); + return n * incident + (n * cosI - cosT) * normal; +} + +__host__ __device__ +float computeReflectance( +const glm::vec3& normal, const glm::vec3& incident, +const float ni, const float nt) +{ + // From http://graphics.stanford.edu/courses/cs148-10-summer/docs/2006--degreve--reflection_refraction.pdf + const float n = ni / nt; + const float cosI = -glm::dot(normal, incident); + float sinT2 = n * n * (1.0f - cosI * cosI); + if (sinT2 > 1.0) { return 1.0f; } //Hack + const float cosT = sqrt(1.0 - sinT2); + const float rOrth = (ni * cosI - nt * cosT) / (ni * cosI + nt * cosT); + const float rPar = (nt * cosI - ni * cosT) / (nt * cosI + ni * cosT); + return (rOrth * rOrth + rPar * rPar) / 2.0f; +} + +/** + * Scatter a ray with some probabilities according to the material properties. + * For example, a diffuse surface scatters in a cosine-weighted hemisphere. + * A perfect specular surface scatters in the reflected ray direction. + * In order to apply multiple effects to one surface, probabilistically choose + * between them. + * + * 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). + * + * - 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 + * by its probability (0.5), to counteract the chance (0.5) of the branch + * being taken. + * - This way is inefficient, but serves as a good starting point - it + * converges slowly, especially for pure-diffuse or pure-specular. + * - Pick the split based on the intensity of each material color, and divide + * branch result by that branch's probability (whatever probability you use). + * + * This method applies its changes to the Ray parameter `ray` in place. + * It also modifies the color `color` of the ray in place. + * + * You may need to change the parameter list for your purposes! + */ +__host__ __device__ +void scatterRay( + PathSegment & pathSegment, + glm::vec3 intersect, + glm::vec3 normal, + glm::vec3 eye, + const Material &m, + thrust::default_random_engine &rng) +{ + Ray& outRay = pathSegment.ray; + glm::vec3& outColor = pathSegment.color; + + const bool isInwardsRay = (glm::dot(normal, outRay.direction) < 0.0f); + if (!m.hasReflective && !m.hasRefractive) // Diffuse + { + outRay.direction = computeDiffuseDirection(normal, rng); + pathSegment.color *= glm::abs(glm::dot(outRay.direction, normal)) * m.color; + } + else + { + float ni = 1.0f, nt = 1.0f; + { + if (isInwardsRay) + { + ni = 1.0f; + nt = m.indexOfRefraction; + } + else + { + ni = m.indexOfRefraction; + nt = 1.0f; + } + } + + float reflectance = computeReflectance( normal, outRay.direction, ni, nt ); + if (m.hasReflective) + { + outRay.direction = glm::reflect(pathSegment.ray.direction, normal); + //pathSegment.color *= m.color; + pathSegment.color *= glm::abs(glm::dot(outRay.direction, normal)) * m.color; + } + else if (m.hasRefractive) + { + outRay.direction = computeRefractiveDirection(normal, pathSegment.ray.direction, ni, nt); + outColor *= m.color * (1.0f - reflectance); + } + } + + float pathDir = isInwardsRay ? -1 : 1; + + const float MY_EPSILON = 1e-4f; + outRay.origin = intersect + pathDir * normal * MY_EPSILON; +} diff --git a/src/interactions.h b/src/interactions.h index 5ce3628..9b6a965 100644 --- a/src/interactions.h +++ b/src/interactions.h @@ -1,79 +1,158 @@ #pragma once +#include "timer.h" #include "intersections.h" // CHECKITOUT /** - * Computes a cosine-weighted random direction in a hemisphere. - * Used for diffuse lighting. - */ +* 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 computeDiffuseDirection( +glm::vec3& normal, PRNG& rng) { - float up = sqrt(u01(rng)); // cos(theta) - float over = sqrt(1 - up * up); // sin(theta) - float around = u01(rng) * TWO_PI; + float up = sqrt( rng.getNextVal01() ); // cos(theta) + float over = sqrt(1 - up * up); // sin(theta) + float around = rng.getNextVal01() * 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. + // 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); - } + 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)); + // 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; + return up * normal + + cos(around) * over * perpendicularDirection1 + + sin(around) * over * perpendicularDirection2; +} + +__host__ __device__ +glm::vec3 computeReflectiveDirection( +const glm::vec3& normal, const glm::vec3& incident) +{ + const float cosI = glm::dot(normal, incident); + return incident - 2.0f * cosI * normal; +} + +__host__ __device__ +glm::vec3 computeRefractiveDirection( +const glm::vec3& normal, const glm::vec3& incident, +const float ni, const float nt) +{ + // Uses Snell's Law: + const float n = ni / nt; + const float cosI = -glm::dot(normal, incident); + float sinT2 = n * n * (1.0f - cosI * cosI); + if (sinT2 > 1.0) { return computeReflectiveDirection(normal, incident); } //Hack + const float cosT = sqrt(1.0 - sinT2); + return n * incident + (n * cosI - cosT) * normal; +} + +__host__ __device__ +float computeReflectance( +const glm::vec3& normal, const glm::vec3& incident, +const float ni, const float nt) +{ + // According to Schlick's model, the specular reflection + // coefficient R can be approximated by + const float cosI = -glm::dot(normal, incident); + const float sqrtR0 = (ni - nt) / (ni + nt); + const float R0 = sqrtR0 * sqrtR0; + return R0 + (1 - R0) * powf(1 - cosI, 5); } /** - * Scatter a ray with some probabilities according to the material properties. - * For example, a diffuse surface scatters in a cosine-weighted hemisphere. - * A perfect specular surface scatters in the reflected ray direction. - * In order to apply multiple effects to one surface, probabilistically choose - * between them. - * - * 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). - * - * - 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 - * by its probability (0.5), to counteract the chance (0.5) of the branch - * being taken. - * - This way is inefficient, but serves as a good starting point - it - * converges slowly, especially for pure-diffuse or pure-specular. - * - Pick the split based on the intensity of each material color, and divide - * branch result by that branch's probability (whatever probability you use). - * - * This method applies its changes to the Ray parameter `ray` in place. - * It also modifies the color `color` of the ray in place. - * - * You may need to change the parameter list for your purposes! - */ +* Scatter a ray with some probabilities according to the material properties. +* For example, a diffuse surface scatters in a cosine-weighted hemisphere. +* A perfect specular surface scatters in the reflected ray direction. +* In order to apply multiple effects to one surface, probabilistically choose +* between them. +* +* 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). +* +* - 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 +* by its probability (0.5), to counteract the chance (0.5) of the branch +* being taken. +* - This way is inefficient, but serves as a good starting point - it +* converges slowly, especially for pure-diffuse or pure-specular. +* - Pick the split based on the intensity of each material color, and divide +* branch result by that branch's probability (whatever probability you use). +* +* This method applies its changes to the Ray parameter `ray` in place. +* It also modifies the color `color` of the ray in place. +* +* You may need to change the parameter list for your purposes! +*/ __host__ __device__ void scatterRay( - PathSegment & pathSegment, - glm::vec3 intersect, - glm::vec3 normal, - const Material &m, - thrust::default_random_engine &rng) { - // TODO: implement this. - // A basic implementation of pure-diffuse shading will just call the - // calculateRandomDirectionInHemisphere defined above. -} +PathSegment & pathSegment, +glm::vec3 intersect, +glm::vec3 normal, +const Material &m, +PRNG& rng) +{ + const float MY_EPSILON = 1e-3f; + + Ray& outRay = pathSegment.ray; + glm::vec3& outColor = pathSegment.color; + + const bool isInwardsRay = (glm::dot(normal, outRay.direction) < 0.0f); + const float pathDir = isInwardsRay ? 1 : -1; + + outRay.origin = intersect + pathDir * normal * MY_EPSILON; + if (!m.hasReflective && !m.hasRefractive) // Diffuse + { + outRay.direction = computeDiffuseDirection(normal, rng); + outColor *= glm::abs(glm::dot(outRay.direction, normal)) * m.color; + } + else + { + float ni = 1.0f, nt = 1.0f; + { + if (isInwardsRay) + { + ni = 1.0f; + nt = m.indexOfRefraction; + } + else + { + ni = m.indexOfRefraction; + nt = 1.0f; + } + } + + float reflectance = computeReflectance(normal, outRay.direction, ni, nt); + if (m.hasReflective) + { + outRay.direction = glm::reflect(pathSegment.ray.direction, normal); + outColor *= reflectance* m.color; + + } + else if (m.hasRefractive) + { + outRay.direction = computeRefractiveDirection(normal, pathSegment.ray.direction, ni, nt); + outColor *= (1.0f - reflectance) * m.color; + outRay.origin = intersect - pathDir * normal * MY_EPSILON; + } + } +} \ No newline at end of file diff --git a/src/intersections.h b/src/intersections.h index 6f23872..7c2ccc1 100644 --- a/src/intersections.h +++ b/src/intersections.h @@ -6,19 +6,6 @@ #include "sceneStructs.h" #include "utilities.h" -/** - * Handy-dandy hash function that provides seeds for random number generation. - */ -__host__ __device__ inline unsigned int utilhash(unsigned int a) { - a = (a + 0x7ed55d16) + (a << 12); - a = (a ^ 0xc761c23c) ^ (a >> 19); - a = (a + 0x165667b1) + (a << 5); - a = (a + 0xd3a2646c) ^ (a << 9); - a = (a + 0xfd7046c5) + (a << 3); - a = (a ^ 0xb55a4f09) ^ (a >> 16); - return a; -} - // CHECKITOUT /** * Compute a point at parameter value `t` on ray `r`. diff --git a/src/main.cpp b/src/main.cpp index fe8e85e..2d29399 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,7 +1,10 @@ #include "main.h" #include "preview.h" +#include "timer.h" #include +#include "utilities.h" + static std::string startTimeString; // For camera controls @@ -20,17 +23,25 @@ glm::vec3 cameraPosition; glm::vec3 ogLookAt; // for recentering the camera Scene *scene; +SceneOptions sceneOptions; RenderState *renderState; int iteration; int width; int height; + + + +//------------------------------- +//------------------------------- + //------------------------------- //-------------MAIN-------------- //------------------------------- -int main(int argc, char** argv) { +int main(int argc, char** argv) +{ startTimeString = currentTimeString(); if (argc < 2) { @@ -68,10 +79,12 @@ int main(int argc, char** argv) { // Initialize CUDA and GL components init(); + Timer::initializeTimer(); // GLFW main loop mainLoop(); - + + PRNGenerator::shutdownSystem(); return 0; } @@ -122,9 +135,13 @@ void runCuda() { // Map OpenGL buffer object for writing from CUDA on a single GPU // No data is moved (Win & Linux). When mapped to CUDA, OpenGL should not use this buffer - if (iteration == 0) { + if (iteration == 0) + { pathtraceFree(); pathtraceInit(scene); + + const int NUM_RANDOM_SIZE = 1 << 20; + PRNGenerator::initializeSystem(PRNGenerator::Thrust, NUM_RANDOM_SIZE); } if (iteration < renderState->iterations) { @@ -132,9 +149,10 @@ void runCuda() { iteration++; cudaGLMapBufferObject((void**)&pbo_dptr, pbo); + Timer::resetTimer(true); // execute the kernel - int frame = 0; - pathtrace(pbo_dptr, frame, iteration); + pathtrace(pbo_dptr, sceneOptions, iteration); + Timer::printTimer(NULL, 1.0f); // unmap buffer object cudaGLUnmapBufferObject(pbo); @@ -156,6 +174,12 @@ void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods case GLFW_KEY_S: saveImage(); break; + case GLFW_KEY_M: + sceneOptions.sortPathsByMaterial = !sceneOptions.sortPathsByMaterial; + break; + case GLFW_KEY_C: + sceneOptions.iterToCacheFirstBounces = iteration + 1; + break; case GLFW_KEY_SPACE: camchanged = true; renderState = &scene->state; diff --git a/src/pathtrace - Copy.cu b/src/pathtrace - Copy.cu new file mode 100644 index 0000000..9cff7ee --- /dev/null +++ b/src/pathtrace - Copy.cu @@ -0,0 +1,420 @@ +#include +#include +#include +#include +#include +#include + +#include "sceneStructs.h" +#include "scene.h" +#include "glm/glm.hpp" +#include "glm/gtx/norm.hpp" +#include "utilities.h" +#include "pathtrace.h" +#include "intersections.h" +#include "interactions.h" + +#define ERRORCHECK 1 + +#define FILENAME (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) +#define checkCUDAError(msg) checkCUDAErrorFn(msg, FILENAME, __LINE__) +void checkCUDAErrorFn(const char *msg, const char *file, int line) { +#if ERRORCHECK + cudaDeviceSynchronize(); + cudaError_t err = cudaGetLastError(); + if (cudaSuccess == err) { + return; + } + + fprintf(stderr, "CUDA error"); + if (file) { + fprintf(stderr, " (%s:%d)", file, line); + } + fprintf(stderr, ": %s: %s\n", msg, cudaGetErrorString(err)); +# ifdef _WIN32 + getchar(); +# endif + exit(EXIT_FAILURE); +#endif +} + +__host__ __device__ +thrust::default_random_engine makeSeededRandomEngine(int iter, int index, int depth) { + int h = utilhash((1 << 31) | (depth << 22) | iter) ^ utilhash(index); + return thrust::default_random_engine(h); +} + +//Kernel that writes the image to the OpenGL PBO directly. +__global__ void sendImageToPBO(uchar4* pbo, glm::ivec2 resolution, + int iter, glm::vec3* image) { + int x = (blockIdx.x * blockDim.x) + threadIdx.x; + int y = (blockIdx.y * blockDim.y) + threadIdx.y; + + if (x < resolution.x && y < resolution.y) { + int index = x + (y * resolution.x); + glm::vec3 pix = image[index]; + + glm::ivec3 color; + color.x = glm::clamp((int) (pix.x / iter * 255.0), 0, 255); + color.y = glm::clamp((int) (pix.y / iter * 255.0), 0, 255); + color.z = glm::clamp((int) (pix.z / iter * 255.0), 0, 255); + + // Each thread writes one pixel location in the texture (textel) + pbo[index].w = 0; + pbo[index].x = color.x; + pbo[index].y = color.y; + pbo[index].z = color.z; + } +} + +static Scene * hst_scene = NULL; +static glm::vec3 * dev_image = NULL; +static Geom * dev_geoms = NULL; +static Material * dev_materials = NULL; +static PathSegment * dev_paths = NULL; +static ShadeableIntersection * dev_intersections = NULL; +// TODO: static variables for device memory, any extra info you need, etc +// ... + +void pathtraceInit(Scene *scene) { + hst_scene = scene; + const Camera &cam = hst_scene->state.camera; + const int pixelcount = cam.resolution.x * cam.resolution.y; + + cudaMalloc(&dev_image, pixelcount * sizeof(glm::vec3)); + cudaMemset(dev_image, 0, pixelcount * sizeof(glm::vec3)); + + cudaMalloc(&dev_paths, pixelcount * sizeof(PathSegment)); + + cudaMalloc(&dev_geoms, scene->geoms.size() * sizeof(Geom)); + cudaMemcpy(dev_geoms, scene->geoms.data(), scene->geoms.size() * sizeof(Geom), cudaMemcpyHostToDevice); + + cudaMalloc(&dev_materials, scene->materials.size() * sizeof(Material)); + cudaMemcpy(dev_materials, scene->materials.data(), scene->materials.size() * sizeof(Material), cudaMemcpyHostToDevice); + + cudaMalloc(&dev_intersections, pixelcount * sizeof(ShadeableIntersection)); + cudaMemset(dev_intersections, 0, pixelcount * sizeof(ShadeableIntersection)); + + // TODO: initialize any extra device memeory you need + + checkCUDAError("pathtraceInit"); +} + +void pathtraceFree() { + cudaFree(dev_image); // no-op if dev_image is null + cudaFree(dev_paths); + cudaFree(dev_geoms); + cudaFree(dev_materials); + cudaFree(dev_intersections); + // TODO: clean up any extra device memory you created + + checkCUDAError("pathtraceFree"); +} + +/** +* Generate PathSegments with rays from the camera through the screen into the +* scene, which is the first bounce of rays. +* +* Antialiasing - add rays for sub-pixel sampling +* motion blur - jitter rays "in time" +* lens effect - jitter ray origin positions based on a lens +*/ +__global__ void generateRayFromCamera(Camera cam, int iter, int traceDepth, PathSegment* pathSegments) +{ + int x = (blockIdx.x * blockDim.x) + threadIdx.x; + int y = (blockIdx.y * blockDim.y) + threadIdx.y; + + if (x < cam.resolution.x && y < cam.resolution.y) { + int index = x + (y * cam.resolution.x); + PathSegment & segment = pathSegments[index]; + + segment.ray.origin = cam.position; + segment.color = glm::vec3(1.0f, 1.0f, 1.0f); + + // 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.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. +__global__ void computeIntersections( + int depth + , int num_paths + , PathSegment * pathSegments + , Geom * geoms + , int geoms_size + , ShadeableIntersection * intersections + ) +{ + int path_index = blockIdx.x * blockDim.x + threadIdx.x; + + if (path_index < num_paths) + { + PathSegment pathSegment = pathSegments[path_index]; + if (pathSegment.remainingBounces <= 0) + { + return; + } + float t; + glm::vec3 intersect_point; + glm::vec3 normal; + float t_min = FLT_MAX; + int hit_geom_index = -1; + bool outside = true; + + glm::vec3 tmp_intersect; + glm::vec3 tmp_normal; + + // naive parse through global geoms + + for (int i = 0; i < geoms_size; i++) + { + Geom & geom = geoms[i]; + + if (geom.type == CUBE) + { + t = boxIntersectionTest(geom, pathSegment.ray, tmp_intersect, tmp_normal, outside); + } + else if (geom.type == SPHERE) + { + t = sphereIntersectionTest(geom, pathSegment.ray, tmp_intersect, tmp_normal, outside); + } + // TODO: add more intersection tests here... triangle? metaball? CSG? + + // Compute the minimum t from the intersection tests to determine what + // scene geometry object was hit first. + if (t > 0.0f && t_min > t) + { + t_min = t; + hit_geom_index = i; + intersect_point = tmp_intersect; + normal = tmp_normal; + } + } + + if (hit_geom_index == -1) + { + intersections[path_index].t = -1.0f; + } + else + { + //The ray hits something + intersections[path_index].t = t_min; + intersections[path_index].materialId = geoms[hit_geom_index].materialid; + intersections[path_index].intersectionPoint = intersect_point; + intersections[path_index].surfaceNormal = normal; + } + } +} + +// LOOK: "fake" shader demonstrating what you might do with the info in +// a ShadeableIntersection, as well as how to use thrust's random number +// generator. Observe that since the thrust random number generator basically +// adds "noise" to the iteration, the image should start off noisy and get +// cleaner as more iterations are computed. +// +// 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. +__global__ void shadeScene ( + int iter + , int num_paths + , ShadeableIntersection * shadeableIntersections + , PathSegment * pathSegments + , Material * materials + ) +{ + int idx = blockIdx.x * blockDim.x + threadIdx.x; + if (idx < num_paths) + { + const ShadeableIntersection& intersection = shadeableIntersections[idx]; + PathSegment& pathSegment = pathSegments[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) + { + pathSegment.color *= (materialColor * material.emittance); + pathSegment.remainingBounces = 0; // Terminate path. + } + else + { + glm::vec3 eyeV (0.f, 10.0f, 0.f); + eyeV -= intersection.intersectionPoint; + scatterRay( + pathSegments[idx], + intersection.intersectionPoint, intersection.surfaceNormal, + material, 0,0,0); + --pathSegment.remainingBounces; + } + } + else + { + // 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. + pathSegment.color = glm::vec3(0.0f); + pathSegments[idx].remainingBounces = 0; + } + } +} + +// Add the current iteration's output to the overall image +__global__ void finalGather(int nPaths, glm::vec3 * image, PathSegment * iterationPaths) +{ + int index = (blockIdx.x * blockDim.x) + threadIdx.x; + + if (index < nPaths) + { + PathSegment iterationPath = iterationPaths[index]; + image[iterationPath.pixelIndex] += iterationPath.color; + } +} + +struct is_path_terminated +{ + __host__ __device__ + bool operator()(const PathSegment& path) + { + return path.remainingBounces > 0; + } +}; + +/** + * 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; + + // 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); + + // 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); + checkCUDAError("generate camera ray"); + + int depth = 0; + PathSegment* dev_path_end = dev_paths + pixelcount; + int num_paths = dev_path_end - dev_paths; + + // --- PathSegment Tracing Stage --- + // Shoot ray into scene, bounce between objects, push shading chunks + + 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: compare between directly shading the path segments and shading + // path segments that have been reshuffled to be contiguous in memory. + + shadeScene << > > ( + iter, + num_paths, + dev_intersections, + dev_paths, + dev_materials + ); + + PathSegment* end = thrust::partition(thrust::device, dev_paths, dev_paths + num_paths, is_path_terminated()); + num_paths = std::distance(dev_paths, end); + if (num_paths == 0) { + iterationComplete = true; + num_paths = std::distance(dev_paths, dev_path_end); + depth = 0; + } + } + + // Assemble this iteration and apply it to the image + dim3 numBlocksPixels = (pixelcount + blockSize1d - 1) / blockSize1d; + finalGather<<>>(num_paths, dev_image, dev_paths); + + /////////////////////////////////////////////////////////////////////////// + + // 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"); +} diff --git a/src/pathtrace.cu b/src/pathtrace.cu index c1ec122..7b36d44 100644 --- a/src/pathtrace.cu +++ b/src/pathtrace.cu @@ -2,7 +2,11 @@ #include #include #include -#include + +#include +#include +#include +#include #include #include "sceneStructs.h" @@ -13,6 +17,8 @@ #include "pathtrace.h" #include "intersections.h" #include "interactions.h" +#include "timer.h" +#include "utilities.h" #define ERRORCHECK 1 @@ -38,12 +44,6 @@ void checkCUDAErrorFn(const char *msg, const char *file, int line) { #endif } -__host__ __device__ -thrust::default_random_engine makeSeededRandomEngine(int iter, int index, int depth) { - int h = utilhash((1 << 31) | (depth << 22) | iter) ^ utilhash(index); - return thrust::default_random_engine(h); -} - //Kernel that writes the image to the OpenGL PBO directly. __global__ void sendImageToPBO(uchar4* pbo, glm::ivec2 resolution, int iter, glm::vec3* image) { @@ -73,6 +73,7 @@ static Geom * dev_geoms = NULL; static Material * dev_materials = NULL; static PathSegment * dev_paths = NULL; static ShadeableIntersection * dev_intersections = NULL; +static ShadeableIntersection * dev_firstIntersections = NULL; // TODO: static variables for device memory, any extra info you need, etc // ... @@ -95,14 +96,20 @@ void pathtraceInit(Scene *scene) { cudaMalloc(&dev_intersections, pixelcount * sizeof(ShadeableIntersection)); cudaMemset(dev_intersections, 0, pixelcount * sizeof(ShadeableIntersection)); + cudaMalloc(&dev_firstIntersections, pixelcount * sizeof(ShadeableIntersection)); + cudaMemset(dev_firstIntersections, 0, pixelcount * sizeof(ShadeableIntersection)); + // TODO: initialize any extra device memeory you need checkCUDAError("pathtraceInit"); } -void pathtraceFree() { +void pathtraceFree() +{ + checkCUDAError("pathtraceFree"); cudaFree(dev_image); // no-op if dev_image is null cudaFree(dev_paths); + checkCUDAError("pathtraceFree"); cudaFree(dev_geoms); cudaFree(dev_materials); cudaFree(dev_intersections); @@ -119,23 +126,42 @@ void pathtraceFree() { * motion blur - jitter rays "in time" * lens effect - jitter ray origin positions based on a lens */ -__global__ void generateRayFromCamera(Camera cam, int iter, int traceDepth, PathSegment* pathSegments) +__global__ void generateRayFromCamera( + Camera cam, int iter, int traceDepth, PathSegment* pathSegments, + PRNG prng) { int x = (blockIdx.x * blockDim.x) + threadIdx.x; int y = (blockIdx.y * blockDim.y) + threadIdx.y; - if (x < cam.resolution.x && y < cam.resolution.y) { + if (x < cam.resolution.x && y < cam.resolution.y) + { int index = x + (y * cam.resolution.x); PathSegment & segment = pathSegments[index]; + segment.color = glm::vec3(1.0f, 1.0f, 1.0f); segment.ray.origin = cam.position; - segment.color = glm::vec3(1.0f, 1.0f, 1.0f); - - // 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) - ); + - 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) + ); + + if (cam.lensRadius > 0) // Use depth of field + { + // Set up the RNG + prng.setSeed(iter, x * y, 0); + + const float lensRdmRadius = cam.lensRadius * prng.getNextVal01(); + const float lensRdmTheta = 2 * PI * prng.getNextVal01(); + + const float focalT = cam.focalLength * cam.view.z / segment.ray.direction.z; + const glm::vec3 focusPoint = segment.ray.origin + focalT * segment.ray.direction; + + segment.ray.origin = cam.position + + cam.right * lensRdmRadius * cos(lensRdmTheta) + - cam.up * lensRdmRadius * sin(lensRdmTheta); + segment.ray.direction = glm::normalize(focusPoint - segment.ray.origin); + } + segment.pixelIndex = index; segment.remainingBounces = traceDepth; @@ -200,13 +226,17 @@ __global__ void computeIntersections( if (hit_geom_index == -1) { + pathSegment.intersectionIndex = -1; intersections[path_index].t = -1.0f; } else { + pathSegment.intersectionIndex = path_index; + //The ray hits something intersections[path_index].t = t_min; intersections[path_index].materialId = geoms[hit_geom_index].materialid; + intersections[path_index].intersectionPoint = intersect_point; intersections[path_index].surfaceNormal = normal; } } @@ -218,49 +248,60 @@ __global__ void computeIntersections( // adds "noise" to the iteration, the image should start off noisy and get // cleaner as more iterations are computed. // -// 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 ( +// 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. +__global__ void shadeScene ( int iter , int num_paths , ShadeableIntersection * shadeableIntersections , PathSegment * pathSegments , Material * materials + , PRNG prng ) { 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); + // Set up the RNG + // LOOK: this is how you use thrust's RNG! Please look at + // makeSeededRandomEngine as well. + prng.setSeed(iter, idx, num_paths); + + const ShadeableIntersection& intersection = shadeableIntersections[idx]; + PathSegment& pathSegment = pathSegments[idx]; + if (intersection.t > 0.0f) // if the intersection exists... + { 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); + if (material.emittance > 0.0f) + { + pathSegment.color *= (materialColor * material.emittance); + pathSegment.remainingBounces = 0; // Terminate path. } - // 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 + else + { + scatterRay( + pathSegments[idx], + intersection.intersectionPoint, intersection.surfaceNormal, + material, prng); + --pathSegment.remainingBounces; } - // 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); + } + else + { + // 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. + pathSegment.color = glm::vec3(0.0f); + pathSegments[idx].remainingBounces = 0; } } } @@ -277,11 +318,46 @@ __global__ void finalGather(int nPaths, glm::vec3 * image, PathSegment * iterati } } +struct IsPathValid +{ + __host__ __device__ + bool operator()(const PathSegment& path) + { + return path.remainingBounces > 0; + } +}; + +struct SortByMaterialId +{ +public: + + SortByMaterialId(ShadeableIntersection* intersections) : dev_intersections(intersections) + {} + + __host__ __device__ + bool operator()(const PathSegment& pathLhs, const PathSegment& pathRhs) + { + return operator()(dev_intersections[pathLhs.intersectionIndex], dev_intersections[pathRhs.intersectionIndex]); + } + + __host__ __device__ + bool operator()(const ShadeableIntersection& intersectLhs, const ShadeableIntersection& intersectRhs) + { + return intersectLhs.materialId < intersectRhs.materialId; + } + +public: + + ShadeableIntersection* dev_intersections; +}; + + /** * 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) { +void pathtrace(uchar4 *pbo, const SceneOptions& sceneOptions, 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; @@ -325,57 +401,81 @@ void pathtrace(uchar4 *pbo, int frame, int iter) { // for you. // TODO: perform one iteration of path tracing - - generateRayFromCamera <<>>(cam, iter, traceDepth, dev_paths); + checkCUDAError("generate camera ray"); + PRNG prng(PRNGenerator::getType(), PRNGenerator::getNumVals(), PRNGenerator::getVals()); + checkCUDAError("generate camera ray"); + generateRayFromCamera << > >(cam, iter, traceDepth, dev_paths, prng); checkCUDAError("generate camera ray"); int depth = 0; PathSegment* dev_path_end = dev_paths + pixelcount; int num_paths = dev_path_end - dev_paths; + Timer::playTimer(); // --- PathSegment Tracing Stage --- // Shoot ray into scene, bounce between objects, push shading chunks + bool iterationComplete = false; + while (!iterationComplete) + { - 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)); + dim3 numblocksPathSegmentTracing = (num_paths + blockSize1d - 1) / blockSize1d; + if (iter <= sceneOptions.iterToCacheFirstBounces || depth != 0) + { + // tracing + computeIntersections << > > ( + depth + , num_paths + , dev_paths + , dev_geoms + , hst_scene->geoms.size() + , dev_intersections + ); + checkCUDAError("trace one bounce"); + cudaDeviceSynchronize(); + + if (iter == sceneOptions.iterToCacheFirstBounces && depth == 0) + { + cudaMemcpy(dev_firstIntersections, dev_intersections, pixelcount * sizeof(ShadeableIntersection), cudaMemcpyDeviceToDevice); + } + } + else // iter > sceneOptions.iterToCacheFirstBounces && depth == 0 + { + cudaMemcpy(dev_intersections, dev_firstIntersections, pixelcount * sizeof(ShadeableIntersection), cudaMemcpyDeviceToDevice); + } + + // TODO: compare between directly shading the path segments and shading + // path segments that have been reshuffled to be contiguous in memory. + /*if (sceneOptions.sortPathsByMaterial) + { + thrust::device_vector dv_in_paths(dev_paths, dev_paths + num_paths); + thrust::stable_sort(dv_in_paths.begin(), dv_in_paths.end(), SortByMaterialId(dev_intersections)); + + thrust::device_vector dv_in_intersects(dev_intersections, dev_intersections + num_paths); + thrust::stable_sort(dv_in_intersects.begin(), dv_in_intersects.end(), SortByMaterialId(dev_intersections)); + }*/ + + shadeScene << > > ( + iter, + num_paths, + dev_intersections, + dev_paths, + dev_materials, + prng + ); + + PathSegment* end = thrust::partition(thrust::device, dev_paths, dev_paths + num_paths, IsPathValid()); + num_paths = std::distance(dev_paths, end); + if (num_paths == 0) + { + iterationComplete = true; + num_paths = std::distance(dev_paths, dev_path_end); + } + depth++; + } + Timer::pauseTimer(); // Assemble this iteration and apply it to the image dim3 numBlocksPixels = (pixelcount + blockSize1d - 1) / blockSize1d; finalGather<<>>(num_paths, dev_image, dev_paths); diff --git a/src/pathtrace.h b/src/pathtrace.h index 1241227..7b4b0ce 100644 --- a/src/pathtrace.h +++ b/src/pathtrace.h @@ -5,4 +5,4 @@ void pathtraceInit(Scene *scene); void pathtraceFree(); -void pathtrace(uchar4 *pbo, int frame, int iteration); +void pathtrace(uchar4 *pbo, const SceneOptions& sceneOptions, int iter); diff --git a/src/scene.cpp b/src/scene.cpp index cbae043..70be87e 100644 --- a/src/scene.cpp +++ b/src/scene.cpp @@ -96,7 +96,7 @@ int Scene::loadCamera() { float fovy; //load static properties - for (int i = 0; i < 5; i++) { + for (int i = 0; i < 10; i++) { string line; utilityCore::safeGetline(fp_in, line); vector tokens = utilityCore::tokenizeString(line); @@ -111,21 +111,23 @@ int Scene::loadCamera() { state.traceDepth = atoi(tokens[1].c_str()); } else if (strcmp(tokens[0].c_str(), "FILE") == 0) { state.imageName = tokens[1]; - } + } else if (strcmp(tokens[0].c_str(), "EYE") == 0) { + camera.position = glm::vec3(atof(tokens[1].c_str()), atof(tokens[2].c_str()), atof(tokens[3].c_str())); + } else if (strcmp(tokens[0].c_str(), "LOOKAT") == 0) { + 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(), "FOCAL_LENGTH") == 0) { + camera.focalLength = atof(tokens[1].c_str()); + } else if (strcmp(tokens[0].c_str(), "LENS_RADIUS") == 0) { + camera.lensRadius = atof(tokens[1].c_str()); + } } string line; utilityCore::safeGetline(fp_in, line); while (!line.empty() && fp_in.good()) { vector tokens = utilityCore::tokenizeString(line); - if (strcmp(tokens[0].c_str(), "EYE") == 0) { - camera.position = glm::vec3(atof(tokens[1].c_str()), atof(tokens[2].c_str()), atof(tokens[3].c_str())); - } else if (strcmp(tokens[0].c_str(), "LOOKAT") == 0) { - 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())); - } - utilityCore::safeGetline(fp_in, line); } diff --git a/src/sceneStructs.h b/src/sceneStructs.h index b38b820..6780c90 100644 --- a/src/sceneStructs.h +++ b/src/sceneStructs.h @@ -49,9 +49,12 @@ struct Camera { glm::vec3 right; glm::vec2 fov; glm::vec2 pixelLength; + float focalLength; + float lensRadius; }; -struct RenderState { +struct RenderState +{ Camera camera; unsigned int iterations; int traceDepth; @@ -59,18 +62,30 @@ struct RenderState { std::string imageName; }; -struct PathSegment { +struct SceneOptions +{ + SceneOptions() : sortPathsByMaterial(true), iterToCacheFirstBounces(1) + {} + bool sortPathsByMaterial; + bool iterToCacheFirstBounces; +}; + +struct PathSegment +{ Ray ray; glm::vec3 color; int pixelIndex; int remainingBounces; + int intersectionIndex; }; // Use with a corresponding PathSegment to do: // 1) color contribution computation // 2) BSDF evaluation: generate a new ray -struct ShadeableIntersection { - float t; +struct ShadeableIntersection +{ + glm::vec3 intersectionPoint; glm::vec3 surfaceNormal; int materialId; + float t; }; diff --git a/src/timer.cu b/src/timer.cu new file mode 100644 index 0000000..9c3ef44 --- /dev/null +++ b/src/timer.cu @@ -0,0 +1,462 @@ + +#include +#include + +#include "timer.h" + +#define FILENAME (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) +#define checkCUDAError(msg) checkCUDAErrorFn(msg, FILENAME, __LINE__) +static void checkCUDAErrorFn(const char *msg, const char *file, int line) { +#if ERRORCHECK + cudaDeviceSynchronize(); + cudaError_t err = cudaGetLastError(); + if (cudaSuccess == err) { + return; + } + + fprintf(stderr, "CUDA error"); + if (file) { + fprintf(stderr, " (%s:%d)", file, line); + } + fprintf(stderr, ": %s: %s\n", msg, cudaGetErrorString(err)); +# ifdef _WIN32 + getchar(); +# endif + exit(EXIT_FAILURE); +#endif +} + +MyTimer* Timer::m_myTimer = NULL; + +class MyTimer +{ +public: + using Clock = std::chrono::high_resolution_clock; + using TimePoint = std::chrono::time_point; + +public: + MyTimer() + { + m_refCount = 0; + m_useGPU = true; + m_elapsedTimeInms = 0.0f; + + cudaEventCreate(&m_start); + cudaEventCreate(&m_stop); + + m_startTime = Clock::now(); + m_stopTime = Clock::now(); + } + + ~MyTimer() + { + cudaEventDestroy(m_start); + cudaEventDestroy(m_stop); + } + +public: + + void resetTimer(bool useGPU = true) + { + m_useGPU = useGPU; + m_elapsedTimeInms = 0.0f; + } + + void playTimer() + { + if (m_refCount++ == 0) + { + if (m_useGPU) + { + cudaEventRecord(m_start); + } + else + { + m_startTime = Clock::now(); + } + } + } + + bool pauseTimer() + { + bool bPaused = false; + if (--m_refCount == 0) + { + float newElapsedTime = 0.0f; + if (m_useGPU) + { + cudaEventRecord(m_stop); + cudaEventSynchronize(m_stop); + cudaEventElapsedTime(&newElapsedTime, m_start, m_stop); + } + else + { + m_stopTime = Clock::now(); + newElapsedTime = std::chrono::duration_cast(m_stopTime - m_startTime).count(); + } + m_elapsedTimeInms += newElapsedTime; + bPaused = true; + } + return bPaused; + } + + float printTimer(const char* timerHeader, float timerFactor) + { + float elapsedTime = timerFactor * m_elapsedTimeInms; + printf("%s - Elapsed Time:%f ms.\n", timerHeader, elapsedTime); + return elapsedTime; + } + +private: + size_t m_refCount; + bool m_useGPU; + float m_elapsedTimeInms; +private: + cudaEvent_t m_start; + cudaEvent_t m_stop; + +private: + TimePoint m_startTime; + TimePoint m_stopTime; +}; + +Timer::Timer() +{ +} + +Timer::~Timer() +{ +} + +void Timer::initializeTimer() +{ + if (m_myTimer == NULL) + m_myTimer = new MyTimer; +} + +void Timer::shutdownTimer() +{ + if (m_myTimer != NULL) + delete m_myTimer; +} + +void Timer::resetTimer(bool useGPU) +{ + m_myTimer->resetTimer(useGPU); +} + +void Timer::playTimer() +{ + m_myTimer->playTimer(); +} + +void Timer::pauseTimer() +{ + m_myTimer->pauseTimer(); +} + +void Timer::printTimer(const char* timerHeader, float timerFactor) +{ + m_myTimer->printTimer(timerHeader, timerFactor); +} + + +//------------------------------- +//-------------RNG TESTS--------- +//------------------------------- + +void xOrBinValues(const char* x, const char* y, char* z) +{ + int bitXIdx = 0; int bitYIdx = 0; int bitZIdx = 0; + while (x[bitXIdx] != NULL || y[bitYIdx] != NULL) + { + int xBit = 0; + if (x[bitXIdx] != NULL) + { + xBit = (x[bitXIdx] == '1') ? 1 : 0; + bitXIdx++; + } + + int yBit = 0; + if (y[bitYIdx] != NULL) + { + yBit = (y[bitYIdx] == '1') ? 1 : 0; + bitYIdx++; + } + z[bitZIdx++] = ((xBit ^ yBit) == 0) ? '0' : '1'; + } + z[bitZIdx] = NULL; +} + +int indexOfRightMostZeroBit(int bitMask) +{ + int bitIdx = 1; + while (bitMask) + { + if ((bitMask & 0x1) == 0) break; + bitMask >>= 1; + ++bitIdx; + } + return bitIdx; +} + +int computeViInBinary(int mi, int i, char* outVi) +{ + outVi[i] = NULL; + for (int iter = i - 1; iter >= 0; --iter, mi >>= 1) + { + char nextBin = (mi & 0x1 == 1) ? '1' : '0'; + outVi[iter] = nextBin; + } + return i; +} + +float convertBinary01ToFloat(const char* bin) +{ + float val = 0; + int idx = 0; + while (bin[idx] != NULL) + { + int bit = (bin[idx] == '0') ? 0 : 1; + val += bit * powf(2, -(idx + 1)); + idx++; + } + return val; +} + +void preComputeMiTable(const int numMi, int* miBuffer) +{ + // From ALGORITHM 659 Implementing Sobol’s Quasirandom Sequence Generator. + // Each mi is odd and mi < (1< u01(0, 1); + + const int gridIdx = iter % GridSize; + const float i01Val = u01(rng); + + ++iter; + return gridIdx / (1.0f * (GridSize - 1)) + i01Val; +} +///////////////////////////////////////////////////////////////////////////// +#include +#include + +//PRNGenerator::eType PRNGenerator::m_type = PRNGenerator::None; +//static size_t m_numVals = 0; +//static float* m_vals = NULL; + +PRNGenerator::eType PRNGenerator::m_type = PRNGenerator::None; +size_t PRNGenerator::m_numVals = 0; +float* PRNGenerator::m_vals = NULL; + +void PRNGenerator::initializeSystem(eType prngType, int numVals) +{ + if (prngType == PRNGenerator::None || m_vals != NULL) + { + fprintf(stderr, "ERROR"); + return; + } + checkCUDAError("generate camera ray"); + m_type = prngType; + m_numVals = numVals; + + cudaMalloc(&m_vals, numVals * sizeof(float)); + float* vals = new float[numVals]; memset(vals, 0, numVals* sizeof(float)); + + checkCUDAError("generate camera ray"); + switch (m_type) + { + case PRNGenerator::Thrust: + break; + case PRNGenerator::Stratified: + for (int i = 0; i < numVals; ++i) + { + vals[i] = generateNextStratifiedRNG(); + } + break; + case PRNGenerator::Halton: + for (int i = 0; i < numVals; ++i) + { + vals[i] = generateNextHaltonRNG(); + } + break; + case PRNGenerator::Sodel: + for (int i = 0; i < numVals; ++i) + { + checkCUDAError("generate camera ray"); + vals[i] = generateNextSodelRNG(); + } + break; + default: + break; + } + + cudaMemcpy(m_vals, vals, numVals * sizeof(float), cudaMemcpyKind::cudaMemcpyHostToDevice); + delete [] vals; + checkCUDAError("generate camera ray"); +} + +void PRNGenerator::shutdownSystem() +{ + cudaFree(m_vals); +} + +PRNG::PRNG(PRNGenerator::eType prngType, int numVals, float* vals) +: m_type(prngType), + m_numVals(numVals), m_vals(vals) +{ + +} + +__host__ __device__ void PRNG::setSeed(int iter, int index, int depth) +{ + const int h = utilhash((1 << 31) | (depth << 22) | iter) ^ utilhash(index); + switch (m_type) + { + case PRNGenerator::Thrust: + m_rng = thrust::default_random_engine(h); + break; + case PRNGenerator::Stratified: + case PRNGenerator::Halton: + case PRNGenerator::Sodel: + { + const size_t absH = abs(h); + m_nextRandomIdx = absH % m_numVals; + break; + } + default: + break; + } +} + +__host__ __device__ PRNG::~PRNG() +{ +} + +__host__ __device__ float PRNG::getNextVal01() +{ + float nextVal = 0.0f; + switch (m_type) + { + case PRNGenerator::Thrust: + nextVal = m_u01(m_rng); + break; + case PRNGenerator::Stratified: + case PRNGenerator::Halton: + case PRNGenerator::Sodel: + { + nextVal = m_vals[m_nextRandomIdx++]; + if (m_nextRandomIdx >= m_numVals) + { + m_nextRandomIdx = 0; + } + } + break; + default: + break; + } + return nextVal; +} diff --git a/src/timer.h b/src/timer.h new file mode 100644 index 0000000..013d4b9 --- /dev/null +++ b/src/timer.h @@ -0,0 +1,81 @@ +#pragma once + +class MyTimer; + +class Timer +{ +public: + Timer(); + ~Timer(); + +public: + static void initializeTimer(); + static void shutdownTimer(); + +public: + static void resetTimer(bool useGPU = true); + static void playTimer(); + static void pauseTimer(); + static void printTimer(const char* timerHeader, float timerFactor); + +private: + static MyTimer* m_myTimer; +}; + +/** +* Handy-dandy hash function that provides seeds for random number generation. +*/ +__host__ __device__ inline unsigned int utilhash(unsigned int a) { + a = (a + 0x7ed55d16) + (a << 12); + a = (a ^ 0xc761c23c) ^ (a >> 19); + a = (a + 0x165667b1) + (a << 5); + a = (a + 0xd3a2646c) ^ (a << 9); + a = (a + 0xfd7046c5) + (a << 3); + a = (a ^ 0xb55a4f09) ^ (a >> 16); + return a; +} + +#include +#include + +struct PRNGenerator +{ + enum eType + { + None, + Thrust, + Stratified, + Halton, + Sodel, + }; + + static void initializeSystem(eType prngType, int numVals); + static void shutdownSystem(void); + + static eType getType() { return m_type; }; + static size_t getNumVals() { return m_numVals; }; + static float* getVals() { return m_vals; }; + +private: + + static eType m_type; + static size_t m_numVals; + static float* m_vals; +}; + +struct PRNG +{ + __host__ __device__ PRNG(PRNGenerator::eType prngType, int numVals, float* vals); + __host__ __device__ ~PRNG(); + + __host__ __device__ void setSeed(int iter, int index, int depth); + __host__ __device__ float getNextVal01(); + + PRNGenerator::eType m_type; + size_t m_numVals; + float* m_vals; + + size_t m_nextRandomIdx; + thrust::default_random_engine m_rng; + thrust::uniform_real_distribution m_u01; +}; diff --git a/src/utilities.cpp b/src/utilities.cpp index 9c06c68..8dea8f0 100644 --- a/src/utilities.cpp +++ b/src/utilities.cpp @@ -109,4 +109,4 @@ std::istream& utilityCore::safeGetline(std::istream& is, std::string& t) { t += (char)c; } } -} +} \ No newline at end of file diff --git a/src/utilities.h b/src/utilities.h index abb4f27..67a0959 100644 --- a/src/utilities.h +++ b/src/utilities.h @@ -23,4 +23,4 @@ namespace utilityCore { extern glm::mat4 buildTransformationMatrix(glm::vec3 translation, glm::vec3 rotation, glm::vec3 scale); extern std::string convertIntToString(int number); extern std::istream& safeGetline(std::istream& is, std::string& t); //Thanks to http://stackoverflow.com/a/6089413 -} +} \ No newline at end of file From f4ef62d1b11d6c16b6d5efe342f119d73acb0d83 Mon Sep 17 00:00:00 2001 From: David Grosman Date: Sun, 9 Oct 2016 23:31:55 -0400 Subject: [PATCH 2/8] Submit Too --- src/interactions - Copy (2).h | 191 ---------------------------------- src/interactions - Copy.h | 159 ---------------------------- src/interactions.h | 12 +++ 3 files changed, 12 insertions(+), 350 deletions(-) delete mode 100644 src/interactions - Copy (2).h delete mode 100644 src/interactions - Copy.h diff --git a/src/interactions - Copy (2).h b/src/interactions - Copy (2).h deleted file mode 100644 index 9b7e65e..0000000 --- a/src/interactions - Copy (2).h +++ /dev/null @@ -1,191 +0,0 @@ -#pragma once - -#include "intersections.h" - -// CHECKITOUT -/** -* Computes a cosine-weighted random direction in a hemisphere. -* Used for diffuse lighting. -*/ -__host__ __device__ -glm::vec3 computeDiffuseDirection( -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__ -glm::vec3 computeReflectiveDirection( -const glm::vec3& normal, const glm::vec3& incident) -{ - const float cosI = glm::dot(normal, incident); - return incident - 2.0f * cosI * normal; -} - -__host__ __device__ -glm::vec3 computeRefractiveDirection( -const glm::vec3& normal, const glm::vec3& incident, -const float ni, const float nt) -{ - // Uses Snell's Law: - const float n = ni / nt; - const float cosI = -glm::dot(normal, incident); - float sinT2 = n * n * (1.0f - cosI * cosI); - if (sinT2 > 1.0) { return computeReflectiveDirection(normal, incident); } //Hack - const float cosT = sqrt(1.0 - sinT2); - return n * incident + (n * cosI - cosT) * normal; -} - -__host__ __device__ -float computeReflectance( -const glm::vec3& normal, const glm::vec3& incident, -const float ni, const float nt) -{ - const float cosI = -glm::dot(normal, incident); - float R0 = (ni - nt) / (ni + nt); - R0 *= R0; - return R0 + (1 - R0) * powf(1 - cosI, 5); -} - -/** -* Scatter a ray with some probabilities according to the material properties. -* For example, a diffuse surface scatters in a cosine-weighted hemisphere. -* A perfect specular surface scatters in the reflected ray direction. -* In order to apply multiple effects to one surface, probabilistically choose -* between them. -* -* 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). -* -* - 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 -* by its probability (0.5), to counteract the chance (0.5) of the branch -* being taken. -* - This way is inefficient, but serves as a good starting point - it -* converges slowly, especially for pure-diffuse or pure-specular. -* - Pick the split based on the intensity of each material color, and divide -* branch result by that branch's probability (whatever probability you use). -* -* This method applies its changes to the Ray parameter `ray` in place. -* It also modifies the color `color` of the ray in place. -* -* You may need to change the parameter list for your purposes! -*/ -__host__ __device__ -void scatterRay( -PathSegment & pathSegment, -glm::vec3 intersect, -glm::vec3 normal, -const Material &m, -thrust::default_random_engine &rng) -{ - const float MY_EPSILON = 1e-3f; - - Ray& outRay = pathSegment.ray; - glm::vec3& outColor = pathSegment.color; - - const bool isInwardsRay = (glm::dot(normal, outRay.direction) < 0.0f); - const float pathDir = isInwardsRay ? 1 : -1; - - if (!m.hasReflective && !m.hasRefractive) // Diffuse - { - outRay.direction = computeDiffuseDirection(normal, rng); - outColor *= glm::abs(glm::dot(outRay.direction, normal)) * m.color; - outRay.origin = intersect + pathDir * normal * MY_EPSILON; - } - else - { - float ni = 1.0f, nt = 1.0f; - { - if (isInwardsRay) - { - ni = 1.0f; - nt = m.indexOfRefraction; - } - else - { - ni = m.indexOfRefraction; - nt = 1.0f; - } - } - - float reflectance = computeReflectance(normal, outRay.direction, ni, nt); - if (m.hasReflective) - { - outRay.direction = glm::reflect(pathSegment.ray.direction, normal); - outColor *= reflectance* m.color; - outRay.origin = intersect + pathDir * normal * MY_EPSILON; - } - else if (m.hasRefractive) - { - outRay.direction = computeRefractiveDirection(normal, pathSegment.ray.direction, ni, nt); - outColor *= (1.0f - reflectance) * m.color; - outRay.origin = intersect - pathDir * normal * MY_EPSILON; - //printf("(%f,%f,%f)", outColor.r, outColor.g, outColor.b); - } - } - - - - - -} - - -//__host__ __device__ -//void scatterRay( -//Ray& ray, -//glm::vec3& color, -//glm::vec3 intersect, -//glm::vec3 normal, -//const Material &m, -//thrust::default_random_engine &rng) -//{ -// float precision_fix = 1e-4f; -// -// // TODO: partial? -// if (m.hasReflective < 0.5f) -// { -// // Diffuse only -// ray.direction = calculateRandomDirectionInHemisphere(normal, rng); -// ray.origin = intersect + precision_fix * normal; -// color *= m.color; -// } -// else -// { -// // Reflection only -// ray.direction = glm::reflect(ray.direction, normal); -// ray.origin = intersect + precision_fix * normal; -// color *= m.color; -// } -//} \ No newline at end of file diff --git a/src/interactions - Copy.h b/src/interactions - Copy.h deleted file mode 100644 index a13117e..0000000 --- a/src/interactions - Copy.h +++ /dev/null @@ -1,159 +0,0 @@ -#pragma once - -#include "intersections.h" - -// CHECKITOUT -/** - * Computes a cosine-weighted random direction in a hemisphere. - * Used for diffuse lighting. - */ -__host__ __device__ -glm::vec3 computeDiffuseDirection( -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__ -glm::vec3 computeReflectiveDirection( -const glm::vec3& normal, const glm::vec3& incident) -{ - const float cosI = glm::dot(normal, incident); - return incident - 2.0f * cosI * normal; -} - -__host__ __device__ -glm::vec3 computeRefractiveDirection( -const glm::vec3& normal, const glm::vec3& incident, -const float ni, const float nt) -{ - // Uses Snell's Law: - const float n = ni / nt; - const float cosI = -glm::dot(normal, incident); - float sinT2 = n * n * (1.0f - cosI * cosI); - if (sinT2 > 1.0) { return computeReflectiveDirection(normal, incident); } //Hack - const float cosT = sqrt(1.0 - sinT2); - return n * incident + (n * cosI - cosT) * normal; -} - -__host__ __device__ -float computeReflectance( -const glm::vec3& normal, const glm::vec3& incident, -const float ni, const float nt) -{ - // From http://graphics.stanford.edu/courses/cs148-10-summer/docs/2006--degreve--reflection_refraction.pdf - const float n = ni / nt; - const float cosI = -glm::dot(normal, incident); - float sinT2 = n * n * (1.0f - cosI * cosI); - if (sinT2 > 1.0) { return 1.0f; } //Hack - const float cosT = sqrt(1.0 - sinT2); - const float rOrth = (ni * cosI - nt * cosT) / (ni * cosI + nt * cosT); - const float rPar = (nt * cosI - ni * cosT) / (nt * cosI + ni * cosT); - return (rOrth * rOrth + rPar * rPar) / 2.0f; -} - -/** - * Scatter a ray with some probabilities according to the material properties. - * For example, a diffuse surface scatters in a cosine-weighted hemisphere. - * A perfect specular surface scatters in the reflected ray direction. - * In order to apply multiple effects to one surface, probabilistically choose - * between them. - * - * 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). - * - * - 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 - * by its probability (0.5), to counteract the chance (0.5) of the branch - * being taken. - * - This way is inefficient, but serves as a good starting point - it - * converges slowly, especially for pure-diffuse or pure-specular. - * - Pick the split based on the intensity of each material color, and divide - * branch result by that branch's probability (whatever probability you use). - * - * This method applies its changes to the Ray parameter `ray` in place. - * It also modifies the color `color` of the ray in place. - * - * You may need to change the parameter list for your purposes! - */ -__host__ __device__ -void scatterRay( - PathSegment & pathSegment, - glm::vec3 intersect, - glm::vec3 normal, - glm::vec3 eye, - const Material &m, - thrust::default_random_engine &rng) -{ - Ray& outRay = pathSegment.ray; - glm::vec3& outColor = pathSegment.color; - - const bool isInwardsRay = (glm::dot(normal, outRay.direction) < 0.0f); - if (!m.hasReflective && !m.hasRefractive) // Diffuse - { - outRay.direction = computeDiffuseDirection(normal, rng); - pathSegment.color *= glm::abs(glm::dot(outRay.direction, normal)) * m.color; - } - else - { - float ni = 1.0f, nt = 1.0f; - { - if (isInwardsRay) - { - ni = 1.0f; - nt = m.indexOfRefraction; - } - else - { - ni = m.indexOfRefraction; - nt = 1.0f; - } - } - - float reflectance = computeReflectance( normal, outRay.direction, ni, nt ); - if (m.hasReflective) - { - outRay.direction = glm::reflect(pathSegment.ray.direction, normal); - //pathSegment.color *= m.color; - pathSegment.color *= glm::abs(glm::dot(outRay.direction, normal)) * m.color; - } - else if (m.hasRefractive) - { - outRay.direction = computeRefractiveDirection(normal, pathSegment.ray.direction, ni, nt); - outColor *= m.color * (1.0f - reflectance); - } - } - - float pathDir = isInwardsRay ? -1 : 1; - - const float MY_EPSILON = 1e-4f; - outRay.origin = intersect + pathDir * normal * MY_EPSILON; -} diff --git a/src/interactions.h b/src/interactions.h index 9b6a965..3beb7d5 100644 --- a/src/interactions.h +++ b/src/interactions.h @@ -43,6 +43,18 @@ glm::vec3& normal, PRNG& rng) { + sin(around) * over * perpendicularDirection2; } +__host__ __device__ +glm::vec3 computeDiffuseDirectionToo( +glm::vec3& normal, PRNG& rng) +{ + const float s = rng.getNextVal01(); + const float t = rng.getNextVal01(); + float u = TWO_PI * s; + float v = sqrt(1 - t); // sin(theta) + + return glm::vec3(v * cos(u), sqrt(t), v * sin(u)); +} + __host__ __device__ glm::vec3 computeReflectiveDirection( const glm::vec3& normal, const glm::vec3& incident) From 6817c086ad1eedbf960424d0419eb6939d4316fe Mon Sep 17 00:00:00 2001 From: David Grosman Date: Sun, 9 Oct 2016 23:53:02 -0400 Subject: [PATCH 3/8] A --- src/pathtrace.cu | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/pathtrace.cu b/src/pathtrace.cu index 7b36d44..cf840cb 100644 --- a/src/pathtrace.cu +++ b/src/pathtrace.cu @@ -448,14 +448,14 @@ void pathtrace(uchar4 *pbo, const SceneOptions& sceneOptions, int iter) // TODO: compare between directly shading the path segments and shading // path segments that have been reshuffled to be contiguous in memory. - /*if (sceneOptions.sortPathsByMaterial) + if (sceneOptions.sortPathsByMaterial) { thrust::device_vector dv_in_paths(dev_paths, dev_paths + num_paths); thrust::stable_sort(dv_in_paths.begin(), dv_in_paths.end(), SortByMaterialId(dev_intersections)); thrust::device_vector dv_in_intersects(dev_intersections, dev_intersections + num_paths); thrust::stable_sort(dv_in_intersects.begin(), dv_in_intersects.end(), SortByMaterialId(dev_intersections)); - }*/ + } shadeScene << > > ( iter, @@ -474,6 +474,10 @@ void pathtrace(uchar4 *pbo, const SceneOptions& sceneOptions, int iter) num_paths = std::distance(dev_paths, dev_path_end); } depth++; + if (depth >= traceDepth) + { + iterationComplete = true; + } } Timer::pauseTimer(); // Assemble this iteration and apply it to the image From 05a4094d82569321260980ce49c5028be80dc469 Mon Sep 17 00:00:00 2001 From: davidgrosman Date: Sun, 9 Oct 2016 23:55:31 -0400 Subject: [PATCH 4/8] Update README.md --- README.md | 41 +++++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 110697c..c836721 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,38 @@ -CUDA Path Tracer -================ +# University of Pennsylvania, CIS 565: GPU Programming and Architecture. +Project 3 CUDA: Path Tracer +==================== -**University of Pennsylvania, CIS 565: GPU Programming and Architecture, Project 3** +## User resources +- **Name:** David Grosman. +- **Tested on:** Microsoft Windows 7 Professional, i7-5600U @ 2.6GHz, 256GB, GeForce 840M (Personal laptop). -* (TODO) YOUR NAME HERE -* Tested on: (TODO) Windows 22, i7-2222 @ 2.22GHz 22GB, GTX 222 222MB (Moore 2222 Lab) +## Project description +This Project's purpose was to gain some experience with writing Graphics code that would benefit as much as possible from CUDA as possible. In fact, a path tracer is a very useful type of application to run on Cuda since each ray processed by the application can be done in a separate thread. Furthermore, computations such as intersection-testing and pixel coloring are very intensive and are thus most usefully done on GPU. Furthermore, there is no memory bandwidth from CPU to GPU to pass on the pixel buffer as is usually the case in a CPU implementation. +In this project, I have implemented several key features such as: +1. Diffuse shading +2. Caching Initial rays. +3. Stream compaction on terminated paths during each iteration. +4. Sort Rays by material type they are intersecting with. +5. Specular reflection and refraction. +6. Depth of Field. +7. Jittered, Halton and Sobel Pseudo-Random generators to improve the cosine weighted hemisphere generated when computing the diffuse component. -### (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. + +###Shading, +I first implemented my efficient scan version following the class slides closely but I was unsatisfied with its performance -- it was around 8 times slower than my cpu approach. +![](img/RefrAndRefl.JPG) + + + +--- +### Performance Analysis +Note that the following statistics have been captured by calling the given functions 1000 times (with the default parameters given when starting the project) and averaging the results. +Please note that I used CUDA events for timing GPU code and I did not include any initial/final memory operations (cudaMalloc, cudaMemcpy) in your performance measurements, for comparability. +![](images/ScanRuntimePerformanceGivenArraySize.JPG) + +It is interesting to notice that the CPU version is the fastest. It is most probably due to the fact that the algorithm on CPU is O(n) and accessing contiguous memory on CPU is very fast compared to GPU. The performance time on GPU decreases much faster given a bigger array size. It confirms that memory access is the GPU's performance main bottleneck. +It is nice to see that the efficient-scan performs better than the Naive implementation, even though it doesn't outperform Thrust's version which might include more efficient tricks. + +![](images/CompactRuntimePerformanceGivenArraySize.JPG) From 641e2ff4808488309de34845f1e0e2cbd04eb5a3 Mon Sep 17 00:00:00 2001 From: davidgrosman Date: Mon, 10 Oct 2016 00:03:18 -0400 Subject: [PATCH 5/8] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c836721..a07cb26 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,8 @@ Project 3 CUDA: Path Tracer ## Project description This Project's purpose was to gain some experience with writing Graphics code that would benefit as much as possible from CUDA as possible. In fact, a path tracer is a very useful type of application to run on Cuda since each ray processed by the application can be done in a separate thread. Furthermore, computations such as intersection-testing and pixel coloring are very intensive and are thus most usefully done on GPU. Furthermore, there is no memory bandwidth from CPU to GPU to pass on the pixel buffer as is usually the case in a CPU implementation. In this project, I have implemented several key features such as: -1. Diffuse shading + +1. Diffuse shading. 2. Caching Initial rays. 3. Stream compaction on terminated paths during each iteration. 4. Sort Rays by material type they are intersecting with. From 01583b1e7db17294ce56f86b8d79d7840f95d6a7 Mon Sep 17 00:00:00 2001 From: davidgrosman Date: Mon, 10 Oct 2016 00:29:47 -0400 Subject: [PATCH 6/8] Add files via upload --- img/PerfGivenRayBounces.JPG | Bin 0 -> 47912 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 img/PerfGivenRayBounces.JPG diff --git a/img/PerfGivenRayBounces.JPG b/img/PerfGivenRayBounces.JPG new file mode 100644 index 0000000000000000000000000000000000000000..b590fabb972403fc5bdebc1c175222b146a81200 GIT binary patch literal 47912 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 literal 0 HcmV?d00001 From dcf70be7495ae550725727ec7d34ca09c0d4d03c Mon Sep 17 00:00:00 2001 From: davidgrosman Date: Mon, 10 Oct 2016 00:41:42 -0400 Subject: [PATCH 7/8] Update README.md --- README.md | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index a07cb26..5bf4cfc 100644 --- a/README.md +++ b/README.md @@ -9,31 +9,34 @@ Project 3 CUDA: Path Tracer ## Project description This Project's purpose was to gain some experience with writing Graphics code that would benefit as much as possible from CUDA as possible. In fact, a path tracer is a very useful type of application to run on Cuda since each ray processed by the application can be done in a separate thread. Furthermore, computations such as intersection-testing and pixel coloring are very intensive and are thus most usefully done on GPU. Furthermore, there is no memory bandwidth from CPU to GPU to pass on the pixel buffer as is usually the case in a CPU implementation. In this project, I have implemented several key features such as: - -1. Diffuse shading. -2. Caching Initial rays. -3. Stream compaction on terminated paths during each iteration. -4. Sort Rays by material type they are intersecting with. -5. Specular reflection and refraction. +1. Diffuse shading +2. Specular reflection and refraction. +3. Caching Initial rays. +4. Stream compaction on non-terminated paths during each iteration. +5. Sort Rays by material type they are intersecting with. 6. Depth of Field. -7. Jittered, Halton and Sobel Pseudo-Random generators to improve the cosine weighted hemisphere generated when computing the diffuse component. +7. Better hemisphere sampling methods. -###Shading, -I first implemented my efficient scan version following the class slides closely but I was unsatisfied with its performance -- it was around 8 times slower than my cpu approach. +###Shading: Diffuse and Specular reflection, refraction. +The shading implemented for this project is pretty straight-forward and is inspired from http://graphics.stanford.edu/courses/cs148-10-summer/docs/2006--degreve--reflection_refraction.pdf. The reflectance factor used to determine how much of the reflecting vs. refracting ray to use for the final color was implemented using the Schlik's approximation, which is pretty Schlik. The ray used to determine the diffuse color is actually a cosine weighted hemisphere where there are fewer rays along the horizon and increase density as we go up. ![](img/RefrAndRefl.JPG) +###Caching Initial rays. +Since all initial rays go from the camera's position to each pixel of the screen, it is easy to cache the first intersection of each ray since they stay constant until the camera (or scene objects) move again. Unfortunately, there isn't much performance gain from doing this since we must not only use a lot of memory to store the intersections but we also only use them for the first ray bounce which is often a small portion of the time the path-tracer determines new intersections since each ray must bounce at least 8 times to get nice global illumination effects. +###Stream compaction on non-terminated paths. +As shown on the graph below, the performance increase in compacting non-terminated paths is non-negligent, especially when increasing the number of bounces per ray. This is the most important optimization done for this project. +![](img/PerfGivenRayBounces.JPG) ---- -### Performance Analysis -Note that the following statistics have been captured by calling the given functions 1000 times (with the default parameters given when starting the project) and averaging the results. -Please note that I used CUDA events for timing GPU code and I did not include any initial/final memory operations (cudaMalloc, cudaMemcpy) in your performance measurements, for comparability. -![](images/ScanRuntimePerformanceGivenArraySize.JPG) - -It is interesting to notice that the CPU version is the fastest. It is most probably due to the fact that the algorithm on CPU is O(n) and accessing contiguous memory on CPU is very fast compared to GPU. The performance time on GPU decreases much faster given a bigger array size. It confirms that memory access is the GPU's performance main bottleneck. -It is nice to see that the efficient-scan performs better than the Naive implementation, even though it doesn't outperform Thrust's version which might include more efficient tricks. +###Sort Rays by material type they are intersecting with. +This is an optimization which actually decreased the performance of the application: The time spent sorting the rays is non-negligeable, especially when there are so many rays and not space or time-coherent scheme is adopted to sort the rays faster. This optimization should be tested on Waverfont pathtracing where rays are grouped by material without a sorting pass. -![](images/CompactRuntimePerformanceGivenArraySize.JPG) +###Depth of Field. +Depth of field is an easy technique to implement when ray-tracing since the only change is how rays are generated. In fact their origin should be located on the lens and their direction should be towards a point that is at a dustance specified by the focal distance. +![](img/DOF.JPG) +###Better hemisphere sampling methods. +I implemented Jittered, Halton and Sobel Pseudo-Random generators to improve the cosine weighted hemisphere generated when computing the diffuse component. Quasi-Random numbers as generated by Halton and Sobel schemes is pretty powerful since they can issue sequences of numbers specifically designed to fill an interval (typically [0…1] in n-dimensional space) in a relatively uniform way (compared to purely random or pseudo-random). In fact, each new number (or vector) in the sequence is spaced as far as possible from the previous ones. Their goal is to be able to generate randomized, but relatively uniformly spaced patterns, similar to jittering, but not requiring knowledge ahead of time about the total number of samples. +![](img/RefrAndRefl.JPG) From 0d4a648e401bb13e65738646da94d1a28616d94c Mon Sep 17 00:00:00 2001 From: davidgrosman Date: Mon, 10 Oct 2016 09:42:38 -0400 Subject: [PATCH 8/8] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5bf4cfc..e872e85 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ Project 3 CUDA: Path Tracer ## Project description This Project's purpose was to gain some experience with writing Graphics code that would benefit as much as possible from CUDA as possible. In fact, a path tracer is a very useful type of application to run on Cuda since each ray processed by the application can be done in a separate thread. Furthermore, computations such as intersection-testing and pixel coloring are very intensive and are thus most usefully done on GPU. Furthermore, there is no memory bandwidth from CPU to GPU to pass on the pixel buffer as is usually the case in a CPU implementation. In this project, I have implemented several key features such as: + 1. Diffuse shading 2. Specular reflection and refraction. 3. Caching Initial rays. @@ -39,4 +40,4 @@ Depth of field is an easy technique to implement when ray-tracing since the only ###Better hemisphere sampling methods. I implemented Jittered, Halton and Sobel Pseudo-Random generators to improve the cosine weighted hemisphere generated when computing the diffuse component. Quasi-Random numbers as generated by Halton and Sobel schemes is pretty powerful since they can issue sequences of numbers specifically designed to fill an interval (typically [0…1] in n-dimensional space) in a relatively uniform way (compared to purely random or pseudo-random). In fact, each new number (or vector) in the sequence is spaced as far as possible from the previous ones. Their goal is to be able to generate randomized, but relatively uniformly spaced patterns, similar to jittering, but not requiring knowledge ahead of time about the total number of samples. -![](img/RefrAndRefl.JPG) +![](img/RefrOnRefl.JPG)