Пример #1
0
/**
 * 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);
}
Пример #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);
  }
}
Пример #3
0
/**
 * 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);
  }
}
Пример #4
0
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);
}
Пример #5
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);
  }
}