|
|
@ -35,6 +35,20 @@ scatter (Ray o d) (Hit t p n (Lambertian c)) = do |
|
|
|
scatter (Ray o d) (Hit t p n (Metal c)) = do |
|
|
|
scatter (Ray o d) (Hit t p n (Metal c)) = do |
|
|
|
let reflected = reflect (unitVector d) n |
|
|
|
let reflected = reflect (unitVector d) n |
|
|
|
return $ Ray p reflected |
|
|
|
return $ Ray p reflected |
|
|
|
|
|
|
|
scatter (Ray o d) (Hit t p n (Glass c)) = do |
|
|
|
|
|
|
|
let refraction_ratio = if isFrontFace (Ray o d) n then 1.0 / 1.5 else 1.0 |
|
|
|
|
|
|
|
let ud = unitVector d |
|
|
|
|
|
|
|
let ct = min (ud `dotP` (unitVector n)) 1.0 |
|
|
|
|
|
|
|
let st = sqrt (1.0 - ct * ct) |
|
|
|
|
|
|
|
rVal <- rand |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if refraction_ratio * st > 1.0 || reflectance ct refraction_ratio < rVal |
|
|
|
|
|
|
|
then do |
|
|
|
|
|
|
|
let reflected = reflect ud n |
|
|
|
|
|
|
|
return $ Ray p reflected |
|
|
|
|
|
|
|
else do |
|
|
|
|
|
|
|
let refracted = refract ud n refraction_ratio |
|
|
|
|
|
|
|
return $ Ray p refracted |
|
|
|
|
|
|
|
|
|
|
|
getRayColor :: (Shape s, RandomGen g) => [s] -> Int -> Ray Double -> Rand g (V3 Double) |
|
|
|
getRayColor :: (Shape s, RandomGen g) => [s] -> Int -> Ray Double -> Rand g (V3 Double) |
|
|
|
getRayColor ws d r = do |
|
|
|
getRayColor ws d r = do |
|
|
@ -105,8 +119,9 @@ main = do |
|
|
|
let w = 400 |
|
|
|
let w = 400 |
|
|
|
let h = 400 |
|
|
|
let h = 400 |
|
|
|
let world = |
|
|
|
let world = |
|
|
|
[ Circle (V3 0.0 0.0 (-1.0)) 0.25 (Metal (V3 0.8 0.8 0.8)), |
|
|
|
[ Circle (V3 (0.0) 0.0 (-1.0)) 0.25 (Glass (V3 1.0 1.0 1.0)), |
|
|
|
Circle (V3 0.0 (-10.25) (-1.0)) 10 (Lambertian (V3 0.7 0.3 0.3)) |
|
|
|
Circle (V3 (-0.5) 0.0 (-1.0)) 0.25 (Lambertian (V3 0.7 0.1 0.1)), |
|
|
|
|
|
|
|
Circle (V3 0.0 (-10.25) (-1.0)) 10 (Lambertian (V3 0.7 0.6 0.5)) |
|
|
|
] |
|
|
|
] |
|
|
|
let coords = reverse $ range ((-1 * (w `div` 2), -1 * (h `div` 2)), ((w `div` 2) - 1, (h `div` 2) - 1)) -- "canvas" |
|
|
|
let coords = reverse $ range ((-1 * (w `div` 2), -1 * (h `div` 2)), ((w `div` 2) - 1, (h `div` 2) - 1)) -- "canvas" |
|
|
|
colors <- mapM (\x -> rayTrace x (w, h) (1.0, 1.0) world) coords |
|
|
|
colors <- mapM (\x -> rayTrace x (w, h) (1.0, 1.0) world) coords |
|
|
|