Beispiel #1
0
bool Transform::intersect(const Ray & r, Hit & h, float tmin)
{

	// Need to Transform Ray before do intersection

	Matrix reverseMat = transformMat;
	reverseMat.Inverse();
	
	// cout << "Original Origin:\t" << r.getOrigin() << endl;
	// cout << "Original Direction:\t" << r.getDirection() << endl;

	Vec4f aug_origin(r.getOrigin(), 1);
	Vec3f aug_dir = r.getDirection();

	reverseMat.Transform(aug_origin);
	reverseMat.TransformDirection(aug_dir);

	// cout << "Now Origin:\t" << r.getOrigin() << endl;
	// cout << "Now Direction:\t" << r.getDirection() << endl;

	// aug_dir.Normalize();
	Ray transRay(aug_dir, Vec3f(aug_origin[0], aug_origin[1], aug_origin[2]));
	if ( !( object -> intersect(transRay, h, tmin) ) )
		return false;
	
	// After transforming Ray, we need to transform Normal
	Matrix transposeRevMat = reverseMat;
	transposeRevMat.Transpose();
	Vec3f hn = h.getNormal();
	transposeRevMat.Transform(hn);
	hn.Normalize();

	h.set(h.getT(), NULL, hn, r);

	return true;

}
Beispiel #2
0
void shade(const Scene * scene, const int level, const C_FLT weight,
           const Ray &ray, Intercept * intercepts, Color * color) {
  Material * entryMat = intercepts[0].material,
           * hitMat = intercepts[0].enter?
                      intercepts[0].primitive->material: ray.medium;

  C_FLT specWeight = hitMat->specular.magnitude() * weight,
        transWeight = hitMat->transmission.magnitude() * weight;

  Vector3D specDir, transDir, normal;
  std::vector<P_FLT> mapping;

  Point3D interceptPoint = ray.rayPoint(intercepts[0].t);

  intercepts[0].primitive->getIntersect(interceptPoint, &normal, &mapping);
  if (dotProduct(ray.dir, normal) > 0.0f) {
    normal.negate();
  }
  specularDirection(ray.dir, normal, &specDir);
  bool transmission = transmissionDirection(entryMat, hitMat, ray.dir, normal,
                                            &transDir);

  *color += scene->ambience * hitMat->ambience;

  for (std::vector<Light *>::const_iterator itr = scene->lights.begin();
       itr != scene->lights.end(); itr++) {
    Vector3D pointToLight = (*itr)->orig - interceptPoint;
    P_FLT distanceToLight = pointToLight.normalize();
    Ray rayToLight(interceptPoint, pointToLight, NULL);

    P_FLT lightDotNormal = dotProduct(pointToLight, normal);
    if (fGreaterZero(lightDotNormal) &&
        fGreaterZero(shadow(scene, rayToLight, distanceToLight))) {
      // Light source diffuse reflection
      *color += (*itr)->color * hitMat->diffuse * lightDotNormal;

      // Light source specular reflection
      Vector3D h = pointToLight - ray.dir;
      h.normalize();
      P_FLT specDot = dotProduct(normal, h);
      if (specDot > 0.0f) {
        *color += (*itr)->color * hitMat->specular *
                  pow(specDot, hitMat->shine);
      }
    } else if (transmission && fLessZero(lightDotNormal) &&
               fLessZero(shadow(scene, rayToLight, distanceToLight))) {
      // Light source specular transmission
      C_FLT refrRatio = hitMat->refraction / entryMat->refraction;
      if (!fEqual(refrRatio, 1.0f)) {
        Vector3D h_j = (-ray.dir - pointToLight * refrRatio) /
                       (refrRatio - 1);
        h_j.normalize();

        // TODO(kent): Define transmission highlight coefficient
        *color += (*itr)->color * hitMat->transmission *
                  pow(dotProduct(-normal, h_j), hitMat->shine);
      }
    }
  }

  if (level < MAX_LEVEL) {
    // Other body specular reflection
    if (specWeight > MIN_WEIGHT) {
      Ray specRay(interceptPoint, specDir, entryMat);
      Color specColor;

      trace(scene, level + 1, specWeight, specRay, &specColor);
      *color += specColor * hitMat->specular;
    }

    // Other body specular transmission
    if (transWeight > MIN_WEIGHT) {
      if (transmission) {
        Ray transRay(interceptPoint, transDir, hitMat);
        Color transColor;

        trace(scene, level + 1, transWeight, transRay, &transColor);
        *color += transColor * hitMat->transmission;
      } else {
        // TODO(kent): Handle total internal reflection
      }
    }
  }

  if (intercepts[0].enter && intercepts[0].primitive->texture != NULL) {
    *color *= intercepts[0].primitive->getTexColor(mapping);
  }
}