shared_ptr<Surfel> RayTracer::castRay(const Ray& ray,float maxDistance,bool anyHit) const { // Distance from P to X float distance(maxDistance); shared_ptr<Surfel> surfel; if (m_settings.useTree) { // Treat the triTree as a tree surfel = m_triTree.intersectRay(ray, distance, anyHit); } else { // Treat the triTree as an array Tri::Intersector intersector; for (int t = 0; t < m_triTree.size(); ++t) { const Tri& tri = m_triTree[t]; intersector(ray, m_triTree.cpuVertexArray(), tri, anyHit, distance); } surfel = intersector.surfel(); } return surfel; }
void Raytracer::forwardTrace(Photon* photon, const int bouncesLeft, const int numberOfPhotons) { if (bouncesLeft > 0) { Tri::Intersector intersector; float distance = inf(); Ray photonRay(photon->position, photon->direction); if (_triTree.intersectRay(photonRay, intersector, distance)) { Color3 pixelColor; Vector3 position, normal; Vector2 texCoord; intersector.getResult(position, normal, texCoord); photon->position = position + normal * 0.0001f; Photon* photonCopy = new Photon(photon); //if (bouncesLeft != _settings._forwardBounces) { _photonMap->insert(photon); } SurfaceSample surfaceSample(intersector); if (scatter(intersector, photonCopy)) { forwardTrace(photonCopy, bouncesLeft - 1, numberOfPhotons); } } } }
shared_ptr<Surfel> RayTracer::castRay(const Point3& X, const Vector3& w, float& distance, bool anyHit) const { // Distance from P to X shared_ptr<Surfel> surfel; const Ray ray(X, w); if (m_settings.useTree) { // Treat the triTree as a tree surfel = m_triTree.intersectRay(ray, distance, anyHit); // if(!isNull(surfel)) { // if(surfel->material->name() == "mirror") { // } // } } else { // Treat the triTree as an array Tri::Intersector intersector; for (int t = 0; t < m_triTree.size(); ++t) { const Tri& tri = m_triTree[t]; intersector(ray, m_triTree.cpuVertexArray(), tri, anyHit, distance); } surfel = intersector.surfel(); } return surfel; }
Color3 Raytracer::shadePixel(const Tri::Intersector& intersector, const Ray& ray, int backwardBouncesLeft) const { Color3 pixelColor; Vector3 position, normal; Vector2 texCoord; intersector.getResult(position, normal, texCoord); SurfaceSample surfaceSample(intersector); if (_settings._useSuperBSDF) { if(_settings._useDirectShading) { pixelColor = shadeDirectBSDF(surfaceSample, ray); } pixelColor += shadeSpecularBSDF(surfaceSample, -ray.direction(), backwardBouncesLeft); if (_settings._usePhotonMap) { pixelColor += shadeIndirectIllumination(surfaceSample); } } else { pixelColor = myShadePixel(intersector, ray, backwardBouncesLeft); } return pixelColor; }
Color3 Raytracer::myShadePixel(const Tri::Intersector& intersector, const Ray& ray, int backwardBouncesLeft) const { ray; backwardBouncesLeft; Vector3 position, normal; Vector2 texCoord; intersector.getResult(position, normal, texCoord); SurfaceSample surfaceSample(intersector); Color3 lightContribution(0,0,0); for (int i = 0; i < _currentScene->lighting()->lightArray.length(); ++i) { GLight& light = _currentScene->lighting()->lightArray[i]; const float lightDistance = light.distance(position); const Power3 power = light.power().rgb(); check(power.average()); const float lightArea = 4 * pif() * lightDistance * lightDistance; const Color3 kx = surfaceSample.lambertianReflect; const Vector3 light_in = (light.position.xyz() - position).unit(); const float lightIn_dot_normal = light_in.dot(normal); // Spotlight if (!isInSpotlight(light, light_in)) { continue; } if (isInShadow(surfaceSample, light_in, lightDistance)) { continue; } Color3 fx(0, 0, 0); if (lightIn_dot_normal > 0) { fx = kx / pif(); } lightContribution += (power / lightArea) * lightIn_dot_normal * fx; } return lightContribution; }