-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathrender_illumination.c
74 lines (65 loc) · 2.32 KB
/
render_illumination.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
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* render_illumination.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: fvonsovs <[email protected] +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/06 14:13:34 by fvonsovs #+# #+# */
/* Updated: 2024/09/14 15:18:38 by fvonsovs ### ########.fr */
/* */
/* ************************************************************************** */
#include "minirt.h"
void illuminate(t_map *map, t_trace *closest)
{
int color;
color = color_multiply(closest->color, map->amb.lum);
if (!calculate_shadow(map, closest))
color = add_colors(color, diffuse(map, closest, map->light.lum));
closest->color = color;
}
int diffuse(t_map *map, t_trace *closest, float intensity)
{
t_float_3 light_dir;
int ret;
float cos_angle;
float ratio;
float attenuation;
light_dir = vec_sub(map->light.pos, closest->hit_point);
attenuation = (90.0 / vec_length(light_dir));
if (attenuation > 1.0f)
attenuation = 1.0f;
cos_angle = vec_cos(closest->normal, light_dir);
if (cos_angle < 0.0f)
cos_angle = 0.0f;
ratio = intensity * cos_angle * attenuation;
ret = color_multiply(closest->color, ratio);
return (ret);
}
int calculate_shadow(t_map *map, t_trace *closest)
{
t_float_3 light_dir;
t_ray ray;
float dist;
light_dir = vec_sub(map->light.pos, closest->hit_point);
dist = vec_length(light_dir);
ray.orig = vec_add(closest->hit_point, vec_mul(closest->normal, 1e-4));
ray.dir = vec_normalize(light_dir);
return (obscured(map, &ray, closest->hit_object.object, dist));
}
int obscured(t_map *map, t_ray *ray, t_obj *closest, float max_dist)
{
t_obj *objects;
float t;
t = INFINITY;
objects = map->objects;
while (objects != NULL)
{
if (objects->id == closest->id)
objects = objects->next;
if (intersect(*ray, objects, &t) && t < max_dist)
return (1);
objects = objects->next;
}
return (0);
}