Advertisement
Guest User

Untitled

a guest
May 17th, 2018
154
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 7.49 KB | None | 0 0
  1. namespace Tracer
  2. module Material =
  3.     open System
  4.     open Interfaces
  5.     open System.Threading
  6.     open Vector
  7.  
  8.     //Might need to take the average of the colourSums, we'll see when I can test
  9.  
  10.     let Pi = Math.PI
  11.     let e = 0.00001
  12.        
  13.     let reflectLight (ld:Vector) (n:Vector) = -ld + (2.0 * (n * ld)) * n
  14.     let reflectRay (dir:Vector) (n:Vector) = dir + (-2.0 * (n * dir) * n)
  15.    
  16.     let rec shadeMatte (kdcdPi:Colour) (p:Point) (n:Vector) (lights:ILight list) (scene:IScene) (acc:Colour) =
  17.         match lights with
  18.         | l :: rest -> let ls = l.s p n scene
  19.                        let ld = l.d p
  20.                        let lG = l.G
  21.                        let lpdf = l.pdf n
  22.                        let lc = l.c p scene
  23.                        
  24.  
  25.                        let cosPhi = n*ld
  26.                        if not ls && cosPhi > 0.0
  27.                        then let colour = acc + (kdcdPi * (lG/lpdf) * lc * cosPhi)
  28.                             shadeMatte kdcdPi p n rest scene colour
  29.                        else shadeMatte kdcdPi p n rest scene acc
  30.         | [] -> acc
  31.    
  32.     let spec (cs:Colour) (ks:float) (exp:int) (rl:Vector) (rd:Vector) =
  33.         if (rl * (-rd)) > 0.0
  34.         then ks * cs * (pown (rl * -rd) exp)
  35.         else Colour.BLACK
  36.  
  37.     let reflect (cr:Colour) (kr:float) (p:Point) (d':Vector) (scene:IScene) (depth:int) =
  38.        if depth <= scene.maxDepth
  39.        then
  40.            let hit = scene.traceRay p d'
  41.             if hit.IsNone then Colour.BLACK
  42.             else
  43.                 let hit = hit.Value :?> ShapeHit
  44.                 let n2 = hit.n
  45.                 let mat2 = hit.m
  46.                 let hp = hit.p
  47.                 let n2 =
  48.                     if d' * n2 > 0.0
  49.                    then -n2
  50.                    else n2
  51.                let p' = hp + e * n2
  52.                 kr * cr * (mat2.shade p' d' n2 scene (depth+1))
  53.         else Colour.BLACK
  54.  
  55.  
  56.     let rec shadePhong (kdcdPi:Colour) (cs:Colour) (ks:float) (exp:int) (dir:Vector) (p:Point) (n:Vector) (lights:ILight list) (scene:IScene) (acc:Colour) =
  57.         match lights with
  58.         | l :: rest -> let ls = l.s p n scene
  59.                        let ld = l.d p
  60.                        let nld = n * ld
  61.                        let rl = (-ld) + (2.0 * (nld)) * n
  62.                        let rlrd = rl * (-dir)
  63.                        let shade = if (not ls) && nld > 0.0
  64.                                    then let spec = if rlrd > 0.0
  65.                                                     then (ks * cs) * (pown rlrd exp)
  66.                                                     else Colour.BLACK
  67.                                         let acc = acc + (kdcdPi + spec) * ((l.G/(l.pdf n))*(l.c p scene) * nld)
  68.                                         shadePhong kdcdPi cs ks exp dir p n rest scene acc
  69.                                    else shadePhong kdcdPi cs ks exp dir p n rest scene acc
  70.                        match shade with
  71.                        | Colour.RGB(r,g,b) -> if Double.IsInfinity r then failwith "infinity"
  72.                        shade
  73.         | [] -> acc
  74.  
  75.     type MatteMaterial(ca:Colour, ka:float, cd:Colour, kd:float) =
  76.         let kdcdPi = (kd*cd) / Pi
  77.         interface IMaterial with
  78.             member this.shade p d n scene depth =
  79.                 let ambient = ca * ka * scene.ambientLight.c p n scene
  80.                 let n = if d * n > 0.0 then -n else n
  81.                 let p' = p + (e * n)
  82.                shadeMatte kdcdPi p' n scene.lights scene ambient
  83.  
  84.            
  85.     type MatteReflectiveMaterial(ca:Colour, ka:float, cd:Colour, kd:float, cr:Colour, kr:float) =
  86.         let kdcdPi = (kd*cd / Pi)
  87.         interface IMaterial with
  88.             member this.shade p d n scene depth =
  89.                 let ambient = ca * ka * scene.ambientLight.c p n scene
  90.                 let n = if d * n > 0.0 then -n else n
  91.                 let p' = p + (e * n)
  92.                let d' = d + (-2.0 * (n * d)) * n
  93.                 let c = shadeMatte kdcdPi p' n scene.lights scene ambient
  94.                c + reflect cr kr p' d' scene depth
  95.    
  96.    type PhongMaterial(ca:Colour, ka:float, cd:Colour, kd:float, cs:Colour, ks:float, exp:int) =
  97.        let kdcdPi = (kd * cd) / Pi
  98.        interface IMaterial with
  99.            member this.shade p d n scene depth =
  100.                let ambient = ca * ka * scene.ambientLight.c p n scene
  101.                let dn = d * n
  102.                let n = if dn > 0.0 then -n else n
  103.                let p' = p + (e * n)
  104.                 shadePhong kdcdPi cs ks exp d p' n scene.lights scene ambient
  105.        
  106.    type PhongReflectiveMaterial(ca:Colour, ka:float, cd:Colour, kd:float, cs:Colour, ks:float, cr:Colour, kr:float, exp:int) =
  107.        let kdcdPi = (kd * cd) / Pi
  108.        interface IMaterial with
  109.            member this.shade p d n scene depth =
  110.                let ambient = ca * ka * scene.ambientLight.c p n scene
  111.                let n = if d * n > 0.0 then -n else n
  112.                let p' = p + e * n
  113.                 let d' = d + (-2.0 * (n * d)) * n
  114.                let c = shadePhong kdcdPi cs ks exp d p' n scene.lights scene ambient
  115.                 c + reflect cr kr p' d' scene depth
  116.  
  117.     type MatteGlossyReflectiveMaterial(ca : Colour, ka : float, cd : Colour, kd : float, cr : Colour, kr : float, s : ISampler) =
  118.         let kdcdPi = (kd*cd) / Pi
  119.         interface IMaterial with
  120.             member this.shade p d n scene depth =
  121.                 let spx,spy,spz = s.getNext Thread.CurrentThread.ManagedThreadId
  122.                 let ambient = ca * ka * scene.ambientLight.c p n scene
  123.                 let n = if d * n > 0.0
  124.                         then -n
  125.                         else n
  126.                 let p' = p + e * n
  127.                let c = shadeMatte kdcdPi p' n scene.lights scene ambient
  128.                 let d' = d + 2.0 * (n * -d) * n
  129.                let frame = OrthonormalFrame(d')
  130.                 let frameDir = normalize (Point.direction (Point.mkPoint 0.0 0.0 0.0) (Point.mkPoint spx spy spz))
  131.                 let d'' = normalize (convertOrthVector frameDir frame)
  132.                 let d''' =
  133.                    if Vector.dotProduct n d'' > 0.0
  134.                    then mkVector -(Vector.getX d'') -(Vector.getY d'') (Vector.getZ d'')
  135.                    else d''
  136.                c + reflect cr kr p' d''' scene depth
  137.  
  138.    type PhongGlossyReflectiveMaterial (ca : Colour, ka : float, cd : Colour, kd : float, cs : Colour, ks : float, cr : Colour, kr : float, exps : int, expr : int, s : ISampler) =
  139.        interface IMaterial with
  140.            member this.shade p d n scene depth = failwith "venter på Peter"
  141.  
  142.    type EmissiveMaterial(c : Colour, i : float) =
  143.        member this.er = c * i
  144.        interface IMaterial with
  145.            member this.shade p d n scene depth =
  146.                if (n * -d > 0.0) then this.er
  147.                else Colour.BLACK
  148.  
  149.    
  150.  
  151.  
  152.    let mkMatteMaterial ca ka cd kd = new MatteMaterial(ca, ka, cd, kd) :> IMaterial
  153.    let mkMatteReflectiveMaterial ca ka cd kd cr kr = new MatteReflectiveMaterial(ca, ka, cd, kd, cr, kr) :> IMaterial
  154.    let mkPhongMaterial ca ka cd kd cs ks exp = new PhongMaterial(ca, ka, cd, kd, cs, ks, exp) :> IMaterial
  155.    let mkPhongReflectiveMaterial ca ka cd kd cs ks cr kr exp = new PhongReflectiveMaterial(ca, ka, cd, kd, cs, ks, cr, kr, exp) :> IMaterial
  156.    let mkMatteGlossyReflectiveMaterial ca ka cd kd cr kr s = new MatteGlossyReflectiveMaterial(ca, ka, cd, kd, cr, kr, s) :> IMaterial
  157.    let mkEmissiveMaterial c i = new EmissiveMaterial(c, i) :> IMaterial
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement