Ejemplo n.º 1
0
cv::Vec3f BlinnMaterial::brdf(const HitRecord &hit, QVector3D direction) const
{
    QVector3D normal = hit.getSurfaceNormal();
    normal.normalize();
    QVector3D wo = -hit.getRay().getDirection().normalized();
    QVector3D wi = -direction.normalized();
    if(signum(QVector3D::dotProduct(normal, wo)) != signum(QVector3D::dotProduct(normal, wi)))
    {
        return cv::Vec3f();
    }
    if(QVector3D::dotProduct(normal, wo) < 0) normal *= -1;
    QVector3D wh = wi + wo;
    wh.normalize();
    return kd * (1 / M_PI) + ks * D(wh, normal) * G(wi, wo, normal) / (4 * QVector3D::dotProduct(wo, normal) * QVector3D::dotProduct(wi, normal));
}
Ejemplo n.º 2
0
QVector3D BlinnMaterial::outDirection(const HitRecord &hit, Sample s, float &pdf, cv::Vec3f &brdf) const
{
    QVector3D normal = hit.getSurfaceNormal();
    normal.normalize();
    QVector3D wo = -hit.getRay().getDirection().normalized();
    if(QVector3D::dotProduct(normal, wo) < 0) normal *= -1;
    QVector3D wh = s.getCosinePowerWeightedDirection(normal, pdf, exponent);
    if(QVector3D::dotProduct(wo, wh) < 0)
    {
      pdf = 0;
      brdf = cv::Vec3f();
      return QVector3D();
    }
    //if(QVector3D::dotProduct(wh, normal) < 0) wh *= -1;
    QVector3D out = -reflect(wo, wh);
    assert(pdf >= 0);
    pdf /= 4 * std::max(QVector3D::dotProduct(wo, wh), .0001f);
    assert(pdf >= 0);
    brdf = this->brdf(hit, out);
    assert(brdf[0] >= 0 && brdf[1] >= 0 && brdf[2] >= 0);
    return out;
}
Ejemplo n.º 3
0
Path Renderer::createPath(const Ray& primaryRay, const Intersectable &scene, const Sample pathSamples[], cv::Vec3f alpha, int pathLength, float russianRoulettePdf, int russianRouletteStartIndex)
{
  Path result;
  HitRecord hit = scene.intersect(primaryRay);
  for(int i = 0; i < pathLength; i++)
  {
    if(!hit.intersects()) return result;


    float pdf;
    cv::Vec3f brdf;
    QVector3D outDirection = hit.getMaterial().outDirection(hit, pathSamples[i], pdf, brdf);
    if(hit.getMaterial().emitsLight())
    {
        result.alphaValues.push_back(alpha);
        result.hitRecords.push_back(hit);
        return result;
    }
    else if(hit.getMaterial().isSpecular())
    {
        //Try not to terminate on refractive vertices
        if(i == pathLength - 1 && pathLength < MAX_DEPTH) pathLength++;
    }
    else
    {
      result.alphaValues.push_back(alpha);
      result.hitRecords.push_back(hit);
      if(pdf == 0 || alpha == cv::Vec3f()) return result;
      float cos = fabs(QVector3D::dotProduct(outDirection.normalized(), hit.getSurfaceNormal().normalized()));
      assert(cos >= 0 && !isnan(pdf));
      assert(pdf > 0 && !isnan(pdf));
      alpha = alpha.mul(brdf) * (cos / pdf);
      if(i > russianRouletteStartIndex) alpha *= (1 / russianRoulettePdf);
    }
    hit = scene.intersect(Ray(hit.getIntersectingPoint(), outDirection));
  }
  return result;
}