Пример #1
0
bool SmoothMeshTriangle::intersects(const Rayd& ray, State& state) const {
  int ku = mod3[k + 1];
  int kv = mod3[k + 2];
  
  const Vector4d& O = ray.origin();
  const Vector3d& D = ray.direction();
  const Vector3d& A = m_mesh->vertices[m_index0].point;
  
  const double lnd = 1.0f / (D[k] + nu * D[ku] + nv * D[kv]);
  
  const double t = (nd - O[k] - nu * O[ku] - nv * O[kv]) * lnd;
  if (t < 0) {
    state.shadowMiss("SmoothMeshTriangle, behind ray");
    return false;
  }
  
  const double hu = O[ku] + t * D[ku] - A[ku];
  const double hv = O[kv] + t * D[kv] - A[kv];
  
  const double beta = hv * bnu + hu * bnv;
  if (beta < 0 || beta > 1) {
    state.shadowMiss("SmoothMeshTriangle, beta not in [0, 1]");
    return false;
  }
  
  const double gamma = hu * cnu + hv * cnv;
  if (gamma < 0 || (beta + gamma) > 1) {
    state.shadowMiss("SmoothMeshTriangle, gamma < 0 or beta + gamma > 1");
    return false;
  }
  
  state.shadowHit("SmoothMeshTriangle");
  return true;
}
Пример #2
0
bool Sphere::intersects(const Rayd& ray, State& state) const {
  const Vector3d& o = ray.origin() - m_origin, d = ray.direction();
  
  double od = o * d, dd = d * d;
  double discriminant = od * od - dd * (o * o - m_radius * m_radius);
  
  if (discriminant < 0) {
    state.shadowMiss(this, "Sphere, ray miss");
    return false;
  } else if (discriminant > 0) {
    double discriminantRoot = sqrt(discriminant);
    double t1 = (-od - discriminantRoot) / dd;
    double t2 = (-od + discriminantRoot) / dd;
    if (t1 <= 0 && t2 <= 0) {
      state.shadowMiss(this, "Sphere, behind ray");
      return false;
    }
    
    state.shadowHit(this, "Sphere");
    return true;
  }
  
  state.shadowMiss(this, "Sphere, ray miss");
  return false;
}
Пример #3
0
void Display::mousePressEvent(QMouseEvent* event) {
  QtDisplay::mousePressEvent(event);
  
  Rayd ray = m_camera->rayForPixel(event->pos().x(), event->pos().y());
  if (ray.direction().isDefined()) {
    auto state = m_raytracer->rayState(ray);
  
    cout << state.hitPoint.primitive() << " - " << state.hitPoint << endl;
  }
}
Пример #4
0
Colord PhongMaterial::shade(const Raytracer* raytracer, const Rayd& ray, const HitPoint& hitPoint, State& state) const {
  auto texColor = diffuseTexture() ? diffuseTexture()->evaluate(ray, hitPoint) : Colord::black();

  Lambertian ambientBRDF(texColor, ambientCoefficient());
  Lambertian diffuseBRDF(texColor, diffuseCoefficient());

  Vector3d out = -ray.direction();
  auto color = ambientBRDF.reflectance(hitPoint, out) * raytracer->scene()->ambient();

  for (const auto& light : raytracer->scene()->lights()) {
    Vector3d in = light->direction(hitPoint.point());

    if (raytracer->scene()->intersects(Rayd(hitPoint.point(), in).epsilonShifted(), state)) {
      state.shadowHit(this, "PhongMaterial");
    } else {
      state.shadowMiss(this, "PhongMaterial");
      double normalDotIn = hitPoint.normal() * in;
      if (normalDotIn > 0.0) {
        color += (
          diffuseBRDF(hitPoint, out, in)
        + m_specularBRDF(hitPoint, out, in)
        ) * light->radiance() * normalDotIn;
      }
    }
  }

  return color;
}
Пример #5
0
void Display::mousePressEvent(QMouseEvent* event) {
  QtDisplay::mousePressEvent(event);
  
  if (event->modifiers() & Qt::ControlModifier) {
    Rayd ray = m_raytracer->camera()->rayForPixel(event->pos().x(), event->pos().y());
    if (ray.direction().isDefined()) {
      auto state = m_raytracer->rayState(ray);
  
      cout << state.hitPoint.primitive() << " - " << state.hitPoint << endl;
      cout << "maxRecursionDepth: " << state.maxRecursionDepth << endl;
      cout << "intersectionHits: " << state.intersectionHits << endl;
      cout << "intersectionMisses: " << state.intersectionMisses << endl;
      cout << "shadowIntersectionHits: " << state.shadowIntersectionHits << endl;
      cout << "shadowIntersectionMisses: " << state.shadowIntersectionMisses << endl;
      
      for (const auto& event : *state.events) {
        cout << event << endl;
      }
    }
  }
}
Пример #6
0
void Camera::render(std::shared_ptr<Raytracer> raytracer, Buffer<unsigned int>& buffer, const Recti& rect) const {
  if (isCancelled())
    return;
  
  auto plane = viewPlane();

  for (ViewPlane::Iterator pixel = plane->begin(rect), end = plane->end(rect); pixel != end; ++pixel) {
    Colord pixelColor;
    for (const auto& sample : plane->sampler()->sampleSet()) {
      Rayd ray = rayForPixel(pixel.pixel() + sample);
      if (ray.direction().isDefined()) {
        State state;
        pixelColor += raytracer->rayColor(ray, state);
      }
    }
    
    plot(buffer, rect, pixel, pixelColor);
    
    if (isCancelled())
      break;
  }
}
bool DirectionalLight::getShadow (Intersection& iInfo, ShapeGroup* root)
{
  /*
   * To determine if an intersection is in shadow or not with respect
   * to a light, cast a ray from the intersection towards the light
   * and see if it intersects anything.
   */

	
	if (direction.dot(iInfo.normal)>0)
		return true;
	// otherwise we'll check
	Rayd shadowRay;
	shadowRay.setDir(direction*-1);
	shadowRay.setPos(iInfo.iCoordinate + iInfo.normal * EPSILON);
	Intersection tmpInfo;
	tmpInfo.theRay=shadowRay;
	if (root->intersect(tmpInfo) > EPSILON)
		return true;
	return false;

}
Пример #8
0
Colord TransparentMaterial::shade(const Raytracer* raytracer, const Rayd& ray, const HitPoint& hitPoint, State& state) const {
  Vector3d out = -ray.direction();
  Vector3d in;
  Colord reflectedColor = m_reflectiveBRDF.sample(hitPoint, out, in);
  Rayd reflected(hitPoint.point(), in);
  
  if (m_specularBTDF.totalInternalReflection(ray, hitPoint)) {
    return raytracer->rayColor(reflected.epsilonShifted(), state);
  } else {
    auto color = PhongMaterial::shade(raytracer, ray, hitPoint, state);
    
    Vector3d trans;
    Colord transmittedColor = m_specularBTDF.sample(hitPoint, out, trans);
    Rayd transmitted(hitPoint.point(), trans);
    
    state.recordEvent("TransparentMaterial: Tracing reflection");
    color += reflectedColor * raytracer->rayColor(reflected.epsilonShifted(), state) * fabs(hitPoint.normal() * in);
    
    state.recordEvent("TransparentMaterial: Tracing transmission");
    color += transmittedColor * raytracer->rayColor(transmitted.epsilonShifted(), state) * fabs(hitPoint.normal() * trans);
    
    return color;
  }
}