-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathrefraction.c
101 lines (94 loc) · 3.02 KB
/
refraction.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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* refraction.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jroguszk <[email protected]> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2018/06/15 11:37:43 by jroguszk #+# #+# */
/* Updated: 2018/06/26 11:51:19 by mpauw ### ########.fr */
/* */
/* ************************************************************************** */
#include "rt.h"
static void beer(t_p_info *pi)
{
if (pi->beer.v[0] < 0.99 && pi->beer.v[1] < 0.99 && pi->beer.v[2] < 0.99)
{
pi->beer = ft_3v_scalar(pi->beer, -1.0);
pi->beer.v[0] = (exp(pi->beer.v[0] * (pi->s_value / 70)));
pi->beer.v[1] = (exp(pi->beer.v[1] * (pi->s_value / 70)));
pi->beer.v[2] = (exp(pi->beer.v[2] * (pi->s_value / 70)));
}
}
static void fresnal(t_p_info *pi, double *n_value, double cosi,
double cost)
{
double rs;
double rp;
if (cost < 0.0)
{
pi->fresnal_specular = 1.0;
pi->fresnal_transparent = 0.0;
}
else
{
if ((n_value[1] * cosi) + (n_value[0] * cost) == 0.0)
rs = 1.0;
else
rs = ((n_value[1] * cosi) - (n_value[0] * cost))
/ ((n_value[1] * cosi) + (n_value[0] * cost));
if ((n_value[0] * cosi) + (n_value[1] * cost) == 0.0)
rp = 1.0;
else
rp = ((n_value[0] * cosi) - (n_value[1] * cost))
/ ((n_value[0] * cosi) + (n_value[1] * cost));
pi->fresnal_specular = (rs * rs + rp * rp) / 2;
pi->fresnal_transparent = 1 - pi->fresnal_specular;
}
}
static void call_recursion(t_scene scene, t_pixel *p, t_3v *dir,
double *n_value)
{
if (n_value[2] < 0.0)
{
if (p->amount_refl < scene.refl)
{
p->type = 1;
p->index_refract = n_value[0];
get_reflections(p, scene, *dir);
}
}
else
{
p->type = 2;
p->index_refract = n_value[0];
get_reflections(p, scene, *dir);
}
}
void refraction(t_p_info *pi, t_3v *dir, t_pixel *p, t_scene scene)
{
double cosi;
double index;
double n_value[3];
t_3v n;
n_value[0] = p->index_refract;
n_value[1] = (pi->obj_m).refractive_index;
n = ft_init_3v(pi->normal.v[0], pi->normal.v[1], pi->normal.v[2]);
cosi = ft_clamp(-1.0, 1.0, ft_3v_dot_product(pi->normal, *dir));
if (cosi < 0.0)
cosi = cosi * -1.0;
else
{
pi->is_inside = 1;
ft_swap_double(&n_value[0], &n_value[1]);
n = ft_3v_scalar(n, -1);
beer(pi);
}
index = n_value[0] / n_value[1];
n_value[2] = 1 - index * index * (1.0 - cosi * cosi);
fresnal(pi, n_value, cosi, n_value[2]);
*dir = (n_value[2] < 0.0) ? get_reflection_vector(n, *dir) :
ft_3v_add(ft_3v_scalar(*dir, index), ft_3v_scalar(n, index * cosi
- sqrt(n_value[2])));
call_recursion(scene, p, dir, n_value);
}