Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Submitting Project 1 #3

Open
wants to merge 19 commits into
base: master
Choose a base branch
from
23 changes: 19 additions & 4 deletions PROJ1_WIN/565Raytracer/565Raytracer.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
<Import Project="..\Build\CUDA 4.0.props" />
<Import Project="$(VCTargetsPath)\BuildCustomizations\CUDA 4.0.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
Expand All @@ -91,10 +91,10 @@
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug (v5.5)|Win32'">
<LinkIncremental>true</LinkIncremental>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
Expand Down Expand Up @@ -198,8 +198,23 @@
<Include>C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.5\include;C:/ProgramData/NVIDIA Corporation/CUDA Samples/v5.5/common/inc;../shared/glew/includes;../shared/freeglut/includes</Include>
</CudaCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.5\include;C:\ProgramData\NVIDIA Corporation\CUDA Samples\v5.5\common\inc;../shared/glew/include;../shared/freeglut/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<TreatWarningAsError>false</TreatWarningAsError>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<CudaCompile>
<Include>C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.5\include;C:\ProgramData\NVIDIA Corporation\CUDA Samples\v5.5\common\inc;../shared/glew/includes;../shared/freeglut/includes</Include>
</CudaCompile>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\Build\CUDA 4.0.targets" />
<Import Project="$(VCTargetsPath)\BuildCustomizations\CUDA 4.0.targets" />
</ImportGroup>
</Project>
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added PROJ1_WIN/565Raytracer/README_images/Thumbs.db
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added PROJ1_WIN/565Raytracer/README_images/weird.bmp
Binary file not shown.
425 changes: 211 additions & 214 deletions README.md

Large diffs are not rendered by default.

30 changes: 15 additions & 15 deletions scenes/sampleScene.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ ABSCOEFF 0 0 0
RSCTCOEFF 0
EMITTANCE 0

MATERIAL 3 //red glossy
RGB .63 .06 .04
SPECEX 0
SPECRGB 1 1 1
REFL 0
MATERIAL 3 //yellow glossy
RGB 1 1 0
SPECEX 0.99999
SPECRGB .6 .6 .6
REFL 1
REFR 0
REFRIOR 2
SCATTER 0
Expand All @@ -48,9 +48,9 @@ EMITTANCE 0

MATERIAL 4 //white glossy
RGB 1 1 1
SPECEX 0
SPECEX 0.9
SPECRGB 1 1 1
REFL 0
REFL 1
REFR 0
REFRIOR 2
SCATTER 0
Expand All @@ -70,11 +70,11 @@ ABSCOEFF .02 5.1 5.7
RSCTCOEFF 13
EMITTANCE 0

MATERIAL 6 //green glossy
RGB .15 .48 .09
SPECEX 0
MATERIAL 6 //purple glossy
RGB .5 0 .5
SPECEX 0.999
SPECRGB 1 1 1
REFL 0
REFL 1
REFR 0
REFRIOR 2.6
SCATTER 0
Expand Down Expand Up @@ -108,8 +108,8 @@ EMITTANCE 15

CAMERA
RES 800 800
FOVY 25
ITERATIONS 5000
FOVY 25 25
ITERATIONS 500
FILE test.bmp
frame 0
EYE 0 4.5 12
Expand Down Expand Up @@ -166,15 +166,15 @@ SCALE 3 3 3

OBJECT 6
sphere
material 3
material 6
frame 0
TRANS 2 5 2
ROTAT 0 180 0
SCALE 2.5 2.5 2.5

