Commits

Anonymous committed a9c6e7a

added specularities

Comments (0)

Files changed (1)

 type vector3 = float * float * float
 type color = int * int * int
 type normal = Normal of vector3
+type surface = {surface_color:color;reflectance:float;albedo:float}
 type light = {light_center:vector3; light_color:color}
-type sphere = {center:vector3; radius:float; color:color; sph_id:int}
-type plane = {plane_normal:normal; offset:float; plane_color:color;
+type sphere = {center:vector3; radius:float; sph_surf:surface; sph_id:int}
+type plane = {plane_normal:normal; offset:float; plane_surf:surface;
 	      plane_id:int}
 type shape = Sphere of sphere | Plane of plane
 type intersection = {location:vector3;normal:normal;obj:shape}
 let rgb_red : color = (255,0,0)
 let rgb_green : color = (0,255,0)
 let rgb_blue : color = (0,0,255)
+let rgb_yellow : color = (255,255,0)
+let rgb_cyan : color = (0,255,255)
 
 let rgb_r ((r,g,b):color) = r
 let rgb_g ((r,g,b):color) = g
     (mix r1 r2, mix g1 g2, mix b1 b2)
 let rgb_sum ((r1,g1,b1):color) ((r2,g2,b2):color) : color =
   (r1+r2,g1+g2,b1+b2)
+let rgb_arith_mix (c1:color) (c2:color) (mix:float) : color =
+  assert (mix <= 1.0 && mix >= 0.0);
+  rgb_sum (rgb_coeff c1 mix) (rgb_coeff c2 (1.0 -. mix))
 
 let fabs (f:float) : float = if f > 0.0 then f else 0.0 -. f
 let sq x = x *. x 
 
+(* some convenient surfaces *)
+
+let surf_shiny_green = {surface_color=rgb_green; reflectance=0.5; albedo=0.8}
+let surf_shiny_red = {surface_color=rgb_red; reflectance=0.5; albedo=0.5}
+let surf_shiny_blue = {surface_color=rgb_blue; reflectance=0.5; albedo=0.5}
+let surf_shiny_yellow = {surface_color=rgb_yellow;reflectance=0.5; albedo=0.5}
+let surf_shiny_cyan = {surface_color=rgb_cyan;reflectance=0.5; albedo=0.5}
+
 (* vector3 functions *)
 
 let v3_origin = (0.0,0.0,0.0)
     | (Plane p1, Plane p2) -> p1.plane_id = p2.plane_id
     | _ -> false
 
-let shape_color (s:shape) : color =
+let shape_surface (s:shape) : surface =
   match s with
-      Sphere sph -> sph.color
-    | Plane p -> p.plane_color
+      Sphere sph -> sph.sph_surf
+    | Plane p -> p.plane_surf
 
 
 let sphere_intersect (sph:sphere) (src:vector3) (dir:normal) :
 	  let lightd = v3_l2dist light.light_center isect.location in
 	    isectd > lightd)
 
-let handle_illuminated (isect:intersection) (light:light) : color =
+let handle_illuminated (isect:intersection) (ray:normal) (light:light)
+    : color =
+  let strip_norm = function Normal n -> n in
   let light_dir = v3_norm (v3_sub light.light_center isect.location) in
-  let light_norm = match light_dir with Normal n -> n in
-  let isect_norm = match isect.normal with Normal n -> n in
+  let light_norm = strip_norm light_dir in
+  let isect_norm = strip_norm isect.normal in
+  let ray_norm = strip_norm ray in
   let lambertian_coeff = max (v3_dot light_norm isect_norm) 0.0 in
   let light_in = rgb_coeff light.light_color lambertian_coeff in
-    rgb_mix light_in (shape_color isect.obj)
+  let surf = shape_surface isect.obj in
+  let lambert_color = rgb_mix light_in surf.surface_color in
+  let light_normal_comp = -.2.0*.(v3_dot light_norm isect_norm) in
+  let light_reflect_dir = 
+    v3_add light_norm (v3_mul isect_norm light_normal_comp)
+  in
+  let specular_coeff = v3_dot light_reflect_dir ray_norm in
+  let specular_color = rgb_coeff light.light_color specular_coeff in
+    rgb_arith_mix specular_color lambert_color surf.albedo
 
 let handle_ambient (isect:intersection) (ambience:float) : color =
-  rgb_coeff (shape_color isect.obj) ambience
+  rgb_coeff (shape_surface isect.obj).surface_color ambience
 
 let render_ray (src:vector3) (shapes:shape list)
     (lights:light list) (bg:color) (ambience:float) (ray:normal) : color =
 	  let handle_light color light =
 	    let is_illum = illuminated isect shapes light in
 	      if is_illum then (
-		rgb_sum color (handle_illuminated isect light))
+		rgb_sum color (handle_illuminated isect ray light))
 	      else color
 	  in
 	    rgb_sum (handle_ambient isect ambience)
     dump_bitmap out camera colors;
     close_out out
 
-let shapes = [Sphere {center=(10.0,0.0,0.0); radius=2.0; color=rgb_green;
-		      sph_id=0};
+let shapes = [Sphere {center=(10.0,0.0,0.0); radius=2.0;
+		      sph_surf=surf_shiny_green; sph_id=0};
 	      Plane {plane_normal=v3_norm (0.0,1.0,0.0); offset=(5.0);
-		    plane_color=rgb_blue; plane_id=1};
+		    plane_surf=surf_shiny_blue; plane_id=1};
 	      Plane {plane_normal=v3_norm (-.1.0,0.0,0.5); offset=(15.0);
-		     plane_color=(0,255,255); plane_id=2};
+		     plane_surf=surf_shiny_cyan; plane_id=2};
 	      Plane {plane_normal=v3_norm (0.0,0.0,-1.0); offset=10.0;
-		     plane_color=(255,255,0); plane_id=3}]
+		     plane_surf=surf_shiny_yellow; plane_id=3}]
 let lights = [{light_center=(0.0,10.0,0.0); light_color=(200,200,200)};
-	      {light_center=(3.0,0.0,-.4.0);light_color=(100,255,100)}]
+	      {light_center=(3.0,0.0,-.4.0);light_color=(255,100,100)}]
 let camera = {origin=v3_origin; out=v3_norm (1.0,0.0,0.0);
 	      up=v3_norm (0.0,1.0,0.0); width=1024; height=768;
 	      xangle=2.0; yangle=1.5}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.