Intersection Mesh::intersects(Ray ray) { Intersection ins; for (uint i = 0; i < triangles.size(); i++) { Triangle *t0 = triangles.at(i); Intersection j = t0->intersects(ray); if (!ins.hasIntersected()) { ins = j; } else if (ins.hasIntersected() && j.getIntersectionPoint() < ins.getIntersectionPoint()) { ins = j; } } return ins; }
Intersection BVHTree::searchTree(BVHNode *n, Ray r) { if (n->leaf) { return n->shape->intersects(r); } else { if (n->bbox.intersects(r)) { Intersection i = searchTree(n->left, r); Intersection j = searchTree(n->right, r); if (i.hasIntersected() && j.hasIntersected()) { return i.getIntersectionPoint() < j.getIntersectionPoint() ? i : j; } else { return i.hasIntersected() ? i : j; } } return Intersection(r); } }
SColor RayTracer::shadeIntersection(Intersection in, uint d) { if (d <= 0 || in.hasIntersected() == false) { // terminate recursion return SColor(0, 0, 0); } Vect shade(0, 0, 0); Material *mat = in.getMaterial(); float kt = mat->getTransparency(); SColor ks = mat->getSpecColor(); SColor ka = mat->getAmbColor(); SColor Cd = mat->getDiffColor(); SColor ambLight = Whitted::AmbientLightning(kt, ka, Cd); std::vector<Light *> lts = scene->getLights(); for (uint i = 0; i < lts.size(); i++) { Light *l = lts.at(i); SColor Sj = calculateShadowScalar(*l, in); shade = shade + Whitted::Illumination(l, in, Sj); } SColor reflection; if (ks.length() > 0) { Ray r = in.calculateReflection(); Intersection rin = scene->calculateRayIntersection(r); reflection = shadeIntersection(rin, d-1).linearMult(ks); } SColor refraction; if (kt > 0) { Ray r = in.calculateRefraction(); Intersection rin = scene->calculateRayIntersection(r); refraction = shadeIntersection(rin, d-1).linearMult(kt); } shade = ambLight + shade + reflection + refraction; return shade; }
SColor RayTracer::calculateShadowScalar(Light <, Intersection &in) { // cout << in.toString() << endl; Vect p = lt.getPos(); Vect ori = in.calculateIntersectionPoint();// + in.calculateSurfaceNormal().linearMult(0.0001f); Vect dir; if (lt.getType() == DIRECTIONAL_LIGHT) { dir = lt.getDir().invert(); } else { dir = p - ori; dir.normalize(); } ori = ori + dir.linearMult(0.001f); Ray shdw(ori, dir); Intersection ins = scene->calculateRayIntersection(shdw); Material *mat = ins.getMaterial(); if (!ins.hasIntersected()) { // The point is in direct light return SColor(1, 1, 1); } else if (mat->getTransparency() <= 0.00000001) { // The material is fully opaque Vect pos = ins.calculateIntersectionPoint(); if (lt.getType() == DIRECTIONAL_LIGHT || ori.euclideanDistance(pos) < ori.euclideanDistance(lt.getPos())) { // The ray intersects with an object before the light source return SColor(0, 0, 0); } else { // The ray intersects with an object behind the lightsource // or a direction light, thus fully in light return SColor(1, 1, 1); } } else { // The shape is transparent // Normalize the color for this material, and recursively trace for other // transparent objects SColor Cd = mat->getDiffColor(); float m = max(Cd.R(), max(Cd.G(), Cd.B())); Cd.R(Cd.R()/m); Cd.G(Cd.G()/m); Cd.B(Cd.B()/m); SColor Si = Cd.linearMult(mat->getTransparency()); return Si.linearMult(calculateShadowScalar(lt, ins)); } }