t_bool dielectric(t_material *material, const t_ray *r, const t_hit_record *h, t_vec3 *attenuation, t_ray *scattered) { t_vec3 outward_normal; t_vec3 reflected; t_vec3 refracted; float ni_over_nt; float reflect_probe; float cosine; vec3_reflect(&reflected, &RAY_DIRECTION(r), &h->normal); vec3_assign(attenuation, &material->texture.albedo); if (vec3_dot(&RAY_DIRECTION(r), &h->normal) > 0) { vec3_mul_f(&outward_normal, &h->normal, -1.f); //TODO pass idx ni_over_nt = REF_IDX; cosine = REF_IDX * vec3_dot(&RAY_DIRECTION(r), &h->normal) / vec3_length(&RAY_DIRECTION(r)); } else { vec3_assign(&outward_normal, &h->normal); ni_over_nt = 1.0f / REF_IDX; cosine = - vec3_dot(&RAY_DIRECTION(r), &h->normal) / vec3_length(&RAY_DIRECTION(r)); } if (refract(&RAY_DIRECTION(r), &outward_normal, ni_over_nt, &refracted)) reflect_probe = schlick(cosine, REF_IDX); else reflect_probe = 1.0f; if (drand48() < reflect_probe) ray_assign(scattered, &h->pos, &reflected); else ray_assign(scattered, &h->pos, &refracted); return (TRUE); }
bool Dielectric::scatter(const Ray& r_in, const HitRecord& record, vec3& attenuation, Ray& scattered) const { vec3 outward_normal; vec3 reflected = reflect(r_in.direction(), record.normal); float ni_over_nt; attenuation = vec3(1,1,1); vec3 refracted; float reflect_probability; float cosine; if (dot(r_in.direction(), record.normal) > 0) { outward_normal = -record.normal; ni_over_nt = refractive_index; cosine = refractive_index * dot(r_in.direction(), record.normal) / r_in.direction().length(); } else { outward_normal = record.normal; ni_over_nt = 1.0f / refractive_index; cosine = -dot(r_in.direction(), record.normal) / r_in.direction().length(); } if (refract(r_in.direction(), outward_normal, ni_over_nt, refracted)) { reflect_probability = schlick(cosine, refractive_index); } else { reflect_probability = 1.0f; } if (drand48() < reflect_probability) { scattered = Ray(record.point, reflected); // REFLECT vs } else { scattered = Ray(record.point, refracted); // REFRACT !! } return true; }