mirror of
https://github.com/c-cube/moonpool.git
synced 2025-12-10 13:14:05 -05:00
Materials; with metal and lambertian materials
This commit is contained in:
parent
1ca0d7a9ea
commit
4391e3380c
4 changed files with 70 additions and 19 deletions
|
|
@ -3,3 +3,8 @@ type ray = { origin: Vec3.vec3;
|
||||||
|
|
||||||
let point_at_parameter r t =
|
let point_at_parameter r t =
|
||||||
Vec3.add r.origin (Vec3.mul t r.dir)
|
Vec3.add r.origin (Vec3.mul t r.dir)
|
||||||
|
|
||||||
|
let create o d =
|
||||||
|
{ origin = o;
|
||||||
|
dir = d }
|
||||||
|
;;
|
||||||
|
|
|
||||||
|
|
@ -3,15 +3,23 @@ open Printf
|
||||||
open Vec3
|
open Vec3
|
||||||
open Ray
|
open Ray
|
||||||
|
|
||||||
|
type material = Lambertian of Vec3.vec3
|
||||||
|
| Metal of Vec3.vec3
|
||||||
|
| DummyNone
|
||||||
|
|
||||||
type sphere = { center: Vec3.vec3;
|
type sphere = { center: Vec3.vec3;
|
||||||
radius: float }
|
radius: float;
|
||||||
|
mat: material;
|
||||||
|
}
|
||||||
|
|
||||||
type hitable = Sphere of sphere
|
type hitable = Sphere of sphere
|
||||||
| World of hitable list
|
| World of hitable list
|
||||||
|
|
||||||
|
|
||||||
type hit_rec = { t : float;
|
type hit_rec = { t : float;
|
||||||
p: Vec3.vec3;
|
p: Vec3.vec3;
|
||||||
normal: Vec3.vec3; }
|
normal: Vec3.vec3;
|
||||||
|
mat: material; }
|
||||||
|
|
||||||
type hit = hit_rec option
|
type hit = hit_rec option
|
||||||
|
|
||||||
|
|
@ -23,12 +31,32 @@ let random_in_unit_sphere () =
|
||||||
while ((Vec3.dot !p !p) >= 1.0) do
|
while ((Vec3.dot !p !p) >= 1.0) do
|
||||||
p := Vec3.sub (Vec3.mul 2.0 (Vec3.of_floats ((Random.float 1.0),
|
p := Vec3.sub (Vec3.mul 2.0 (Vec3.of_floats ((Random.float 1.0),
|
||||||
(Random.float 1.0),
|
(Random.float 1.0),
|
||||||
(Random.float 1.0))))
|
(Random.float 1.0))))
|
||||||
(Vec3.of_floats (1., 1., 1.))
|
(Vec3.of_floats (1., 1., 1.))
|
||||||
done;
|
done;
|
||||||
!p
|
!p
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
type scatter = { ray : Ray.ray;
|
||||||
|
color: Vec3.vec3; }
|
||||||
|
|
||||||
|
let reflect v n =
|
||||||
|
Vec3.sub v (Vec3.mul (2. *. (Vec3.dot v n)) n)
|
||||||
|
|
||||||
|
let hit_scatter rin hit_rec =
|
||||||
|
match hit_rec.mat with
|
||||||
|
Lambertian albedo ->
|
||||||
|
let target = (Vec3.add (Vec3.add hit_rec.p hit_rec.normal) (random_in_unit_sphere ())) in
|
||||||
|
let scatter = { ray = Ray.create hit_rec.p (Vec3.sub target hit_rec.p);
|
||||||
|
color = albedo; }
|
||||||
|
in scatter
|
||||||
|
(* TODO: C++ version returns boolean here *)
|
||||||
|
| Metal albedo ->
|
||||||
|
let reflected = reflect (Vec3.unit_vector rin.dir) hit_rec.normal in
|
||||||
|
let scattered = { ray = Ray.create hit_rec.p reflected;
|
||||||
|
color = albedo; } in
|
||||||
|
scattered
|
||||||
|
;;
|
||||||
|
|
||||||
let hit_sphere sphere ray (tmin, tmax) =
|
let hit_sphere sphere ray (tmin, tmax) =
|
||||||
let oc = sub ray.origin sphere.center in
|
let oc = sub ray.origin sphere.center in
|
||||||
|
|
@ -46,7 +74,9 @@ let hit_sphere sphere ray (tmin, tmax) =
|
||||||
let p = Ray.point_at_parameter ray t in
|
let p = Ray.point_at_parameter ray t in
|
||||||
Some { t = t;
|
Some { t = t;
|
||||||
p = p;
|
p = p;
|
||||||
normal = mul (1. /. sphere.radius) (sub p sphere.center); }
|
normal = mul (1. /. sphere.radius) (sub p sphere.center);
|
||||||
|
mat = sphere.mat
|
||||||
|
}
|
||||||
else
|
else
|
||||||
let t = (-.b +. (sqrt discriminant)) /. a in
|
let t = (-.b +. (sqrt discriminant)) /. a in
|
||||||
if (t < tmax && t > tmin)
|
if (t < tmax && t > tmin)
|
||||||
|
|
@ -54,7 +84,9 @@ let hit_sphere sphere ray (tmin, tmax) =
|
||||||
let p = Ray.point_at_parameter ray t in
|
let p = Ray.point_at_parameter ray t in
|
||||||
Some { t = t;
|
Some { t = t;
|
||||||
p = p;
|
p = p;
|
||||||
normal = mul (1. /. sphere.radius) (sub p sphere.center); }
|
normal = mul (1. /. sphere.radius) (sub p sphere.center);
|
||||||
|
mat = sphere.mat;
|
||||||
|
}
|
||||||
else None
|
else None
|
||||||
else None
|
else None
|
||||||
|
|
||||||
|
|
@ -65,7 +97,8 @@ let rec hit_world world ray (tmin, tmax) =
|
||||||
let prev_rec = match acc with
|
let prev_rec = match acc with
|
||||||
None -> { t = tmax;
|
None -> { t = tmax;
|
||||||
p = Vec3.of_floats (-1., -1., -1.);
|
p = Vec3.of_floats (-1., -1., -1.);
|
||||||
normal = Vec3.of_floats (-1., -1., -1.); }
|
normal = Vec3.of_floats (-1., -1., -1.);
|
||||||
|
mat = DummyNone}
|
||||||
| Some r -> r in
|
| Some r -> r in
|
||||||
match (hit h ray (tmin, prev_rec.t)) with
|
match (hit h ray (tmin, prev_rec.t)) with
|
||||||
Some r -> Some r
|
Some r -> Some r
|
||||||
|
|
@ -77,13 +110,13 @@ and hit h ray (tmin, tmax) =
|
||||||
| World w -> hit_world w ray (tmin, tmax)
|
| World w -> hit_world w ray (tmin, tmax)
|
||||||
|
|
||||||
|
|
||||||
let rec get_color world ray =
|
let rec get_color world ray depth =
|
||||||
match (hit world ray (0., Float.infinity)) with
|
match (hit world ray (0., Float.infinity)) with
|
||||||
Some hit_result ->
|
Some hit_result ->
|
||||||
let target = Vec3.add (Vec3.add hit_result.p hit_result.normal)
|
if (depth < 50)
|
||||||
(random_in_unit_sphere ()) in
|
then let s = hit_scatter ray hit_result in
|
||||||
Vec3.mul 0.5 (get_color world {origin = hit_result.p;
|
Vec3.pmul s.color (get_color world s.ray (depth+1))
|
||||||
dir = Vec3.sub target hit_result.p})
|
else Vec3.of_floats (0., 0., 0.)
|
||||||
| None ->
|
| None ->
|
||||||
let unit_direction = unit_vector ray.dir in
|
let unit_direction = unit_vector ray.dir in
|
||||||
let t = 0.5 *. (unit_direction.y +. 1.0) in
|
let t = 0.5 *. (unit_direction.y +. 1.0) in
|
||||||
|
|
@ -94,15 +127,21 @@ let write_to_file filename =
|
||||||
Random.self_init ();
|
Random.self_init ();
|
||||||
|
|
||||||
let sphere1 = Sphere {center = Vec3.of_floats (0., 0., -1.);
|
let sphere1 = Sphere {center = Vec3.of_floats (0., 0., -1.);
|
||||||
radius = 0.5 } in
|
radius = 0.5;
|
||||||
|
mat = Lambertian (Vec3.of_floats (0.8, 0.3, 0.3)) } in
|
||||||
let sphere2 = Sphere {center = Vec3.of_floats (0., -100.5, -1.);
|
let sphere2 = Sphere {center = Vec3.of_floats (0., -100.5, -1.);
|
||||||
radius = 100.0 } in
|
radius = 100.0;
|
||||||
let sphere3 = Sphere {center = Vec3.of_floats (-1.0, -0.75, -2.);
|
mat = Lambertian (Vec3.of_floats (0.8, 0.8, 0.0))} in
|
||||||
radius = 0.25 } in
|
let sphere3 = Sphere {center = Vec3.of_floats (-1.0, 0., -1.);
|
||||||
let world = World [sphere2; sphere1; sphere3] in
|
radius = 0.5;
|
||||||
|
mat = Metal (Vec3.of_floats (0.8, 0.6, 0.2))} in
|
||||||
|
let sphere4 = Sphere {center = Vec3.of_floats (1.0, 0., -1.);
|
||||||
|
radius = 0.5;
|
||||||
|
mat = Metal (Vec3.of_floats (0.8, 0.8, 0.8))} in
|
||||||
|
let world = World [sphere3; sphere2; sphere1; sphere4] in
|
||||||
|
|
||||||
let nx = 200 in
|
let nx = 400 in
|
||||||
let ny = 100 in
|
let ny = 200 in
|
||||||
let ns = 100 in
|
let ns = 100 in
|
||||||
let oc = Out_channel.create filename in
|
let oc = Out_channel.create filename in
|
||||||
fprintf oc "P3\n";
|
fprintf oc "P3\n";
|
||||||
|
|
@ -124,7 +163,7 @@ let write_to_file filename =
|
||||||
|
|
||||||
let r = { origin = origin;
|
let r = { origin = origin;
|
||||||
dir = Vec3.add lower_left_corner (Vec3.add (Vec3.mul u horizontal) (Vec3.mul v vertical)) } in
|
dir = Vec3.add lower_left_corner (Vec3.add (Vec3.mul u horizontal) (Vec3.mul v vertical)) } in
|
||||||
color := Vec3.add !color (get_color world r);
|
color := Vec3.add !color (get_color world r 0);
|
||||||
|
|
||||||
done;
|
done;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,3 +36,9 @@ let mul t v =
|
||||||
{ x = t *. v.x;
|
{ x = t *. v.x;
|
||||||
y = t *. v.y;
|
y = t *. v.y;
|
||||||
z = t *. v.z }
|
z = t *. v.z }
|
||||||
|
|
||||||
|
(* pairwise multiplication *)
|
||||||
|
let pmul v w =
|
||||||
|
{ x = v.x *. w.x;
|
||||||
|
y = v.y *. w.y;
|
||||||
|
z = v.z *. w.z; }
|
||||||
|
|
|
||||||
|
|
@ -9,3 +9,4 @@ val dot : vec3 -> vec3 -> float
|
||||||
val cross: vec3 -> vec3 -> vec3
|
val cross: vec3 -> vec3 -> vec3
|
||||||
val mul : float -> vec3 -> vec3
|
val mul : float -> vec3 -> vec3
|
||||||
val unit_vector : vec3 -> vec3
|
val unit_vector : vec3 -> vec3
|
||||||
|
val pmul : vec3 -> vec3 -> vec3
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue