Beispiel #1
0
bool RayTracer::render () {
    Ray3D ray;

    ray.setOrigin (Vector3 (0, 0, 5));

    float sigmaX = static_cast<float> (_left);
    float sigmaY = static_cast<float> (_top);

    for (int curScanLine = 0; curScanLine < _bitmap.getHeight (); curScanLine++) {
        for (int x = 0; x < _bitmap.getWidth (); x++) {
            ray.setDirection (Vector3 (sigmaX, sigmaY, 0) - ray.getOrigin ());	//no need to normalize - Ray3D does this automatically for us!

            Color pixelColor = traceRay (ray, 999999999.0f);

            if (_bitmap.putPixel (x, curScanLine, pixelColor) != E_SUCCESS) {
                return (_done = false);
            }

            sigmaX += _deltaX;
        }

        sigmaX = static_cast<float> (_left);
        sigmaY += _deltaY;
    }

    _done = true;

    return _done;
}
Beispiel #2
0
bool UVSphere::hit(const Ray3D& r, float tmin, float tmax, float time, HitRecord& record) const
{
	Vector3D temp = r.getOrigin() - center;

	double a = dotProduct(r.getDirection(), r.getDirection());
	double b = 2*dotProduct(r.getDirection(), temp);
	double c = dotProduct(temp, temp) - radius*radius;

	double disc = b*b -4*a*c;
	//is there some intersection

	if(disc > 0.0) {
		disc = sqrt(disc);
		double t = (-b - disc) / (2.0*a);
		if (t < tmin)
			t = (-b + disc) /(2.0*a);
		if (t < tmin || t > tmax)
			return false;

		record.t = t;
		record.p = record.texp = (r.getOrigin() + t*r.getDirection());
		record.uvw.initFromW((record.p - center) / radius);

		Vector3D n = (record.p - center) / radius;
		float twopi = 6.28318530718f;
		float theta = acos(n.getZ());
		float phi = atan2(n.getY(), n.getX());
		if (phi < 0.0f) phi+= twopi;

		float one_over_2pi = .159154943029f;
		float one_over_pi = .318309886184f;
		float pi = 3.14159;
		record.uv = Vector2D(phi*one_over_2pi, (pi-theta)*one_over_pi);

		record.mat_ptr = material;
		return true;
	}
	return false;
}
Beispiel #3
0
/**
 * A ray is represented by l0 + l * t = p
 *      l0 - ray origin
 *      l  - ray direction
 *      t  - parameter
 *      p  - point on plane
 * A plane is represented by (p - p0) dot n = 0 (because perpendicular)
 *      p0 - a point representing the distance from the origin
 *      n  - normal of plane
 * Solving for t by substituting p gives that
 * t = [ (p0 - l0) dot n ] / [ l dot n ]
 */
double Plane::findIntersection(const Ray3D & ray) const {
    Vector3D rayDirection = ray.getDirection();
    Vector3D l = rayDirection;
    Vector3D n = normal;
    double ldotn = l.dotProduct(n);
    if (0 == ldotn) { // Ray is || to plane
        return -1; // Never intersects
    } else {
        Vector3D p0 = normal * distance;
        Vector3D l0 = ray.getOrigin();
        double numerator = (p0 - l0).dotProduct(n);
        return numerator / ldotn;
    }
}
Beispiel #4
0
Color RayTracer::traceRay (Ray3D ray, float distance) {
    Primitive* closestPrim = NULL;
    float newDistance;
    Color color (0.0, 0.0, 0.0);

    for (int i = 0; i < _scene->getNumberOfPrimitives (); i++) {
        newDistance = _scene->getPrimitive (i)->findIntersectionWith (ray, distance);
        if ((newDistance >= 0.0) && (newDistance < distance)) {
            closestPrim = _scene->getPrimitive (i);
            distance = newDistance;
        }
    }

    if (closestPrim == NULL) {
        return color;
    }

    if (closestPrim->getIsLight ()) {
        color = closestPrim->getColor ();
        return color;
    }

    // calculate diffuse lighting
    Vector3 pointOfIntersection = ray.getDirection () * distance + ray.getOrigin ();
    Vector3 normal = closestPrim->getNormalAt (pointOfIntersection);
    for (int i = 0; i < _scene->getNumberOfPrimitives (); i++) {
        Primitive* light = _scene->getPrimitive (i);
        if (!light->getIsLight ()) { 
            // wait, this isn't actually a light ...
            continue;
        }

        Vector3 lightDir = light->getOrigin () - pointOfIntersection;
        lightDir.normalize();
        float lightCoef = normal.dotProduct (lightDir);
        color = color + closestPrim->getColor () * light->getColor () * lightCoef;
    }

    return color;
}
Beispiel #5
0
bool UVSphere::shadowHit(const Ray3D& r, float tmin, float tmax, float time) const
{

	Vector3D temp = r.getOrigin() - center;

	double a = dotProduct(r.getDirection(), r.getDirection());
	double b = 2*dotProduct(r.getDirection(), temp);
	double c = dotProduct(temp, temp) - radius*radius;

	double disc = b*b -4*a*c;
	//is there some intersection

	if(disc > 0.0) {
		disc = sqrt(disc);
		double t = (-b - disc) / (2.0*a);
		if (t < tmin)
			t = (-b + disc) /(2.0*a);
		if (t < tmin || t > tmax)
			return false;
		return true;
	}
	return false;
}
Beispiel #6
0
// Return distance from ray origin to intersection
// See comments for variables and the equations in Plane.cpp's findIntersection
double Triangle::findIntersection(const Ray3D & ray) const {
    // See if the ray intersects the bounding box
    // *** With bounding box
    if (!Object::intersectsBBox(ray)) { return -1; }
    // First check if the ray intersects with the plane (use same calculations)
    Vector3D rayDirection = ray.getDirection();
    Vector3D rayOrigin = ray.getOrigin();
    double ldotn = rayDirection.dotProduct(normal);
    if (0 == ldotn) { // Ray is || to triangle
        return -1;
    } else {
        Vector3D p0 = normal * distance;
        double distanceToPlane = (p0 - rayOrigin).dotProduct(normal) / ldotn;
        // Then see if the point is inside the triangle (3 conditions)
        // Q is the point of intersection
        Vector3D Q = (rayDirection * distanceToPlane) + rayOrigin;
        Vector3D sideCA = epC - epA;
        Vector3D segQA = Q - epA;
        // 1. (CA x QA) * n >= 0
        if (sideCA.crossProduct(segQA).dotProduct(normal) < 0) {
            return -1;
        }
        Vector3D sideBC = epB - epC;
        Vector3D segQC = Q - epC;
        // 2. (BC x QC) * n >= 0
        if (sideBC.crossProduct(segQC).dotProduct(normal) < 0) {
            return -1;
        }
        Vector3D sideAB = epA - epB;
        Vector3D segQB = Q - epB;
        // 3. (AB x QB) * n >= 0
        if (sideAB.crossProduct(segQB).dotProduct(normal) < 0) {
            return -1;
        }
        return distanceToPlane;
    }
}