/**
 * 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);
}
Ejemplo n.º 2
0
/**
 * 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);
  }
}
Ejemplo n.º 3
0
/**
 * 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);
  }
}