void RayTracer::calculateImagePlane() { Vect viewDir = camera.getViewDir(); Vect orthoUp = camera.getOrthoUp(); Vect cameraPos = camera.getPos(); parallelRight = viewDir.crossProduct(orthoUp); parallelUp = parallelRight.crossProduct(viewDir); parallelRight.normalize(); parallelUp.normalize(); imageCenter = cameraPos + viewDir.linearMult(scaleConst); }
Vect Triangle::surfaceNormal(Vect dir, Vect pt) { (void) pt; Vect v = getB() - getA(); Vect w = getC() - getA(); Vect N = v.crossProduct(w); N.normalize(); if (N.dotProduct(dir) > 0) N = N.linearMult(-1); return N; }
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)); } }