/** * Compute the diffusely reemited light data and place the result into reemited. * localBasis : the object localBasis at the computation point. * surfaceCoordinate : the surface coordinate (texture coordinate) of the computation * point on the object. * incident : the incident ray (light ray) * view : the view ray (from the camera or bounced) * incidentLight : the incident light comming from the incident ray. * reemitedLight : the light reemited into the view direction (result will be placed * here). */ void RoughLambertianBRDF::getDiffuseReemited(const Basis& localBasis, const Point2D& surfaceCoordinate, const LightVector& incidentLight, LightVector& reemitedLight) { Vector view = reemitedLight.getRay().v; Vector incident = incidentLight.getRay().v; Real cosOi = -incident.dot(localBasis.k); Real cosOv = -view.dot(localBasis.k); if(cosOi <= 0) { reemitedLight.clear(); return; } if(cosOi>=1.0) cosOi=1.0; if(cosOv>=1.0) cosOv=1.0; Real Oi = std::acos(cosOi); Real Ov = std::acos(cosOv); Real Pi = std::atan2(incident.dot(localBasis.j), incident.dot(localBasis.i)); Real Pv = std::atan2(view.dot(localBasis.j), view.dot(localBasis.i)); Real factor = OrenNayarFormula::orenNayarReflectance(Oi, Pi, Ov, Pv, _roughness); for(unsigned int i=0; i<reemitedLight.size(); i++) reemitedLight[i].setRadiance(incidentLight[i].getRadiance()*_spectrum[incidentLight[i].getIndex()]*factor); reemitedLight.changeReemitedPolarisationFramework(localBasis.k); }
/** * 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); }
void RoughLambertianBRDF::getDiffuseReemitedFromAmbiant(const Basis& localBasis, const Point2D& surfaceCoordinate, LightVector& reemitedLight, const Spectrum& incident) { reemitedLight.clear(); reemitedLight.changeReemitedPolarisationFramework(localBasis.k); //// the same in all directions //for(unsigned int i=0; i<reemitedLight.size(); i++) { // reemitedLight[i].setRadiance(incident[i] * _spectrum[i] ); //} //reemitedLight.changeReemitedPolarisationFramework(localBasis.k); }
/** * Compute the diffusely reemited light data and place the result into reemited. * localBasis : the object localBasis at the computation point. * surfaceCoordinate : the surface coordinate (texture coordinate) of the computation * point on the object. * incident : the incident ray (light ray) * view : the view ray (from the camera or bounced) * incidentLight : the incident light comming from the incident ray. * reemitedLight : the light reemited into the view direction (result will be placed * here). */ void BeckmannBRDF::getDiffuseReemited(const Basis& localBasis, const Point2D& surfaceCoordinate, const LightVector& incidentLight, LightVector& reemitedLight) { const Vector& incident = incidentLight.getRay().v; const Vector& view = reemitedLight.getRay().v; //Computing the micro normal Vector microNormal; microNormal.setsum(incident, view); microNormal.mul(-1.0); microNormal.normalize(); //Computing some cosinuses and sinuses Real cosLN = -localBasis.k.dot(incident); // incident and normal Real cosVN = -localBasis.k.dot(view); // view and normal Real cosHN = localBasis.k.dot(microNormal); // micro normal and normal Real cosLH = -microNormal.dot(incident); // incident and micro normal Real cosVH = -microNormal.dot(view); // view and micro normal //Compute Beckmann and Shadowing&masking coeficients Real beckmann = BeckmannRoughnessFormula::BeckmannDistribution(cosHN, _roughness); Real shadmask = BeckmannRoughnessFormula::BeckmannShadowMasking(cosLN, cosVN, cosVH, cosHN); //Setting the polarisation framework LightVector localIncidentLight(incidentLight); localIncidentLight.changeIncidentPolarisationFramework(microNormal); localIncidentLight.flip(); reemitedLight.changeReemitedPolarisationFramework(microNormal); if(cosVN <=0.001 || cosLN <=0.001) { reemitedLight.clear(); return; } //Computing reflectances for each wavelength for(unsigned int i=0; i<localIncidentLight.size(); i++) { Real ROrth, RPara; getReflectance(cosLH, localIncidentLight[i].getIndex(), ROrth, RPara); reemitedLight[i].applyReflectance(localIncidentLight[i], RPara*beckmann*shadmask, ROrth*beckmann*shadmask); } }
void BeckmannBRDF::getDiffuseReemitedFromAmbiant(const Basis& localBasis, const Point2D& surfaceCoordinate, LightVector& reemitedLight, const Spectrum& incident) { const Vector& light = localBasis.k; const Vector& view = reemitedLight.getRay().v; //Computing the micro normal Vector microNormal; microNormal.setsum(light, view); microNormal.mul(-1.0); microNormal.normalize(); //Computing some cosinuses and sinuses Real cosLN = -localBasis.k.dot(light); // light and normal Real cosVN = -localBasis.k.dot(view); // view and normal Real cosHN = localBasis.k.dot(microNormal); // micro normal and normal Real cosLH = -microNormal.dot(light); // light and micro normal Real cosVH = -microNormal.dot(view); // view and micro normal //Compute Beckmann and Shadowing&masking coeficients Real beckmann = BeckmannRoughnessFormula::BeckmannDistribution(cosHN, _roughness); Real shadmask = BeckmannRoughnessFormula::BeckmannShadowMasking(cosLN, cosVN, cosVH, cosHN); if(cosVN <=0.001 ) { reemitedLight.clear(); return; } for(unsigned int wl=0; wl < reemitedLight.size(); wl++) { Real ROrth, RPara; getReflectance(cosLH, wl, ROrth, RPara); ROrth *= beckmann * shadmask; RPara *= beckmann * shadmask; reemitedLight[wl].setRadiance(incident[wl] /** cosVN*/ * 0.5 * (ROrth + RPara)); } reemitedLight.changeReemitedPolarisationFramework(microNormal); }
/** * Compute the absorption of a light ray through the medium. */ inline void Medium::transportLight(LightVector& light) const { if(isOpaque) { light.clear(); return; } if(useLambertianModel) { for(unsigned int i=0; i<light.size(); i++) light[i].mul(t[light[i].getIndex()]); } if(useFresnelModel) { for(unsigned int i=0; i<light.size(); i++) { Real a = DielectricFormula::dielectricAbsorption(light.getDistance(), GlobalSpectrum::getWaveLength(light[i].getIndex())*1E-9, k[light[i].getIndex()]); light[i].mul(a); } } }