/* multiples two colors channels together to blend * if clamp is 0, color values will not be clamped * if clamp is 1, color values will be clamped at 1.0f */ color_t* color_mult(color_t *colorout, const color_t *color1, const color_t *color2, unsigned int clamp) { colorout->r = color1->r * color2->r; colorout->g = color1->g * color2->g; colorout->b = color1->b * color2->b; if(clamp) color_clamp(colorout); return colorout; }
/* scales the color by a factor * if clamp is 0, color values will not be clamped * if clamp is 1, color values will be clamped at 1.0f */ color_t* color_scale(color_t *colorout, const color_t *color, float scale, unsigned int clamp) { colorout->r = color->r * scale; colorout->g = color->g * scale; colorout->b = color->b * scale; if(clamp) color_clamp(colorout); return colorout; }
static void raycast_light(t_hit *hit, unsigned depth) { t_lstiter it; t_ray ray; t_light *light; int raycast_result; t_vec3 lightness; t_hit sub_hit; if (depth == 0) return ; vec3_set(&lightness, 0, 0, 0); init_iter(&it, rt.scene->lights, increasing); while (lst_iterator_next(&it)) { light = (t_light*)it.data; vec3_copy(&ray.origin, &hit->position); vec3_copy(&ray.direction, &light->position); vec3_sub(&ray.direction, &hit->position); vec3_normalize(&ray.direction); ray.origin.x += ray.direction.x * RC_SHADOW_SHIFT; ray.origin.y += ray.direction.y * RC_SHADOW_SHIFT; ray.origin.z += ray.direction.z * RC_SHADOW_SHIFT; raycast_result = raycast(&ray, &sub_hit, depth - 1, NULL); if (sub_hit.object != NULL) { // ray bounce } else { vec3_add(&lightness, &light->color); } } vec3_div(&lightness, rt.scene->lights->size); vec3_add(&lightness, &rt.scene->ambient_light); color_clamp(&lightness); hit->color.x *= lightness.x; hit->color.y *= lightness.y; hit->color.z *= lightness.z; }