Point PlaneCoordMapper::getCoords(const Intersection& hit) const { /* //assumes local hit = hit - center; Vector dir = normal; Point center = Point::rep(0); Point local = hit.hitPoint(); if(dot(dir, local - center) > 0) { dir = -dir; } //intersect ray (local, n) to plane (center, n) float temp = dot(dir , -dir); float distance = dot((center - local), -dir) / temp; Point hp = local + ((dir * distance) / dir.length()); //calculate uv float u = (hp - center).length() * dot((hp - center).normalize(), e1.normalize()) / e1.length(); float v = (hp - center).length() * dot((hp - center).normalize(), e2.normalize()) / e2.length(); */ //Vector localV = hit.local() - Point::rep(0); Vector localV = hit.hitPoint() - Point::rep(0); float dist = localV.length(); float u = dist * (dot(e1, localV) / dist / e1.length()) / e1.length(); float v = dist * (dot(e2, localV) / dist / e2.length()) / e2.length(); return Point(u, v, 0); }
RGBColor RecursiveRayTracingIntegrator::getRadianceRec(const Ray& ray, int counter) const { if(counter > 6) { return RGBColor::rep(0); } Intersection intersect = world->scene->intersect(ray); if(intersect) { RGBColor color = RGBColor::rep(0.1f) + intersect.solid->material->getEmission( intersect.solid->texMapper->getCoords(intersect), intersect.normal(), -ray.d); Point p = intersect.hitPoint(); if(intersect.solid->material->useSampling() == Material::Sampling::SAMPLING_NOT_NEEDED) { for(int i = 0; i < world->light.size();i++) { LightHit lh = world->light[i]->getLightHit(p); float n1 = dot(ray.o-p, intersect.normal()); float n2 = dot(lh.direction, intersect.normal()); if((n1 > 0 && n2 > 0) || (n1 < 0 && n2 < 0)) { Ray shadowRay = Ray(p, lh.direction); Intersection shadowIntrsct = world->scene->intersect(shadowRay, lh.distance); if(!shadowIntrsct) { RGBColor sourceColor = world->light[i]->getIntensity(lh); RGBColor reflectInt = intersect.solid->material->getReflectance(intersect.solid->texMapper->getCoords(intersect), intersect.normal(), -ray.d, lh.direction); RGBColor reflectColor = sourceColor * reflectInt; color = color + reflectColor; //color = color + reflectInt; } } } } else if(intersect.solid->material->useSampling() == Material::Sampling::SAMPLING_ALL) { Material::SampleReflectance sample = intersect.solid->material->getSampleReflectance(intersect.solid->texMapper->getCoords(intersect), intersect.normal(), -ray.d); RGBColor refColor = getRadianceRec(Ray(p, sample.direction), counter + 1); color = color + (refColor * sample.reflectance); } else if(intersect.solid->material->useSampling() == Material::Sampling::SAMPLING_SECONDARY) { for(int i = 0; i < world->light.size();i++) { LightHit lh = world->light[i]->getLightHit(p); float n1 = dot(ray.o-p, intersect.normal()); float n2 = dot(lh.direction, intersect.normal()); if((n1 > 0 && n2 > 0) || (n1 < 0 && n2 < 0)) { Ray shadowRay = Ray(p, lh.direction); Intersection shadowIntrsct = world->scene->intersect(shadowRay, lh.distance); if(!shadowIntrsct) { RGBColor sourceColor = world->light[i]->getIntensity(lh); RGBColor reflectInt = intersect.solid->material->getReflectance(intersect.solid->texMapper->getCoords(intersect), intersect.normal(), -ray.d, -lh.direction); RGBColor reflectColor = sourceColor * reflectInt; color = color + reflectColor; } } } Material::SampleReflectance sample = intersect.solid->material->getSampleReflectance(intersect.solid->texMapper->getCoords(intersect), intersect.normal(), -ray.d); RGBColor refColor = getRadianceRec(Ray(intersect.hitPoint(), sample.direction), counter + 1); color = color + (refColor * sample.reflectance); } return color; } return RGBColor::rep(0); }
RGBColor RayMarchingIntegrator::getRadiance(const Ray& ray) const { Intersection intersection = world->scene->intersect(ray); if (intersection) { RGBColor color = RGBColor(0, 0, 0); Point local; if (intersection.solid->texMapper == nullptr) { local = WorldMapper(Float4::rep(1)).getCoords(intersection); } else { local = intersection.solid->texMapper->getCoords(intersection); } RGBColor emission; if (intersection.solid->material == nullptr) { float greyScale = fabs(dot(intersection.ray.d, intersection.normalVector)); emission = RGBColor(greyScale, greyScale, greyScale); } else { emission = intersection.solid->material->getEmission(local, intersection.normalVector, -ray.d); } Material::SampleReflectance sample; Ray sampleRay; switch (intersection.solid->material->useSampling()) { case Material::SAMPLING_NOT_NEEDED: for (int i = 0; i < world->light.size(); i++) { LightHit shadowRay = world->light[i]->getLightHit(intersection.hitPoint()); if (dot(intersection.normalVector, shadowRay.direction) > 0) { Ray shadow = Ray(intersection.hitPoint() + EPSILON * shadowRay.direction, shadowRay.direction); //TODO more epsilon? Intersection shadowRayIntersection = world->scene->intersect(shadow, shadowRay.distance); if (!shadowRayIntersection) { RGBColor reflectance; if (intersection.solid->material == nullptr) { reflectance = RGBColor(0.5, 0.5, 0.5); } else { if(intersection.solid->isFracLand){ reflectance = intersection.solid->material->getReflectance( intersection.hitPoint(), intersection.normalVector, -ray.d, shadowRay.direction); } else{ reflectance = intersection.solid->material->getReflectance(local, intersection.normalVector, -ray.d, shadowRay.direction); } // reflectance = intersection.solid->material->getReflectance(local, // intersection.normalVector, -ray.d, shadowRay.direction); } RGBColor intensity = world->light[i]->getIntensity(shadowRay); RGBColor lightSourceColor = (reflectance * intensity); color = color + lightSourceColor; } } } break; case Material::SAMPLING_ALL: sample = intersection.solid->material->getSampleReflectance(intersection.hitPoint(), intersection.normalVector, -intersection.ray.d); // sample = intersection.solid->material->getSampleReflectance(local, intersection.normalVector, // -intersection.ray.d); sampleRay = Ray(intersection.hitPoint() + EPSILON * sample.direction, sample.direction); if (MarchRecursionDepth > MAX_RECURSION_DEPTH) { MarchRecursionDepth = 0.f; } else { MarchRecursionDepth++; color = color + getRadiance(sampleRay) * sample.reflectance; } break; case Material::SAMPLING_SECONDARY: for (int i = 0; i < world->light.size(); i++) { LightHit shadowRay = world->light[i]->getLightHit(intersection.hitPoint()); if (dot(intersection.normalVector, shadowRay.direction) > 0) { Ray shadow = Ray(intersection.hitPoint() + EPSILON * intersection.normal(), shadowRay.direction); Intersection shadowRayIntersection = world->scene->intersect(shadow, shadowRay.distance); if (!shadowRayIntersection) { RGBColor reflectance = intersection.solid->material->getReflectance(local, intersection.normalVector, -ray.d, shadowRay.direction); RGBColor emission = intersection.solid->material->getEmission(local, intersection.normalVector, -ray.d); RGBColor intensity = world->light[i]->getIntensity(shadowRay); RGBColor lightSourceColor = (reflectance * intensity); color = color + lightSourceColor; } } } sample = intersection.solid->material->getSampleReflectance(local, intersection.normalVector, -intersection.ray.d); if (sample.direction != Vector(0, 0, 1) && sample.reflectance != RGBColor(0.f, 0.f, 0.f)) { sampleRay = Ray(intersection.hitPoint() + EPSILON * sample.direction, sample.direction); if (MarchRecursionDepth > MAX_RECURSION_DEPTH) { MarchRecursionDepth = 0; } else { MarchRecursionDepth++; color = color + getRadiance(sampleRay) * sample.reflectance; } } break; default: break; } MarchRecursionDepth = 0; if (world->fogs.size() == 0) { return color + emission; } /* RGBColor fog = world->fog->modulateColor(ray.o, intersection.hitPoint()); float transmittance = world->fog->transmittance(ray.o, intersection.hitPoint()); return (color + emission) * transmittance + (1 - transmittance) * fog;*/ RGBColor fogColor = RGBColor::rep(0); for (int i = 0; i < world->fogs.size(); i++) { Intersection i1 = world->fogs[i]->getPrimitive()->intersect(ray, intersection.distance); if (i1) { float transmittance = 1; float enterDistance = 0; //i1.distance; //float exitDistance = i1.exitDistance == i1.distance ? intersection.distance : i1.exitDistance; float exitDistance = intersection.distance; //std::min(i1.exitDistance, intersection.distance); while (enterDistance < exitDistance) { float stepSize = std::min(STEP_SIZE, exitDistance - enterDistance); Point deltaPoint = ray.o + (enterDistance + stepSize / 2) * ray.d; float deltaTransmittance = exp( -world->fogs[i]->getDensity(deltaPoint) * stepSize); RGBColor deltaColor = RGBColor(0, 0, 0); for (int i = 0; i < world->light.size(); i++) { LightHit shadowRay = world->light[i]->getLightHit( deltaPoint); Ray shadow = Ray( deltaPoint + EPSILON * shadowRay.direction, shadowRay.direction); Intersection shadowRayIntersection = world->scene->intersect(shadow, shadowRay.distance); if (!shadowRayIntersection) { RGBColor intensity = world->light[i]->getIntensity( shadowRay); RGBColor lightSourceColor = (intensity); deltaColor = (deltaColor + lightSourceColor); } } fogColor = fogColor + transmittance * (1 - deltaTransmittance) * deltaColor * world->fogs[i]->getColor(deltaPoint); transmittance *= deltaTransmittance; enterDistance += STEP_SIZE; } //LOG_DEBUG("fogcolor " << fogColor.r << ", " << fogColor.g << ", " << fogColor.b); } } return (color + emission) + fogColor; } else { //if (!world->fog) return RGBColor(0, 0, 0); /*Intersection i1 = world->fog->getPrimitive()->intersect(ray); if (i1) { RGBColor fogColor = RGBColor::rep(0); float transmittance = 1; float enterDistance = i1.distance; //float exitDistance = i1.exitDistance == i1.distance ? intersection.distance : i1.exitDistance; float exitDistance = std::min(i1.exitDistance, intersection.distance); while (enterDistance < exitDistance) { float stepSize = std::min(STEP_SIZE, exitDistance - enterDistance); Point deltaPoint = ray.o + (enterDistance + stepSize / 2) * ray.d; float deltaTransmittance = exp(-world->fog->getDensity(deltaPoint) * stepSize); RGBColor deltaColor = RGBColor(0, 0, 0); for (int i = 0; i < world->light.size(); i++) { LightHit shadowRay = world->light[i]->getLightHit(deltaPoint); if (dot(intersection.normalVector, shadowRay.direction) > 0) { Ray shadow = Ray(deltaPoint + EPSILON * shadowRay.direction, shadowRay.direction); Intersection shadowRayIntersection = world->scene->intersect(shadow, shadowRay.distance); if (!shadowRayIntersection) { RGBColor reflectance = world->fog->getColor(deltaPoint); RGBColor intensity = world->light[i]->getIntensity(shadowRay); RGBColor lightSourceColor = (reflectance * intensity); deltaColor = (deltaColor + lightSourceColor); } } } fogColor = fogColor + transmittance * (1 - deltaTransmittance) * deltaColor; transmittance *= deltaTransmittance; enterDistance += STEP_SIZE; } return fogColor; } RGBColor fog = world->fog->getColor(intersection.hitPoint());*/ //return fog; } }
Point WorldMapper::getCoords(const Intersection& hit) const { Point p = hit.hitPoint(); return Point(scale.x * p.x, scale.y * p.y, scale.z * p.z); }