|
|
|
@ -26,14 +26,14 @@ scatter (Ray o d) (Hit t p n (Lambertian c)) = do |
|
|
|
|
scatter (Ray o d) (Hit t p n (Metal c)) = do |
|
|
|
|
let reflected = reflect (unitVector d) n |
|
|
|
|
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 |
|
|
|
|
scatter (Ray o d) (Hit t p n Glass) = do |
|
|
|
|
let refraction_ratio = if isFrontFace (Ray o d) n then 1.0 / 1.5 else 1.5 |
|
|
|
|
let ud = unitVector d |
|
|
|
|
let ct = min (ud `dotP` n) 1.0 |
|
|
|
|
let ct = min (negated ud `dotP` n) 1.0 |
|
|
|
|
let st = sqrt (1.0 - ct * ct) |
|
|
|
|
rVal <- rand |
|
|
|
|
rVal <- randRange 0 1 |
|
|
|
|
|
|
|
|
|
if refraction_ratio * st > 1.0 || reflectance ct refraction_ratio < rVal |
|
|
|
|
if refraction_ratio * st > 1.0 || reflectance ct refraction_ratio > rVal |
|
|
|
|
then do |
|
|
|
|
let reflected = reflect ud n |
|
|
|
|
return $ Ray p reflected |
|
|
|
@ -70,7 +70,7 @@ getRayColor' (Ray o d) (Just (Hit t p n m)) ws depth = do |
|
|
|
|
colorGradient :: V3 Double -> V3 Double |
|
|
|
|
colorGradient (V3 x y z) = do |
|
|
|
|
let t = 0.5 * (y + 1.0) |
|
|
|
|
(1.0 - t) *^ V3 1.0 1.0 1.0 + t *^ V3 0.5 0.7 1.0 |
|
|
|
|
((1.0 - t) *^ V3 1.0 1.0 1.0) ^+^ (t *^ V3 0.5 0.7 1.0) |
|
|
|
|
|
|
|
|
|
-- from a list of possible hits, get the closest possible hit found |
|
|
|
|
getBestHit :: [Hit] -> Maybe Hit |
|
|
|
@ -93,7 +93,7 @@ rayTrace :: (Shape s) => (Int, Int) -> ImageDimensions -> [s] -> Int -> Camera - |
|
|
|
|
rayTrace coord dim world samples camera = do |
|
|
|
|
let maxDepth = 50 |
|
|
|
|
l <- replicateM samples (evalRandIO (grc coord dim world maxDepth camera)) |
|
|
|
|
return $ foldl (^+^) (V3 0.0 0.0 0.0) l |
|
|
|
|
return $ sumV l |
|
|
|
|
|
|
|
|
|
main :: IO () |
|
|
|
|
main = do |
|
|
|
@ -101,15 +101,11 @@ main = do |
|
|
|
|
let h = 400 |
|
|
|
|
|
|
|
|
|
let aspect = 1.0 -- 16.0 / 9.0 |
|
|
|
|
let viewHeight = 2.0 |
|
|
|
|
let viewWidth = aspect * viewHeight |
|
|
|
|
let focalLength = 1.0 |
|
|
|
|
let camera = makeCamera (V3 0.0 0.0 1.0) (V3 0.0 0.0 (-1.0)) (V3 0.0 1.0 0.0) 90 aspect |
|
|
|
|
|
|
|
|
|
let camera = makeCamera (V3 0.0 0.0 0.0) viewWidth viewHeight focalLength |
|
|
|
|
|
|
|
|
|
let samples = 25 |
|
|
|
|
let samples = 500 |
|
|
|
|
let world = |
|
|
|
|
[ Circle (V3 0.0 0.0 (-1.0)) 0.5 (Glass (V3 1.0 1.0 1.0)), |
|
|
|
|
[ Circle (V3 0.0 0.0 (-1.0)) 0.5 Glass, |
|
|
|
|
Circle (V3 1.0 0.0 (-1.0)) 0.5 (Lambertian (V3 1.0 0.753 0.796)), |
|
|
|
|
Circle (V3 0.0 (-100.5) (-1.0)) 100 (Lambertian (V3 0.7 0.6 0.5)) |
|
|
|
|
] |
|
|
|
|