OBJECT 7
sphere
material 6
material 3
frame 0
TRANS -2 5 -2
ROTAT 0 180 0
Expand Down
126 changes: 122 additions & 4 deletions src/interactions.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ __host__ __device__ glm::vec3 calculateTransmissionDirection(glm::vec3 normal, g
__host__ __device__ glm::vec3 calculateReflectionDirection(glm::vec3 normal, glm::vec3 incident);
__host__ __device__ Fresnel calculateFresnel(glm::vec3 normal, glm::vec3 incident, float incidentIOR, float transmittedIOR, glm::vec3 reflectionDirection, glm::vec3 transmissionDirection);
__host__ __device__ glm::vec3 calculateRandomDirectionInHemisphere(glm::vec3 normal, float xi1, float xi2);
__host__ __device__ glm::vec3 computePhongTotal(ray& r, glm::vec3 intersection_point, glm::vec3 intersection_normal, material intersection_mtl, staticGeom* lights, int numberOfLights, staticGeom* geoms, int numberOfGeoms, material* materials, float time);
__host__ __device__ float computeShadowCoefficient(glm::vec3 intersection_point, staticGeom light, staticGeom* geoms, int numberOfGeoms, float time);

//TODO (OPTIONAL): IMPLEMENT THIS FUNCTION
__host__ __device__ glm::vec3 calculateTransmission(glm::vec3 absorptionCoefficient, float distance) {
Expand All @@ -45,8 +47,12 @@ __host__ __device__ glm::vec3 calculateTransmissionDirection(glm::vec3 normal, g

//TODO (OPTIONAL): IMPLEMENT THIS FUNCTION
__host__ __device__ glm::vec3 calculateReflectionDirection(glm::vec3 normal, glm::vec3 incident) {
//nothing fancy here
return glm::vec3(0,0,0);
float IdotN = glm::dot(-incident,normal);
glm::vec3 I;
if (IdotN < 0.0f) { I = incident; }
else { I = -incident; }
glm::vec3 R = glm::normalize(2*IdotN*normal - I);
return R;
}

//TODO (OPTIONAL): IMPLEMENT THIS FUNCTION
Expand All @@ -67,7 +73,8 @@ __host__ __device__ glm::vec3 calculateRandomDirectionInHemisphere(glm::vec3 nor
float over = sqrt(1 - up * up); // sin(theta)
float around = xi2 * 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) {
Expand All @@ -90,7 +97,118 @@ __host__ __device__ glm::vec3 calculateRandomDirectionInHemisphere(glm::vec3 nor
//Now that you know how cosine weighted direction generation works, try implementing non-cosine (uniform) weighted random direction generation.
//This should be much easier than if you had to implement calculateRandomDirectionInHemisphere.
__host__ __device__ glm::vec3 getRandomDirectionInSphere(float xi1, float xi2) {
return glm::vec3(0,0,0);

float z = xi1;
float theta = xi2 * TWO_PI;

float r = sqrt(1-z*z);
float x = r*cos(theta);
float y = r*sin(theta);

return glm::vec3(x,y,z);
}

__host__ __device__ glm::vec3 computePhongTotal(ray& r, glm::vec3 intersection_point, glm::vec3 intersection_normal,
material intersection_mtl, staticGeom* lights, int numberOfLights,
staticGeom* geoms, int numberOfGeoms, material* materials, float time){
glm::vec3 rgb(0.0, 0.0, 0.0);

float n = intersection_mtl.specularExponent;
glm::vec3 ks = glm::vec3(intersection_mtl.specularColor);
glm::vec3 kd = glm::vec3(intersection_mtl.color);
glm::vec3 N = glm::vec3(intersection_normal);
glm::vec3 V = glm::vec3(-r.direction);

glm::vec3 I, R, L;

for (int i = 0; i < numberOfLights; i++) {
staticGeom light = lights[i];

float shadow_coefficient = computeShadowCoefficient(intersection_point, light, geoms, numberOfGeoms, time);
if (shadow_coefficient > 0.0)
{
// get point on light source
glm::vec3 light_point = getRandomPointOnGeom(light,time);

// direction from intersection point to light source
L = glm::normalize(light_point - intersection_point);
float LdotN = glm::dot(L,N);
//if (LdotN<0) LdotN=0.0f; if (LdotN>1) LdotN=1.0f;

// direction of perfect specular reflection
R = glm::normalize(2*LdotN*N - L);
float RdotV = glm::dot(R,V);
if (RdotV<0) RdotV=0.0f; if (RdotV>1) RdotV=1.0f;

// light material
material light_mtl = materials[light.materialid];
// light intensity
I = light_mtl.color * min((float)1.0, materials[light.materialid].emittance);

// specular phong term
glm::vec3 specular;
if (n == 0.0f) { specular = glm::vec3(0.0f,0.0f,0.0f); }
else { specular = ks*pow(RdotV, n)*0.5f; }
if (specular.x > 1.0f) { specular.x = 1.0f; } else if (specular.x < 0.0f) { specular.x = 0.0f; }
if (specular.y > 1.0f) { specular.y = 1.0f; } else if (specular.y < 0.0f) { specular.y = 0.0f; }
if (specular.z > 1.0f) { specular.z = 1.0f; } else if (specular.z < 0.0f) { specular.z = 0.0f; }
specular *= glm::vec3(0.1f, 0.1f, 0.1f); //scale back specular component, rendering too bright

// diffuse phong term
glm::vec3 diffuse = kd*LdotN;

// phong reflectance model
rgb += (diffuse + specular) * shadow_coefficient * I;
rgb += intersection_mtl.emittance;
}
}
if (rgb.x > 1.0f) { rgb.x = 1.0f; } else if (rgb.x < 0.0f) { rgb.x = 0.0f; }
if (rgb.y > 1.0f) { rgb.y = 1.0f; } else if (rgb.y < 0.0f) { rgb.y = 0.0f; }
if (rgb.z > 1.0f) { rgb.z = 1.0f; } else if (rgb.z < 0.0f) { rgb.z = 0.0f; }
return rgb;
}

__host__ __device__ float computeShadowCoefficient(glm::vec3 intersection_point, staticGeom light,
staticGeom* geoms, int numberOfGeoms, float randomSeed) {

//glm::vec3 ro = glm::vec3(intersection_point);
//glm::vec3 rd = multiplyMV(light.transform, glm::vec4(0,0,0,1.0f)) - intersection_point;
//ray rt; rt.origin = ro; rt.direction = rd;

thrust::default_random_engine rng(hash(randomSeed));
thrust::uniform_real_distribution<float> u01(-0.5,0.5);
glm::vec3 random_light_point = getRandomPointOnGeom(light,randomSeed);
glm::vec3 ro = glm::vec3(intersection_point);
glm::vec3 rd = random_light_point - intersection_point;
ray rt; rt.origin = ro; rt.direction = rd;

glm::vec3 shadow_point;
glm::vec3 shadow_normal;
float dist_to_light = geomIntersectionTest(light, rt, shadow_point, shadow_normal);

for (int i = 0; i < numberOfGeoms; i++) {

// return values for intersection tests
float t = -1.0;

// current geometry object
staticGeom geom = geoms[i];

// if the geometry is equivalent to the light source, skip it
if (geom.objectid == light.objectid)
continue;

// test for intersections with sphere/box
t = geomIntersectionTest(geom, rt, shadow_point, shadow_normal);

// see if geometry was intersected before the light source
float error = 1e-3;
if ((t > error) && (t < dist_to_light))
return (0.0f);
}
//account for linear attenuation of light source (unless geom is light source)
if (dist_to_light > 1e-4) { return 1.0f/(0.25f*dist_to_light); }
else { return 1.0f; }
}

//TODO (PARTIALLY OPTIONAL): IMPLEMENT THIS FUNCTION
Expand Down
83 changes: 80 additions & 3 deletions src/intersections.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ __host__ __device__ glm::vec3 getSignOfRay(ray r);
__host__ __device__ glm::vec3 getInverseDirectionOfRay(ray r);
__host__ __device__ float boxIntersectionTest(staticGeom sphere, ray r, glm::vec3& intersectionPoint, glm::vec3& normal);
__host__ __device__ float sphereIntersectionTest(staticGeom sphere, ray r, glm::vec3& intersectionPoint, glm::vec3& normal);
__host__ __device__ glm::vec3 getRandomPointOnGeom(staticGeom geom, float randomSeed);
__host__ __device__ glm::vec3 getRandomPointOnCube(staticGeom cube, float randomSeed);
__host__ __device__ glm::vec3 getRandomPointOnSphere(staticGeom sphere, float randomSeed);

//Handy dandy little hashing function that provides seeds for random number generation
__host__ __device__ unsigned int hash(unsigned int a){
Expand Down Expand Up @@ -68,11 +70,72 @@ __host__ __device__ glm::vec3 getSignOfRay(ray r){
return glm::vec3((int)(inv_direction.x < 0), (int)(inv_direction.y < 0), (int)(inv_direction.z < 0));
}

//Cube intersection test, return -1 if no intersection, otherwise, distance to intersection
__host__ __device__ float geomIntersectionTest(staticGeom geom, ray r, glm::vec3& intersectionPoint, glm::vec3& normal){
if (geom.type == CUBE) return boxIntersectionTest(geom, r, intersectionPoint, normal);
else if (geom.type == SPHERE) return sphereIntersectionTest(geom, r, intersectionPoint, normal);
return (float)-1.0;
}

//TODO: IMPLEMENT THIS FUNCTION
//Cube intersection test, return -1 if no intersection, otherwise, distance to intersection
__host__ __device__ float boxIntersectionTest(staticGeom box, ray r, glm::vec3& intersectionPoint, glm::vec3& normal){

glm::vec3 ro = multiplyMV(box.inverseTransform, glm::vec4(r.origin,1.0f));
glm::vec3 rd = glm::normalize(multiplyMV(box.inverseTransform, glm::vec4(r.direction,0.0f)));

ray rt; rt.origin = ro; rt.direction = rd;

glm::vec3 faceNormals[6];
glm::vec3 faceCenters[6];
faceNormals[0] = glm::vec3(0,0,-1); faceCenters[0] = glm::vec3(0,0,-0.5);
faceNormals[1] = glm::vec3(0,0,-1); faceCenters[1] = glm::vec3(0,0, 0.5);
faceNormals[2] = glm::vec3(0,-1,0); faceCenters[2] = glm::vec3(0,-0.5,0);
faceNormals[3] = glm::vec3(0, 1,0); faceCenters[3] = glm::vec3(0, 0.5,0);
faceNormals[4] = glm::vec3(-1,0,0); faceCenters[4] = glm::vec3(-0.5,0,0);
faceNormals[5] = glm::vec3( 1,0,0); faceCenters[5] = glm::vec3( 0.5,0,0);

// closest discovered intersection
float min_t = -1.0;
int min_i = 6;

// find intersection of ray with each plane of the box
for (unsigned int i = 0; i < 6; i++) {
glm::vec3 normal = faceNormals[i];
glm::vec3 center = faceCenters[i];

return -1;
float t = glm::dot((center - rt.origin), normal) / glm::dot(rt.direction, normal);

// continue if intersection is behind camera
if (t <= 0)
continue;

// if t is greater than the closest found intersection, skip it
if ((min_t > 0.0) && (t >= min_t))
continue;

// check to see if the point found is within
// the edges defined by the face
glm::vec3 P = getPointOnRay(rt,t);
float error = 0.75e-3;
if ((P.x >= (-0.5 - error)) && (P.x <= (0.5 + error)) &&
(P.y >= (-0.5 - error)) && (P.y <= (0.5 + error)) &&
(P.z >= (-0.5 - error)) && (P.z <= (0.5 + error)))
min_t = t;
min_i = i;
}

if (min_t < 0)
return (float) -1.0;

else {
glm::vec3 realIntersectionPoint = multiplyMV(box.transform, glm::vec4(getPointOnRay(rt, min_t), 1.0));
glm::vec3 realNormal = glm::normalize(multiplyMV(box.transform, glm::vec4(faceNormals[min_i],0.0f)));
intersectionPoint = realIntersectionPoint;
normal = realNormal;

return glm::length(r.origin - realIntersectionPoint);
}
}

//LOOK: Here's an intersection test example from a sphere. Now you just need to figure out cube and, optionally, triangle.
Expand All @@ -89,7 +152,7 @@ __host__ __device__ float sphereIntersectionTest(staticGeom sphere, ray r, glm::
float vDotDirection = glm::dot(rt.origin, rt.direction);
float radicand = vDotDirection * vDotDirection - (glm::dot(rt.origin, rt.origin) - pow(radius, 2));
if (radicand < 0){
return -1;
return (float) -1.0;
}

float squareRoot = sqrt(radicand);
Expand Down Expand Up @@ -127,6 +190,12 @@ __host__ __device__ glm::vec3 getRadiuses(staticGeom geom){
return glm::vec3(xradius, yradius, zradius);
}

__host__ __device__ glm::vec3 getRandomPointOnGeom(staticGeom geom, float randomSeed){
if (geom.type == SPHERE) { return getRandomPointOnSphere(geom, randomSeed); }
else if (geom.type == CUBE) { return getRandomPointOnCube(geom, randomSeed); }
else { return glm::vec3(0.0f, 0.0f, 0.0f); }
}

//LOOK: Example for generating a random point on an object using thrust.
//Generates a random point on a given cube
__host__ __device__ glm::vec3 getRandomPointOnCube(staticGeom cube, float randomSeed){
Expand Down Expand Up @@ -176,8 +245,16 @@ __host__ __device__ glm::vec3 getRandomPointOnCube(staticGeom cube, float random
//TODO: IMPLEMENT THIS FUNCTION
//Generates a random point on a given sphere
__host__ __device__ glm::vec3 getRandomPointOnSphere(staticGeom sphere, float randomSeed){

thrust::default_random_engine rng(hash(randomSeed));
thrust::uniform_real_distribution<float> u01(-0.5,0.5);

float x = (float)u01(rng);
float y = (float)u01(rng);
float z = (float)u01(rng);

return glm::vec3(0,0,0);
glm::vec3 randPoint = multiplyMV(sphere.transform, glm::normalize(glm::vec4(x,y,z,1.0f)));
return randPoint;
}

#endif
Expand Down
Loading