diff --git a/src/raytracer.ml b/src/raytracer.ml index 582d6903..739d9488 100644 --- a/src/raytracer.ml +++ b/src/raytracer.ml @@ -15,6 +15,19 @@ type hit_rec = { t : float; type hit = hit_rec option +let random_in_unit_sphere () = + let p = ref (Vec3.of_floats ((Random.float 1.0), + (Random.float 1.0), + (Random.float 1.0))) in + while ((Vec3.dot !p !p) >= 1.0) do + p := Vec3.mul 2.0 (Vec3.sub (Vec3.of_floats ((Random.float 1.0), + (Random.float 1.0), + (Random.float 1.0))) + (Vec3.of_floats (1., 1., 1.))) + done; + !p +;; + let hit_sphere sphere ray (tmin, tmax) = let oc = sub ray.origin sphere.center in @@ -63,16 +76,13 @@ and hit h ray (tmin, tmax) = | World w -> hit_world w ray (tmin, tmax) -let get_color world ray = +let rec get_color world ray = match (hit world ray (0., Float.infinity)) with Some hit_result -> - let t = hit_result.t in - if (t > 0.0) - then let n = hit_result.normal in - mul 0.5 (Vec3.of_floats (n.x +. 1., n.y +. 1., n.z +. 1.)) - else let unit_direction = unit_vector ray.dir in - let t = 0.5 *. (unit_direction.y +. 1.0) in - add (mul (1.0 -. t) {x= 1.0; y=1.0; z= 1.0}) (mul t {x= 0.5; y= 0.7; z= 1.0}) + let target = Vec3.add (Vec3.add hit_result.p hit_result.normal) + (random_in_unit_sphere ()) in + Vec3.mul 0.5 (get_color world {origin = hit_result.p; + dir = Vec3.sub target hit_result.p}) | None -> let unit_direction = unit_vector ray.dir in let t = 0.5 *. (unit_direction.y +. 1.0) in