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)); } }
void calcVetor () { // Initialize x, y and z elements Vect vecA; Vect vecB(1, 10, 100); // Set elements vecA.set(1, 2, 3); // Get elements double x = vecA.getx(); double y = vecA.gety(); double z = vecA.getz(); Vect vecC; // Addition and subtraction of vectors vecC = vecA + vecB; vecC += vecA; vecC = vecA - vecB; vecC -= vecA; int val = 10; // Multiplication and division of a vector and a scholar vecC = vecA * val; vecC *= val; vecC = vecA / val; vecC /= val; // Cross product vecC = vecA * vecB; // Inner product double inner = vecA % vecB; // Norm double norm = vecA.norm(); // Normalization vecC = vecA.normalize(); }
Color traceRay(Ray* ray, Scene* scene, int objectCount, int lightCount, int maxBounces, double ambientLighting) { Color shaderResult (0,0,0); Ray* shadowRay = new Ray(); Ray* reflectionRay = new Ray(); RayIntersection primaryObjectHit = testRayIntersection(ray, scene, objectCount, 0, MINIMAL_DISTANCE); if(primaryObjectHit.objectId >= 0) { Object* sceneObject = scene->getObjectList().at(primaryObjectHit.objectId); // calulate brightness and specularity Color specular (0,0,0); Color diffuse (0,0,0); Color reflection (0,0,0); Vect intersectionPoint = primaryObjectHit.location; Color ambient = sceneObject->getColorAt(intersectionPoint).scale(ambientLighting); shadowRay->setOrigin(intersectionPoint); Vect normalAtIntersection = sceneObject->getNormalAt(intersectionPoint); Vect reflectionDirection = ray->getReflectingDirection(normalAtIntersection); double lightImportance = 1; if(lightCount > 1) { lightImportance = 1.0 / lightCount; } for(int lightIndex = 0; lightIndex < lightCount; lightIndex++) { Light *lightSource = scene->getLightList().at(lightIndex); Vect pointToLightVect = lightSource->getPosition().subtract(intersectionPoint); Vect lightDirection = pointToLightVect.normalize(); // Test if light is visible or hidden to render shadows double diffuseFactor = normalAtIntersection.dot(lightDirection); double specularFactor = reflectionDirection.dot(lightDirection); bool shadowed = false; if(diffuseFactor > 0) // object is facing the light source - add diffuse { // check if it is shadowed; shadowRay->setDirection(lightDirection); double lightDistance = pointToLightVect.magnitude(); shadowed = (testRayIntersection(shadowRay, scene, objectCount, lightDistance, MINIMAL_DISTANCE).objectId > -1); } if(!shadowed && diffuseFactor > 0) { diffuse = diffuse.add(sceneObject->getColorAt(intersectionPoint).scale(diffuseFactor)); } if(!shadowed && specularFactor > 0 && sceneObject->getMaterial().getRoughness() > 0) { specular = specular.add(lightSource->getColor().scale(pow(specularFactor, 10) * sceneObject->getMaterial().getRoughness())); } } if(maxBounces > 0 && sceneObject->getMaterial().getReflectivity() > 0) { reflectionRay->setOrigin(intersectionPoint); reflectionRay->setDirection(reflectionDirection); reflection = traceRay(reflectionRay, scene, objectCount, lightCount, --maxBounces, ambientLighting).scale(sceneObject->getMaterial().getReflectivity() * 0.25); } shaderResult = ambient.add(diffuse).add(specular).add(reflection).normalize(); } else { shaderResult = scene->getBackgroundColor(); } delete shadowRay; delete reflectionRay; return shaderResult; }
Vect Sphere::surfaceNormal(Vect o, Vect pt) { (void) o; Vect normal = pt - origin; normal.normalize(); return normal; }
Plane::Plane(Vect n, Vect p, Material m) { normal = n.normalize(); position = p; material = m; }
void Plane::setNormal(Vect _normal) { this->normal = _normal.normalize(); }