t_vec3f single_tracer(t_params p, t_ray *ray, t_objects *sp) { int i; t_vec3f trans; t_vec3f tmp; t_vec3f light_dir; t_color scolor; i = 0; if (dot_vec3f(&ray->dir, &p.nhit) > 0) p.nhit = scale_vec3f(&p.nhit, -1); scolor = new_uni_color(0); while (i < sp->top) { if (sp->store[i].type == LIGHT) { light_dir = normalize_vec3f(sub_vec3f(&sp->store[i].pos, &p.phit)); if (sp->store[i].nature == AREA_LIGHT) trans = soft_shadows(p, ray, sp, i); else trans = sharp_shadows(p, ray, sp, light_dir); tmp = phong_shading(trans, ray, p, light_dir, sp->store[i].ecolor); scolor = add_vec3f(&scolor, &tmp); } i++; } return (add_vec3f(&scolor, &p.sphere->ecolor)); }
static inline t_color soft_shadows(t_params p, t_ray *r, t_objects *s, int j) { int x; int y; t_vec3f w; t_color trans; t_vec3f tmp; t_vec3f lp; trans = new_uni_color((x = 0)); while (x < 5 && !(y = 0)) { while (y < 5) { tmp = new_vec3f(x, 0, y); lp = add_vec3f(&s->store[j].pos, &tmp); if (sharp_shadows(p, r, s, normalize_vec3f(sub_vec3f(&lp, &p.phit))).x != 0) { w = new_vec3f(1 / 25., 1 / 25., 1 / 25.); trans = add_vec3f(&trans, &w); } y++; } x++; } return (trans); }
t_bool plane_intersection(t_ray *r, t_sphere *s, t_f64 *t0, t_f64 *t1) { t_f64 denom; t_vec3f v_n; t_vec3f c; t_vec3f f; v_n = normal_vec3f(&s->pos); denom = dot_vec3f(&v_n, &r->dir); if (denom > 1e-6) { f = sub_vec3f(&s->pos, &r->origin); *t1 = dot_vec3f(&f, &v_n) / denom; *t0 = *t1; c = scale_vec3f(&r->dir, *t0); c = add_vec3f(&c, &r->origin); if (!((c.x > s->pos.x) && (c.x < (s->pos.x + 10)))) return (FALSE); if (!((c.y > s->pos.y) && (c.y < (s->pos.y + 10)))) return (FALSE); if (!((c.x > s->pos.z) && (c.y < (s->pos.y + 10)))) return (FALSE); return (*t0 >= 0); } return (FALSE); }
void cast_ray(int x, int y, t_vec3f *pixel, t_interface *env) { t_vec3f dir; t_ray ray; t_f64 xx; t_f64 yy; xx = (2 * ((x + 0.5) * (1.0 / WIDTH)) - 1) * env->camera.angle * ARATIO; yy = (1 - 2 * ((y + 0.5) * (1.0 / HEIGHT))) * env->camera.angle; dir = new_vec3f(xx, yy, 0); dir = add_vec3f(&dir, &env->camera.up); ray = new_ray(env->camera.pos, normal_vec3f(&dir)); *pixel = trace_ray(&ray, env->objects, 0); }
t_vec3f trace_ray(t_ray *ray, t_objects *sp, int depth) { t_params param; param = get_closest_primitive(ray, sp); param.depth = depth; if (param.sphere == NULL) return (new_uni_color(3)); param.phit = scale_vec3f(&ray->dir, param.tnear); param.phit = add_vec3f(&ray->origin, ¶m.phit); param.nhit = param.sphere->normal(¶m.phit, ¶m.sphere->pos, param.sphere->inverse_matrix); param.ray = ray; if ((param.sphere)->reflection > 0 && depth < MAX_RAY_DEPTH) return (recursive_tracer(param, ray, sp)); return (single_tracer(param, ray, sp)); }
static inline t_color sharp_shadows(t_params p, t_ray *r, t_objects *s, t_vec3f ld) { t_f64 t0; int i; t_ray sray; i = 0; while (i < s->top) { if (s->store[i].type != LIGHT) { sray = dup_ray(r); sray.origin = scale_vec3f(&p.nhit, BIAS); sray.origin = add_vec3f(&sray.origin, &p.phit); sray.dir = ld; if (s->store[i].intersect(&sray, &s->store[i], &t0, &t0)) return (new_uni_color(0)); } i++; } return (new_uni_color(1)); }