-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtrace_path.c
78 lines (70 loc) · 2.59 KB
/
trace_path.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* trace_path.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: ajaehaer <[email protected]> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2019/02/16 18:52:38 by ajaehaer #+# #+# */
/* Updated: 2019/03/20 15:41:27 by ajaehaer ### ########.fr */
/* */
/* ************************************************************************** */
#include "path_tracing.h"
static t_ray bsdf(t_intersection inter, t_ray ray,
t_vector *signal)
{
double chance;
chance = rand_double();
if (fits_probability(chance, inter.primitive->material, ALBEDO))
albedo_ray(&ray, inter, signal);
else if (fits_probability(chance, inter.primitive->material, SPECULAR))
specular_ray(&ray, inter, signal);
else if (fits_probability(chance, inter.primitive->material, REFRACTION))
refraction_ray(&ray, inter, signal);
else
{
*signal = (t_vector){0., 0., 0., 0.};
ray.direction = (t_vector){0., 0., 0., 0.};
}
return (ray);
}
t_vector emit(t_render *render, t_intersection inter, t_ray ray)
{
t_vector res[2];
double intensity[2];
res[0] = vector_scalar_mul(primitive_color(inter.primitive, inter.uv, 1.),
inter.primitive->material->light_intensity);
if (!(inter.primitive->material->light_intensity < 1.))
return (res[0]);
get_lighting(ray, inter, render, intensity);
intensity[0] = intensity[0] * inter.primitive->material->albedo +
intensity[1];
res[1] = primitive_color(inter.primitive, inter.uv, intensity[0]);
return (vector_sum(res[0], res[1]));
}
t_vector scaled_by(t_vector vector, t_vector scaler)
{
vector.x *= scaler.x;
vector.y *= scaler.y;
vector.z *= scaler.z;
return (vector);
}
t_vector trace_path(t_render *render, t_ray ray, size_t depth)
{
t_vector signal;
t_intersection inter;
t_vector res;
size_t i;
res = (t_vector){0., 0., 0., 0.};
signal = (t_vector){1., 1., 1., 0.};
i = -1;
while (++i < depth)
{
inter = scene_intersection(render->scene, ray);
if (!(inter.z > 0. && inter.z < INFINITY))
return (res);
res = vector_sum(res, scaled_by(emit(render, inter, ray), signal));
ray = bsdf(inter, ray, &signal);
}
return (res);
}