mirror of
https://github.com/c-cube/moonpool.git
synced 2025-12-15 23:36:04 -05:00
Remove DummyNone material; start work on dielectric material
This commit is contained in:
parent
5e44c0b22a
commit
552a70e6bd
3 changed files with 47 additions and 13 deletions
|
|
@ -5,7 +5,7 @@ open Ray
|
||||||
|
|
||||||
type material = Lambertian of Vec3.vec3 (* albedo *)
|
type material = Lambertian of Vec3.vec3 (* albedo *)
|
||||||
| Metal of Vec3.vec3 * float (* albedo, fuzz *)
|
| Metal of Vec3.vec3 * float (* albedo, fuzz *)
|
||||||
| DummyNone (* TODO: use option type instead *)
|
| Dielectric of float (* refractive index *)
|
||||||
|
|
||||||
type sphere = { center: Vec3.vec3;
|
type sphere = { center: Vec3.vec3;
|
||||||
radius: float;
|
radius: float;
|
||||||
|
|
@ -19,7 +19,7 @@ type hitable = Sphere of sphere
|
||||||
type hit_rec = { t : float;
|
type hit_rec = { t : float;
|
||||||
p: Vec3.vec3;
|
p: Vec3.vec3;
|
||||||
normal: Vec3.vec3;
|
normal: Vec3.vec3;
|
||||||
mat: material; }
|
mat: material option; }
|
||||||
|
|
||||||
type scatter = { ray : Ray.ray;
|
type scatter = { ray : Ray.ray;
|
||||||
color: Vec3.vec3;
|
color: Vec3.vec3;
|
||||||
|
|
@ -41,24 +41,51 @@ let rec random_in_unit_sphere () =
|
||||||
let reflect v n =
|
let reflect v n =
|
||||||
Vec3.sub v (Vec3.mul (2. *. (Vec3.dot v n)) n)
|
Vec3.sub v (Vec3.mul (2. *. (Vec3.dot v n)) n)
|
||||||
|
|
||||||
let hit_scatter rin hit_rec =
|
let refract v n ni_over_nt =
|
||||||
|
let uv = Vec3.unit_vector v in
|
||||||
|
let dt = Vec3.dot uv n in
|
||||||
|
let discriminant = 1.0 -. ((ni_over_nt*.ni_over_nt) *. (1.0 -. dt*.dt)) in
|
||||||
|
if discriminant > 0.0
|
||||||
|
then
|
||||||
|
let refracted = (Vec3.sub (Vec3.mul ni_over_nt (Vec3.sub v (Vec3.mul dt n))) (Vec3.mul (sqrt discriminant) n)) in
|
||||||
|
Some(refracted)
|
||||||
|
else None
|
||||||
|
|
||||||
|
let hit_scatter r_in hit_rec =
|
||||||
match hit_rec.mat with
|
match hit_rec.mat with
|
||||||
(* reflect in random direction *)
|
(* reflect in random direction *)
|
||||||
Lambertian(albedo) ->
|
Some(Lambertian(albedo)) ->
|
||||||
let target = (Vec3.add (Vec3.add hit_rec.p hit_rec.normal) (random_in_unit_sphere ())) in
|
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);
|
let scatter = { ray = Ray.create hit_rec.p (Vec3.sub target hit_rec.p);
|
||||||
color = albedo;
|
color = albedo;
|
||||||
scatter = true;}
|
scatter = true;}
|
||||||
in scatter
|
in scatter
|
||||||
(* "shiny"- angle of reflectance = angle of incidence *)
|
(* "shiny"- angle of reflectance = angle of incidence *)
|
||||||
| Metal(albedo, fuzz) ->
|
| Some(Metal(albedo, fuzz)) ->
|
||||||
let reflected = reflect (Vec3.unit_vector rin.dir) hit_rec.normal in
|
let reflected = reflect (Vec3.unit_vector r_in.dir) hit_rec.normal in
|
||||||
let scattered_ray = Ray.create hit_rec.p (Vec3.add reflected (Vec3.mul fuzz (random_in_unit_sphere ()))) in
|
let scattered_ray = Ray.create hit_rec.p (Vec3.add reflected (Vec3.mul fuzz (random_in_unit_sphere ()))) in
|
||||||
let scattered = { ray = scattered_ray;
|
let scattered = { ray = scattered_ray;
|
||||||
color = albedo;
|
color = albedo;
|
||||||
scatter = (Vec3.dot scattered_ray.dir hit_rec.normal) > 0.0;} in
|
scatter = (Vec3.dot scattered_ray.dir hit_rec.normal) > 0.0;} in
|
||||||
scattered
|
scattered
|
||||||
| DummyNone -> failwith "not a real material type"
|
|
||||||
|
| Some(Dielectric(ref_idx)) ->
|
||||||
|
let reflected = reflect (Vec3.unit_vector r_in.dir) hit_rec.normal in
|
||||||
|
let attenuation = Vec3.of_floats (1.0, 1.0, 1.0) in
|
||||||
|
let (outward_normal, ni_over_nt) =
|
||||||
|
if (Vec3.dot r_in.dir hit_rec.normal) > 0.0
|
||||||
|
then (Vec3.neg hit_rec.normal, ref_idx)
|
||||||
|
else (hit_rec.normal, 1.0 /. ref_idx) in
|
||||||
|
let scattered_ray =
|
||||||
|
match (refract r_in.dir outward_normal ni_over_nt) with
|
||||||
|
| Some(refracted) -> Ray.create hit_rec.p refracted
|
||||||
|
| None -> Ray.create hit_rec.p reflected in
|
||||||
|
let scattered =
|
||||||
|
{ ray= scattered_ray;
|
||||||
|
color= attenuation;
|
||||||
|
scatter = false; } in
|
||||||
|
scattered
|
||||||
|
| None -> failwith "not a real material type"
|
||||||
|
|
||||||
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
|
||||||
|
|
@ -77,7 +104,7 @@ let hit_sphere sphere ray (tmin, tmax) =
|
||||||
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
|
mat = Some(sphere.mat)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
let t = (-.b +. (sqrt discriminant)) /. a in
|
let t = (-.b +. (sqrt discriminant)) /. a in
|
||||||
|
|
@ -87,7 +114,7 @@ let hit_sphere sphere ray (tmin, tmax) =
|
||||||
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;
|
mat = Some(sphere.mat);
|
||||||
}
|
}
|
||||||
else None
|
else None
|
||||||
else None
|
else None
|
||||||
|
|
@ -100,7 +127,7 @@ let rec hit_world world ray (tmin, tmax) =
|
||||||
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}
|
mat = None }
|
||||||
| 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
|
||||||
|
|
@ -137,10 +164,13 @@ let write_to_file filename =
|
||||||
let sphere3 = Sphere {center = Vec3.of_floats (-1.0, 0., -1.);
|
let sphere3 = Sphere {center = Vec3.of_floats (-1.0, 0., -1.);
|
||||||
radius = 0.5;
|
radius = 0.5;
|
||||||
mat = Metal ((Vec3.of_floats (0.8, 0.6, 0.2)), 0.4)} in
|
mat = Metal ((Vec3.of_floats (0.8, 0.6, 0.2)), 0.4)} in
|
||||||
let sphere4 = Sphere {center = Vec3.of_floats (1.0, 0., -1.);
|
(* 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)), 0.1)} in *)
|
||||||
|
let sphere4 = Sphere {center = Vec3.of_floats (1.0, 0.0, -1.);
|
||||||
radius = 0.5;
|
radius = 0.5;
|
||||||
mat = Metal ((Vec3.of_floats (0.8, 0.8, 0.8)), 0.1)} in
|
mat = Dielectric (1.5)} in
|
||||||
let world = World [sphere3; sphere2; sphere1; sphere4] in
|
let world = World [sphere3; sphere2; sphere1; sphere4;] in
|
||||||
|
|
||||||
let nx = 400 in
|
let nx = 400 in
|
||||||
let ny = 200 in
|
let ny = 200 in
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,9 @@ let sub v w =
|
||||||
y = v.y -. w.y;
|
y = v.y -. w.y;
|
||||||
z = v.z -. w.z}
|
z = v.z -. w.z}
|
||||||
|
|
||||||
|
let neg v =
|
||||||
|
sub {x= 0.0; y=0.0; z=0.0} v
|
||||||
|
|
||||||
let dot v w =
|
let dot v w =
|
||||||
v.x*.w.x +. v.y*.w.y +.v.z*.w.z
|
v.x*.w.x +. v.y*.w.y +.v.z*.w.z
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ type vec3 = { x: float;
|
||||||
val of_floats : float * float * float -> vec3
|
val of_floats : float * float * float -> vec3
|
||||||
val add : vec3 -> vec3 -> vec3
|
val add : vec3 -> vec3 -> vec3
|
||||||
val sub : vec3 -> vec3 -> vec3
|
val sub : vec3 -> vec3 -> vec3
|
||||||
|
val neg : vec3 -> vec3
|
||||||
val dot : vec3 -> vec3 -> float
|
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
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue