Пример #1
0
PixelBuff::Pixel Engine::RayTrace(const Ray &a,int dpt) const
{
	//initialization
	PixelBuff::Pixel result;
	result.depth=FLT_MAX;
	float multiplier=1;
	Ray current=a;
	for(int i=0;i<dpt&&multiplier!=0;++i)
	{
		Scene::Intersection intersection;
		if(!scene->ClosestInt(current,intersection))
			return result; //there was no intersection, so end tracing

		if(result.depth==FLT_MAX) //depth hasn't been set yet so do it
			result.depth=intersection.dst;

		Vector3 point=current.PointAtLen(intersection.dst); //here is the intersection point

		scene->SetSeenLights(point); //check which lights can be seen from point
		const Light* t;
		while((t=scene->NextLight())!=NULL) //for each light do:
		{
			Vector3 lightDir=t->GetLightDirAt(point);
			Color lightColor=t->GetLightColorAt(point);
			//add calculated color, multiplied by multiplier, to result.color
			result.color+=intersection.o->CalculateColorAt(lightColor,lightDir,current.Dir(),point)*multiplier;
		}
		//calculate reflected ray
		Vector3 normal=-intersection.o->GetNormalAt(point);
		current=Ray(point,a.Dir()-2*normal*Vector3::Dot(current.Dir(),normal));
		multiplier*=intersection.o->GetReflectanceAt(point); //multiply by reflectance
	}
	return result;
}
Пример #2
0
bool Plane::Intersects(const Ray& r,float& result) const
{
	float VD=Vector3::Dot(normal,r.Dir());
	if(VD==0)
		return false;
	float V0=-(Vector3::Dot(normal,r.Origin())+distance);
	result=V0/VD;
	if(result<EPSILON) //role of EPSILON is explained in "common.h"
		return false;
	return true;
}
Пример #3
0
//-------------------------------------------------------------
float Sphere :: Intersect( Ray& r ) {
//-------------------------------------------------------------
  Vector dist = r.Start() - center;
  float b = (dist * r.Dir()) * 2.0;
  float a = (r.Dir() * r.Dir());
  float c = (dist * dist) - radius * radius;
  float discr = b * b - 4.0 * a * c;
  if ( discr < 0 ) return -1;
  float sqrt_discr = sqrt( discr );
  float t1 = (-b + sqrt_discr)/2.0/a;
  float t2 = (-b - sqrt_discr)/2.0/a;
  if (t1 < EPSILON) t1 = -EPSILON;
  if (t2 < EPSILON) t2 = -EPSILON;
  if (t1 < 0 && t2 < 0) return -1;
  float t;
  if ( t1 < 0 && t2 >= 0 ) t = t2;
    else if ( t2 < 0 && t1 >= 0 ) t = t1;
      else if (t1 < t2) t = t1;
        else t = t2;
  return t;
}
Пример #4
0
//-------------------------------------------------------------
SColor Scene :: IntersectShadow( Ray r, float maxt ) {
//-------------------------------------------------------------
  SColor att = SColor(1);
  Primitive3D * p;
  while( (p = world.NextPrimitive( )) != NULL ) {
    float t = p -> Intersect( r );
    if ( t > EPSILON && t < maxt) {
      Point x = r.Start() + r.Dir() * t;
      att *= p -> kt( x );
    }
  }
  return att;
}
Пример #5
0
//-------------------------------------------------------------
SColor Scene :: Trace(Ray r, int d) {
//-------------------------------------------------------------
  if (d > maxdepth) return La;
  Point x;
  Primitive3D * q = Intersect(r, x);
  if (q == NULL) return La;
  Vector normal = q -> Normal(x);
  bool out = TRUE;
  if ( normal * (-r.Dir()) < 0) { normal = -normal; out = FALSE; }
  SColor c = DirectLightsource(q, -r.Dir(), normal, x);
  if ( q->kr(x) != 0 ) {
    Vector reflectdir;
    q -> ReflectionDir(reflectdir, normal, -r.Dir(), x);
    c += q->kr(x) * Trace( Ray(x, reflectdir), d+1);
  }
  if ( q->kt(x) != 0 ) {
    Vector refractdir;
    if (q -> RefractionDir(refractdir, normal, -r.Dir(), x, out)) {
      c += q->kt(x) * Trace( Ray(x, refractdir), d+1);
    }
  }
  return c;
}