/** * Compute the estimated reflected radiance. * @param localBasis : the local basis at the computation point. * @param surfaceCoordinate : the local surface coordinate at the computation point. * @param object : the surface that reflect the light. * @param radius : the initial radius search for the nearest photon photon search pass. * @param nb_poton : the number of nearest pĥoton to take count in the computation. * @param lightdata : the reflected light data to compute. */ inline void MultispectralPhotonMap::getEstimation(const Basis& localBasis, const Point2D& surfaceCoordinate, Object& object, Real radius, int nb_photon, LightVector& lightdata) { lightdata.clear(); //Get the nearest photons std::vector<MultispectralPhoton*> photons; Real r2 = _tree.getNearestNeighbor(localBasis.o, nb_photon, radius, localBasis.k, photons); if(r2==0.0) return; Real invarea = 1.0/(M_PI*r2); Real photonPower = _photonPower*invarea; LightVector incident; LightVector reemited; reemited.initGeometricalData(lightdata); for(unsigned int i=0; i<photons.size(); i++) { Real weight = photonPower/std::abs(photons[i]->direction.dot(localBasis.k)); reemited.initSpectralData(lightdata); incident.initSpectralData(lightdata); incident.changeReemitedPolarisationFramework(localBasis.k); for(unsigned int k=0; k<lightdata.size(); k++) incident[k].setRadiance(weight*photons[i]->radiance[lightdata[k].getIndex()]); incident.setRay(photons[i]->position, photons[i]->direction); object.getDiffuseReemited(localBasis, surfaceCoordinate, incident, reemited); lightdata.add(reemited); } lightdata.changeReemitedPolarisationFramework(localBasis.k); }
/** * Compute the secondary rays for diffuse reflexion and place them into the subrays * vector. * localBasis : the local base on the object at the computation point. * surfaceCoordinate : the surface coordinate (texture coordinate) of the computation * point on the object. * view : the view ray (from the camera or bounced) * nbRays : the number of wanted ray. It is an indicative information. * subrays : the vector were the secondaries rays will be put. * weights : the weights corresponding to the distribution */ void RoughLambertianBRDF::getRandomDiffuseRay(const Basis& localBasis, const Point2D& surfaceCoordinate, LightVector& reemitedLight, unsigned int nbRays, std::vector<LightVector>& subrays) { Vector normal=localBasis.k; if(normal.dot(reemitedLight.getRay().v)>0) normal.mul(-1); for(unsigned int i=0; i<nbRays; i++) { Vector incident; Real norm2; Real cosOi; do{ incident[0]=rand()*2.0/RAND_MAX - 1.0; incident[1]=rand()*2.0/RAND_MAX - 1.0; incident[2]=rand()*2.0/RAND_MAX - 1.0; norm2=incident.square(); incident.normalize(); cosOi=incident.dot(normal); }while(norm2>cosOi*cosOi || cosOi<=0.0); LightVector subray; subray.setRay(localBasis.o, incident); subray.changeReemitedPolarisationFramework(normal); subray.initSpectralData(reemitedLight); subray.setWeight(1.0/M_PI); subrays.push_back(subray); } }
/** * Compute the secondary rays for diffuse reflexion and place them into the subrays * vector. * localBasis : the local base on the object at the computation point. * surfaceCoordinate : the surface coordinate (texture coordinate) of the computation * point on the object. * view : the view ray (from the camera or bounced) * nbRays : the number of wanted ray. It is an indicative information. * subrays : the vector were the secondaries rays will be put. * weights : the weights corresponding to the distribution */ void BeckmannBRDF::getRandomDiffuseRay(const Basis& localBasis, const Point2D& surfaceCoordinate, LightVector& reemitedLight, unsigned int nbRays, std::vector<LightVector>& subrays) { Vector view = reemitedLight.getRay().v; view.mul(-1.0); if(view.dot(localBasis.k)<0) return; for(unsigned int i=0; i<nbRays; i++) { Vector dir; Real weight; BeckmannRoughnessFormula::getBeckmannRandomRay(localBasis, view, _roughness, weight, dir); LightVector subray; subray.setRay(localBasis.o, dir); subray.initSpectralData(reemitedLight); subray.changeReemitedPolarisationFramework(localBasis.k); subray.setWeight(weight); subrays.push_back(subray); } }