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 }