module Lights(lighten) where import Basics import Vectors import Data.List(minimumBy) import Objects import World import Colors lighten world material pos normal light = if doesLighten world normal pos light then lighten' world material pos normal light else blackColor lighten' world Material{diffuse=diffuse} pos normal light@(DotLight lightPos lightColor) = result where dist2 = sqnorm (lightPos - pos) coef = (lightPos - pos) `dotProd` normal / dist2 * 10 result = abs coef `weight` (diffuse * lightColor) lighten' world Material{diffuse=diffuse} pos normal light@(DirLight lightDir lightColor) = result where coef = lightDir `dotProd` normal result = abs coef `weight` (diffuse * lightColor) lighten' _ Material{diffuse=diffuse} pos normal (AmbientLight color) = color * diffuse doesLighten world normal pos light@(DotLight lightPos lightColor) = all notHiding $ map (distance lightPos (normalized (pos-lightPos))) $ worldObjects world where notHiding x = x > norm (pos-lightPos) - eps doesLighten world normal pos (AmbientLight _) = True doesLighten world normal pos (DirLight dir _) = (rayDir `dotProd` normal) > 0 -- otherwise the surface is oriented to the light && (all (== infinite) $ map (distance (pos + 0.1 `scale` rayDir) rayDir) $ worldObjects world) where rayDir = negate dir