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 recursive_tracer(t_params p, t_ray *ray, t_objects *sp) { t_f64 inside; t_f64 facingratio; t_f64 fresneleffect; t_vec3f refldir; t_vec3f refdir; t_color reflection; t_color refrac; t_ray rx; if ((inside = dot_vec3f(&ray->dir, &p.nhit) > 0)) p.nhit = scale_vec3f(&p.nhit, -1); facingratio = -dot_vec3f(&ray->dir, &p.nhit); fresneleffect = mix(pow(1 - facingratio, 3), 1, .1); refldir = get_reflection_dir(&p.nhit, &ray->dir); rx = reflected_ray(ray, &refldir, &p.nhit, &p.phit); reflection = trace_ray(&rx, sp, ++p.depth); if (p.sphere->transparency > 0) { refdir = compute_ideal_refractions(ray, inside, p); rx = refracted_ray(ray, &refdir, &p.nhit, &p.phit); refrac = trace_ray(&rx, sp, ++p.depth); } return (defualt_glossy_shading(&reflection, &refrac, fresneleffect, p.sphere)); }
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); }
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)); }