コード例 #1
0
ファイル: put_pixel_rtv1.c プロジェクト: Gman513/rtv1
bool	ray_sphere_intersect(t_ray *ray, t_sphere *sphere)
{
	float 		a;
	float 		b;
	float		c;
	float		discriminant;
    bool        retvalue;
	t_vector	distance;

	a = vector_scalar(&ray->direction, &ray->direction);
    distance = vector_sub(&ray->camera, &sphere->origin);
	b = 2 * vector_scalar(&ray->direction, &distance);
    c = vector_scalar(&distance, &distance) - (sphere->radius * sphere->radius);
	discriminant = b * b - 4 * a * c;
	if (discriminant < 0)
		retvalue = false;
	else
    {
        float sqrtdiscr = sqrtf(discr);
        float t0 = (-B + sqrtdiscr)/(2);
        float t1 = (-B - sqrtdiscr)/(2);
        
        if(t0 > t1)
            t0 = t1;
        if((t0 > 0.001f) && (t0 < *t)){
            *t = t0;
            retval = true;
        }else
            retval = false;
    }
    return (retval);
    }
コード例 #2
0
ファイル: ray.c プロジェクト: dknutsen/dokray
void ray_pointon(Vector &result, const Ray &r, float t){
   vector_add(result, vector_scalar(dir, t), p);
}
コード例 #3
0
struct vector raytrace(struct vector rayorig, struct vector raydir, sphere_t *spheres, int nspheres, int depth)
{
	int inside;
	int i, j;               /* Loop indexes. */
	float t0;
	float t1;
	sphere_t s;
	struct vector surface_color; /* Color of the surface.             */
	struct vector phit;          /* Point of intersection.            */
	struct vector nhit;          /* Normal at the intersection point. */
	struct vector lightdir;      /* Light direction. */
	struct vector refldir;
	struct vector refrdir;
	struct vector tmp1, tmp3;
	struct vector reflection;
	struct vector refraction;
	float tnear;
	float facingratio;
	float fresneleffect;
	float ior;
	float cosi;
	float k;
	float eta;
	int transmission;
	
	t0 = INFINITY;
	t1 = INFINITY;
	tnear = INFINITY;
	s = NULL;
	
	/*
	 * Find closest sphere in the scene 
	 * that the ray intercepts.
	 */
	for (i = 0; i < nspheres; i++)
	{
		/* This sphere is intercepted. */
		if (sphere_intersects(spheres[i], rayorig, raydir, &t0, &t1))
		{
			if (t0 < 0)
				t0 = t1;
			
			/* Closest sphere found. */
			if (t0 < tnear)
			{
				tnear = t0;
				s = spheres[i];
			}
		}
	}
	
	/*
	 * There is no intersection
	 * so return background color.
	 */
	if (s == NULL)
		return (VECTOR(2, 2, 2));
	
	surface_color = VECTOR(0, 0, 0);
	
	phit = vector_scalar(raydir, tnear);
	phit = vector_add(phit, rayorig);
	
	nhit = vector_sub(phit, sphere_center(s));
	nhit = vector_normalize(nhit);
	
	inside = 0;
	if (vector_dot(raydir, nhit) > 0)
	{
		nhit = vector_invert(nhit);
		inside = 1;
	}
										
	tmp3 = vector_scalar(nhit, BIAS);
	tmp3 = vector_add(tmp3, phit);

	if (((s->transparency > 0) || (s->reflection > 0)) && (depth < max_depth))
	{		
		facingratio = -vector_dot(raydir, nhit);
		fresneleffect = mix(pow(1 - facingratio, 3), 1, 0.1);
		
		tmp1 = vector_scalar(nhit, 2*vector_dot(raydir, nhit));
		refldir = vector_sub(raydir, tmp1);
		refldir = vector_normalize(refldir);
		
		reflection = raytrace(tmp3, refldir, spheres, nspheres, depth + 1);
		
		refraction = VECTOR(0, 0, 0);
		
		if (s->transparency > 0)
		{			
			ior = 1.1;
			eta = (inside) ? ior : 1/ior;
			cosi = -vector_dot(nhit, raydir);
			k = 1 - eta*eta*(1 - cosi*cosi);
			
			refrdir = vector_scalar(raydir, eta);
			tmp1 = vector_scalar(nhit, eta*cosi - sqrt(k));
			refrdir = vector_add(refrdir, tmp1);
			refrdir = vector_normalize(refrdir);
			
			tmp3 = vector_scalar(nhit, BIAS);
			tmp3 = vector_sub(phit, tmp3);
			
			refraction = raytrace(tmp3, refrdir, spheres, nspheres, depth + 1);
		}
		
		refraction =vector_scalar(refraction,(1-fresneleffect)*s->transparency);
		reflection = vector_scalar(reflection, fresneleffect);
		
		tmp1 = vector_add(reflection, refraction);
		surface_color = vector_cross(tmp1, s->surface_color);
	}
	
	else
	{	
		/*
		 * It is a diffuse object, so there
		 * is no need to raytrace any further.
		 */
		for (i = 0; i < nspheres; i++)
		{
			/* This is a light source. */
			if (spheres[i]->emission_color.x > 0)
			{
				transmission = 1;

				lightdir = vector_sub(spheres[i]->center, phit);
				lightdir = vector_normalize(lightdir);
				
				for (j = 0; j < nspheres; j++)
				{	
					if (i == j)
						continue;
					
					/* Shade this point. */
					if (sphere_intersects(spheres[j], tmp3, lightdir, NULL, NULL))
					{
						transmission = 0;
						break;
					}
				}
				
				if (transmission)
				{
					tmp1 = vector_scalar(s->surface_color, max(0, vector_dot(nhit, lightdir)));
					tmp1 = vector_cross(tmp1, spheres[i]->emission_color);
					
					surface_color = vector_add(surface_color, tmp1);
				}
			}
		}
	}

	return (vector_add(surface_color, s->emission_color));
}