Esempio n. 1
0
/*======== double get_illumination() ==========
  Inputs:  double *l
	double *n
	int cp
	double *constants

	Returns: illumination (0 - 255)

	Sum of ambient, diffuse, and specular components of illumination

	====================*/
color get_illumination(vector light, vector normal, double *cp, color ca, struct constants *cons){
	color c;
	double ambient, diffuse, specular;
	int val;

	ambient = get_ambient(ca.red, cons -> r[Ka]);
	diffuse = get_diffuse(light, normal, cp[0], cons -> r[Kd]);
	specular = get_specular(light, normal, cp[0], cons -> r[Ks]);

	val = ambient + diffuse + specular;
	c.red = val <= 255 ? val : 255;

	ambient = get_ambient(ca.green, cons -> g[Ka]);
	diffuse = get_diffuse(light, normal, cp[1], cons -> g[Kd]);
	specular = get_specular(light, normal, cp[1], cons -> g[Ks]);

	val = ambient + diffuse + specular;
	c.green = val <= 255 ? val : 255;

	ambient = get_ambient(ca.blue, cons -> b[Ka]);
	diffuse = get_diffuse(light, normal, cp[2], cons -> b[Kd]);
	specular = get_specular(light, normal, cp[2], cons -> b[Ks]);

	val = ambient + diffuse + specular;
	c.blue = val <= 255 ? val : 255;

	if (cons -> red || cons -> green || cons -> blue){
		c.red *= cons -> red;
		c.green *= cons -> green;
		c.blue *= cons -> blue;

	}

	return c;
}
optix::float3 DiffuseAmbientOccluded::doWeightedCosineSamplingWithEnvironmentSampling(const optix::Ray& r, HitInfo& hit, bool emit) const
{
	float3 rho_a = get_emission(hit);
	float3 rho_d = get_diffuse(hit);

	float3 avgUnoccluded = make_float3(0,0,0);
	int numOfUnoccluded = 0;

	const int numOfRays = 200;
	for(int i = 0 ; i < numOfRays ; i++)
	{
		Ray hemiRay = r;
		HitInfo hemiHit;
		if(sampleCosineWeightedHemisphere(hemiRay, hemiHit, hit))
		{
			avgUnoccluded += hemiRay.direction;
			numOfUnoccluded++;
		}
	}

	float3 averageNormal = normalize(avgUnoccluded / numOfUnoccluded);
	float accessability = ((float)numOfUnoccluded) / numOfRays;

	// sample the environment in the average unoccluded direction
	float3 hdrValue = tracer -> get_background(averageNormal);

	return M_1_PIf * accessability * rho_d * hdrValue;
}
Esempio n. 3
0
vector3f get_ray_trace(ray &r, kdtree &kdtree, int depth) 
{
	if (depth >= max_depth)
	{
		return vector3f(0.0, 0.0, 0.0);
	}

	vector3f origin_cp = r.origin;
	primitive *pri = get_intersecting_primitive(kdtree, r);
	
	if (pri == NULL) 
	{
		return background;
	}

	else
	{
		double *amb = pri->get_material().amb;
		double *dif = pri->get_material().dif;
		double *spc = pri->get_material().spc;

		// ambient calculation
		vector3f ambient = get_ambient(amb);

		// specular calculation (no transparency)
		vector3f specular = get_specular(spc, pri, r, kdtree, depth);

		// diffuse calculation
		double spc_alpha = 1;
		vector3f diffuse = get_diffuse(dif, pri, r, kdtree, depth, spc_alpha);

		return rgb_trim(ambient + specular * spc_alpha + diffuse);
	}
}
Esempio n. 4
0
static int		get_spot(t_ray *ray, t_ray *light, t_spot *spot)
{
	int		color;

	color = get_diffuse(ray, light, spot);
	color = color_add(color, get_specular(ray, light, spot));
	return (color);
}
Esempio n. 5
0
/**
 * Performs a raytrace on the given pixel on the current scene.
 * The pixel is relative to the bottom-left corner of the image.
 */
