phong.c
 1  /* ************************************************************************** */
 2  /*                                                                            */
 3  /*                                                        :::      ::::::::   */
 4  /*   phong.c                                            :+:      :+:    :+:   */
 5  /*                                                    +:+ +:+         +:+     */
 6  /*   By: gychoi <gychoi@student.42seoul.kr>         +#+  +:+       +#+        */
 7  /*                                                +#+#+#+#+#+   +#+           */
 8  /*   Created: 2023/05/07 22:10:35 by gychoi            #+#    #+#             */
 9  /*   Updated: 2023/05/28 22:57:12 by gychoi           ###   ########.fr       */
10  /*                                                                            */
11  /* ************************************************************************** */
12  
13  #include "header.h"
14  
15  t_bool	in_shadow(t_object *objs, t_ray light_ray, double light_len)
16  {
17  	t_hit_record	rec;
18  
19  	rec.tmin = 0;
20  	rec.tmax = light_len;
21  	if (hit(objs, light_ray, &rec))
22  		return (TRUE);
23  	return (FALSE);
24  }
25  
26  t_vec3	reflect(t_vec3 v, t_vec3 n)
27  {
28  	return (vsub_v(v, vmul_d(n, vdot(v, n) * 2)));
29  }
30  
31  t_color3	point_light_get(t_scene *scene, t_light *light)
32  {
33  	t_color3	ambient;
34  	t_color3	diffuse;
35  	t_color3	specular;
36  	t_vec3		light_dir;
37  	double		light_len;
38  	t_ray		light_ray;
39  	double		kd;
40  	t_vec3		view_dir;
41  	t_vec3		reflect_dir;
42  	double		spec;
43  	double		ksn;
44  	double		ks;
45  	double		brightness;
46  
47  	ambient = scene->ambient;
48  	light_dir = vsub_v(light->origin, scene->rec.p);
49  	light_len = vlen(light_dir);
50  	light_dir = vunit(light_dir);
51  	light_ray = ray(vadd_v(scene->rec.p, vmul_d(light_dir, EPSILON)), light_dir);
52  	if (in_shadow(scene->world, light_ray, light_len))
53  		return (color3(0, 0, 0));
54  	kd = fmax(vdot(scene->rec.normal, light_dir), 0.0);
55  	diffuse = vmul_d(light->light_color, kd);
56  
57  	view_dir = vunit(vmul_d(scene->ray.direction, -1));
58  	reflect_dir = reflect(vmul_d(light_dir, -1), scene->rec.normal);
59  	ksn = 64;
60  	ks = 0.5;
61  	spec = pow(fmax(vdot(view_dir, reflect_dir), 0.0), ksn);
62  	specular = vmul_d(vmul_d(light->light_color, ks), spec);
63  	brightness = light->bright_ratio * LUMEN;
64  	return (vmul_d(vadd_v(vadd_v(ambient, diffuse), specular), brightness));
65  }
66  
67  t_color3	phong_lighting(t_scene *scene)
68  {
69  	t_color3	light_color;
70  	t_object	*lights;
71  
72  	light_color = color3(0, 0, 0);
73  	lights = scene->light;
74  	while (lights)
75  	{
76  		if (lights->type == LIGHT_POINT)
77  			light_color = vadd_v(light_color, point_light_get(scene, lights->element));
78  		lights = lights->next;
79  	}
80  	light_color = vadd_v(light_color, scene->ambient);
81  	return (vmin(vmul_v(light_color, scene->rec.albedo), color3(1, 1, 1)));
82  }