void PhotonMapping::TracePhoton(const Vec3f &position, const Vec3f &direction, 
				const Vec3f &energy, int iter) {
  
  if(iter>args->num_bounces){
    return;
  }

  Hit h = Hit();
  Ray R = Ray(position, direction);
  bool intersect = raytracer->CastRay(R, h, false);
  if(!intersect){
    return;
  }
  Material *m = h.getMaterial();
  Vec3f normal = h.getNormal();
  Vec3f point = R.pointAtParameter(h.getT());
  Vec3f opDirec = direction;
  opDirec.Negate();
  opDirec.Normalize();
  Vec3f diffuse = m->getDiffuseColor(), reflec = m->getReflectiveColor();
  double diffuseAnswer = diffuse.x()+diffuse.y()+diffuse.z();
  double reflecAnswer = reflec.x()+reflec.y()+reflec.z();
  double total = reflecAnswer+diffuseAnswer;
  diffuseAnswer /= total;
  reflecAnswer /= total;
  double seed = GLOBAL_mtrand.rand();
  if(seed <= diffuseAnswer && seed >= 0){
    Vec3f newEnergy = energy * diffuse;
    Vec3f newPosition = point;
    Vec3f newDirection = Vec3f(GLOBAL_mtrand.rand(),GLOBAL_mtrand.rand(),GLOBAL_mtrand.rand());
    newDirection.Normalize();
    Photon answer = Photon(point,opDirec,newEnergy,iter+1);
    kdtree->AddPhoton(answer);
    TracePhoton(newPosition, newDirection, newEnergy, iter+1);
  }
  else if(seed>diffuseAnswer && seed <= 1){
    Vec3f newEnergy = energy * reflec;
    Vec3f newPosition = point;
    Vec3f newDirection = direction - 2 * direction.Dot3(normal) * normal;
    Photon answer = Photon(point,opDirec,newEnergy,iter+1);
    kdtree->AddPhoton(answer);
    TracePhoton(newPosition, newDirection, newEnergy, iter+1);
  }
  // ==============================================
  // ASSIGNMENT: IMPLEMENT RECURSIVE PHOTON TRACING
  // ==============================================

  // Trace the photon through the scene.  At each diffuse or
  // reflective bounce, store the photon in the kd tree.

  // One optimization is to *not* store the first bounce, since that
  // direct light can be efficiently computed using classic ray
  // tracing.



}
コード例 #2
0
ファイル: Plate.cpp プロジェクト: evanminto/tectonic-terrain
void Plate::applyForce(const Plate& other, const Overlap& overlap, double timestep) {
  Vec3f reverseVelocity = velocity;
  reverseVelocity.Negate();

  // Create friction force based on reversed velocity and the ratio of overlap area to plate area.
  // This ensures the force only stops the velocity and doesn't reverse it.
  acceleration = reverseVelocity * (sqrt(fabs(5 * overlap.getArea())) / sqrt(getArea()));
  
  // Just in case, make sure the force doesn't reverse the velocity
  if (acceleration.Length() > velocity.Length())
    acceleration = reverseVelocity;
}
コード例 #3
0
ファイル: PhongMaterial.cpp プロジェクト: alexunder/X-toys
Vec3f PhongMaterial::Shade(const Ray &ray, const Hit &hit, const Vec3f &dirToLight, const Vec3f &lightColor) const
{
    Vec3f eyeDir = ray.getDirection();
    eyeDir.Negate();

    Vec3f eyePlusLight = eyeDir + dirToLight;
    eyePlusLight.Normalize(); 
    
    float hn = eyePlusLight.Dot3(hit.getNormal());
    hn = pow(hn, mPhongComponent);

    Vec3f color = lightColor * mHighLightColor;
    color = hn * color;

    return color;
}
コード例 #4
0
ファイル: rayTracer.cpp プロジェクト: perfect28/MIT-Graphics
bool transmittedDirection(const Vec3f &normal, const Vec3f &incoming,
	float index_i, float index_t, Vec3f &transmitted)
{
	//折射光方向:T = e(N.I) - sqrt(1 - e ^ 2(1 - (N.I) ^ 2)))N - eI
	//从物体内部向外:T = (-N.I - sqrt(1 - 1 / e ^ 2(1 - N.I) ^ 2) * 1 / e)N - I / e
	//The dot product of the normal and ray direction is negative when we are outside 
	//the object, and positive when we are inside. 

	//不需要在这里判断光线是在内还是在外,求法是一样的
	//不同的是一方面normal是反的,另一方面比值是互倒的
	Vec3f I = incoming;
	I.Negate();
	float e = index_i / index_t;
	float tmp = normal.Dot3(I);
	float sqrt_value = 1 - e*e*(1 - tmp*tmp);
	if (sqrt_value < 0)
		return false;
	transmitted = (e*tmp - sqrt(sqrt_value))*normal - e*I;
	return true;
}