Color3 Raytracer::trace_pixel(int recursions, const Ray& ray, float refractive)
{
    size_t num_geometries = scene->num_geometries();
    bool hit_any = false; // if any geometries were hit
    IsectInfo min_info; // everything we're calculating from intersection
    Vector3 intersection_point = Vector3::Zero;

    // run intersection test on every object in scene
    for (size_t i = 0; i < num_geometries; i++)
    {
        IsectInfo info;
        // intersect returns true if there's a hit, false if not, and sets
        // values in info struct
        bool hit = scene->get_geometries()[i]->intersect_ray(ray, info);

        if (hit && info.time < min_info.time) // min_info.time initializes to inf
        {
            min_info = info;
            intersection_point = ray.eye + (min_info.time * ray.dir);
            hit_any = true;
        }
    }

    // found a hit
    if (hit_any)
    {
        Color3 direct;
        Color3 diffuse = Color3::Black;
        Color3 ambient = scene->ambient_light * min_info.ambient;
        float angle = dot(ray.dir, min_info.normal);
        // compute reflected ray
        Ray incident_ray;
        incident_ray.dir = ray.dir - 2 * angle * min_info.normal;
        incident_ray.dir = normalize(incident_ray.dir);
        incident_ray.eye = intersection_point + eps * incident_ray.dir;

        // no-refraction case
        if (min_info.refractive == 0.0)
        {
            diffuse = get_diffuse(incident_ray.eye, min_info.normal,
                    min_info.diffuse, eps);
            direct = min_info.texture * (ambient + diffuse);

            // return direct light and reflected light if we have recursions left
            if (recursions >= max_recursion_depth)
            {
                return direct;
            }

            return direct + min_info.texture * min_info.specular *
                trace_pixel(recursions + 1, incident_ray, refractive);

        }
        // refraction case
        else
        {
            // return black if no more recursions
            if (recursions >= max_recursion_depth)
            {
                return Color3::Black;
            }

            float c;
            Ray transmitted_ray;
            float refract_ratio = refractive / min_info.refractive;

            // negative dot product between ray and normal indicates entering object
            if (angle < 0.0)
            {
                refract(ray.dir, min_info.normal, refract_ratio, &transmitted_ray.dir);
                c = dot(-1.0 * ray.dir, min_info.normal);
            }
            else
            {
                // exiting object
                if (refract(ray.dir, (-1.0 * min_info.normal), min_info.refractive,
                            &transmitted_ray.dir))
                {
                    c = dot(transmitted_ray.dir, min_info.normal);
                }
                // total internal reflection
                else
                {
                    return trace_pixel(recursions + 1, incident_ray, refractive);
                }
            }

            // schlick approximation to fresnel equations
            float R_0 = pow(refract_ratio - 1, 2) / pow(refract_ratio + 1, 2);
            float R = R_0 + (1 - R_0) * pow(1 - c, 5);
            transmitted_ray.eye = intersection_point + eps * transmitted_ray.dir;

            // return reflected and refracted rays
            return R * trace_pixel(recursions + 1, incident_ray, refractive) +
                (1.0 - R) * trace_pixel(recursions + 1, transmitted_ray,
                        min_info.refractive);
        }
    }
    // didn't hit anything - return background color
    else
    {
        return scene->background_color;
    }
}
Esempio n. 6
0
Color3 Raytracer::trace_pixel_end(int recursions, const Ray& ray, float refractive, 
        IsectInfo min_info)
{
    Color3 direct;
    Color3 diffuse = Color3::Black;
    Color3 ambient = scene->ambient_light * min_info.ambient;
    float angle = dot(ray.dir, min_info.normal);

    // compute reflected ray
    Vector3 intersection_point = ray.eye + (min_info.time * ray.dir);
    Ray incident_ray;
    incident_ray.dir = ray.dir - 2 * angle * min_info.normal;
    incident_ray.dir = normalize(incident_ray.dir);
    incident_ray.eye = intersection_point + eps * incident_ray.dir;

    // no-refraction case
    if (min_info.refractive == 0.0)
    {
        diffuse = get_diffuse(incident_ray.eye, min_info.normal,
                min_info.diffuse, eps);
        direct = min_info.texture * (ambient + diffuse);

        // return direct light and reflected light if we have recursions left
        if (recursions >= max_recursion_depth)
        {
            return direct;
        }

        return direct + min_info.texture * min_info.specular *
            trace_pixel(recursions + 1, incident_ray, refractive);

    }
    // refraction case
    else
    {
        // return black if no more recursions
        if (recursions >= max_recursion_depth)
        {
            return Color3::Black;
        }

        float c;
        Ray transmitted_ray;
        float refract_ratio = refractive / min_info.refractive;

        // negative dot product between ray and normal indicates entering object
        if (angle < 0.0)
        {
            refract(ray.dir, min_info.normal, refract_ratio, &transmitted_ray.dir);
            c = dot(-1.0 * ray.dir, min_info.normal);
        }
        else
        {
            // exiting object
            if (refract(ray.dir, (-1.0 * min_info.normal), min_info.refractive,
                        &transmitted_ray.dir))
            {
                c = dot(transmitted_ray.dir, min_info.normal);
            }
            // total internal reflection
            else
            {
                return trace_pixel(recursions + 1, incident_ray, refractive);
            }
        }

        // schlick approximation to fresnel equations
        float R_0 = pow(refract_ratio - 1, 2) / pow(refract_ratio + 1, 2);
        float R = R_0 + (1 - R_0) * pow(1 - c, 5);
        transmitted_ray.eye = intersection_point + eps * transmitted_ray.dir;

        // return reflected and refracted rays
        return R * trace_pixel(recursions + 1, incident_ray, refractive) +
            (1.0 - R) * trace_pixel(recursions + 1, transmitted_ray,
                    min_info.refractive);
    }
}