示例#1
0
NearestIntersection findNearestIntersection(const Scene& scene, const Ray& ray)
{
    NearestIntersection result;

    for (Scene::ConstIterator it = scene.Begin(); it != scene.End(); it++)
    {
	const RayIntersectionPoint& bestIntersection = result.intersection;
	RayIntersectionPoint intersection = (*it)->getIntersection(ray);

        if (!intersection.isNull())
        {
            if ((result.isNull()) || intersection.getDistance() < bestIntersection.getDistance())
            {
		result.intersection = intersection;
                result.primitive = (*it);
             }
        }
    }
    return result;
}
示例#2
0
Color trace(const Scene& scene, Ray ray, int depth)
{
    const Color background(0,0,0);
    const int maxDepth = 3;
    if (depth >= maxDepth)
        return background;

    Color color(0,0,0);
    double distance = 0;
    const Primitive* prim = NULL;
    int intersectionType = 0;

    findNearsetIntersection(scene, ray, &prim, &distance, &intersectionType);

    if (prim != NULL)
    {
        if (prim->IsIlluminative())
        {
            return prim->GetMaterial().GetColor();
        }

        const Vector3 intersectionPoint = ray.GetPoint(distance);
        const Vector3 n = prim->GetNormal(intersectionPoint);

        if (prim->GetMaterial().GetDiffuse() > 0)
        {
            for (Scene::ConstIterator it = scene.Begin(); it != scene.End(); it++)
            {
                const double intensive = getIntensity((*it), intersectionPoint, n, scene);

                if (intensive != .0)
                {
                    Vector3 x = (prim->GetMaterial().GetColor());
                    Vector3 y = ((*it)->GetMaterial().GetColor());

                    color = color + (intensive * prim->GetMaterial().GetDiffuse()) * x * y;
                }
            }
        }

        //refraction
        {
            const Vector3 x = ray.GetDirection();
            const Vector3 y = intersectionType * (-n);

            double n;
            if (intersectionType == IntersectOutside)
                n = 1.0 / prim->GetMaterial().GetRefractionRate();
            else
                n = prim->GetMaterial().GetRefractionRate();

            const double sin_1 = sqrt(1 - Dot(x,y));
            const double sin_2 = n * sin_1;

            if (sin_2 < 1)
            {
                const double cos_2 = sqrt(1 - sin_2);
                Vector3 xPerpendicular = x - Dot(x,y)*y;
                Vector3 z = cos_2 * y + sin_2 * xPerpendicular;
                z.Normalize();

                if (prim->GetMaterial().GetRefraction() > 0)
                {
                    if (intersectionType == IntersectInside)
                    {
                        color = color +
                            prim->GetMaterial().GetRefraction() *
                            exp(-prim->GetMaterial().GetAbsorptionRate()*distance) *
                            trace(scene, Ray(intersectionPoint, z), depth + 1);
                    }
                    else
                        color = color +
                            prim->GetMaterial().GetRefraction() * trace(scene, Ray(intersectionPoint, z), depth + 1);
                }
            }
        }

        //reflection
        if (prim->GetMaterial().GetReflection() > 0)
        {
            const Vector3 a = ray.GetDirection();
            Vector3 newA = a - 2 * (Dot(a,n)) * n;
            color = color + prim->GetMaterial().GetReflection() * trace(scene, Ray(intersectionPoint, newA), depth + 1);
        }
    }
    return color;
}