So I was tasked to create a model of the Cornell Box. I've managed to do everything up until casting shadows, in which case some shadows are cast when there should not be any. Here are pictures of what it looks like now and a larger picture of what it should look like:
I've found that for some reason, the box walls are also casting shadows.
A quick run-down of how it works: we have a pinhole camera which casts rays out and finds the nearest collision point, which is everything you're seeing. It saves these points as well as the distance from some start pt (camera in this case) to the collision point in a pre-defined data structure called an Intersection. It then uses this data to calculate the distance away from the light to create the intensities in lighting. The same method that is used to find the nearest collision point is used to find the nearest object for shadows as well using the original collision point as the start and the light source as the direction of the ray vector.
I've narrowed down the problem to raytracing; when checking to see if there are any objects to cast shadows from from say the upper-right region of the back gray wall, the cyan ceiling is picked up at a point from the same side of the light. E.g. say the light source is in the middle and the original point is on our right side of the light. The method somehow picks up a point that is on the same side of the light when the vector should be going straight through the light source and end somewhere on our left side.
Here is my source code for the functions in question:
bool ClosestIntersection( vec3 start, vec3 dir, const vector<Triangle>& triangles, Intersection& it ) {
vec3 least;
vec3 e1, e2, b, v0;
mat3 A;
least[0] = m;
int index = triangles.size()-1;
for(int i = 0; i < int(triangles.size()); i++) {
v0 = triangles[i].v0;
e1 = triangles[i].v1 - v0;
e2 = triangles[i].v2 - v0;
b = start - v0;
A = mat3( -dir, e1, e2);
if(!getInverse(A,b)) {continue;}
vec3 x = A * b;
if(x[0] <= least[0] && x[1] + x[2] <= 1.f && x[1] >= 0.f && x[2] >= 0.f && x[0] >= 0.00001f) {
least = x;
index = i;
}
}
if (least[0] == m) {
return false;
}
else {
it.position = least[0] * dir + start;
const vec3 t = it.position-start;
it.distance = sqrt(t[0]*t[0] + t[1]*t[1] + t[2]*t[2]);
it.triangleIndex = index;
return true;
}
}
vec3 DirectLight( const Intersection& i ){
const Triangle T = triangles[i.triangleIndex];
const vec3 r = lightPos - i.position;
const float dist = sqrt(r[0]*r[0] + r[1]*r[1] + r[2]*r[2]);
Intersection t;
t.distance = dist;
t.position = i.position;
t.triangleIndex = i.triangleIndex;
//ClosestIntersection( i.position, lightPos, triangles, t);
/*
if(!ClosestIntersection( lightPos, i.position, triangles, t)) {return vec3(1,0,0);}
else { return vec3(0,0,0); } */
if(ClosestIntersection( i.position, lightPos, triangles, t) && (dist-t.distance > 1.f)) {
return vec3(0,0,0);
} else {
const vec3 B = 14.f * T.color * (float(max(dot(r,T.normal),float(0)) / float(4*3.14 * dist* dist)));
return B;
}
}
I have spent over twelve hours trying to find this problem. Even my lecturer can't figure out the problem. Any help would be much appreciated!