added diffuse light
This commit is contained in:
parent
3ab4789740
commit
197e1a84d7
@ -19,29 +19,66 @@ import Debug.Trace
|
|||||||
|
|
||||||
data Ray = Ray (V3 Float) (V3 Float)
|
data Ray = Ray (V3 Float) (V3 Float)
|
||||||
|
|
||||||
data Collision = Collision (V3 Float) Float Collidable
|
-- | Collision position normal distance object
|
||||||
|
data Collision = Collision (V3 Float) (V3 Float) Float Collidable
|
||||||
deriving (Eq)
|
deriving (Eq)
|
||||||
|
|
||||||
instance Ord Collision where
|
instance Ord Collision where
|
||||||
compare (Collision _ a _) (Collision _ b _) = compare a b
|
compare (Collision _ _ a _) (Collision _ _ b _) = compare a b
|
||||||
|
|
||||||
render :: Int -> Int -> Scene -> Int -> PixelRGB8
|
render :: Int -> Int -> Scene -> Int -> PixelRGB8
|
||||||
render w h s index = case pcolls of
|
render w h s index = PixelRGB8 (ci cr) (ci cg) (ci cb)
|
||||||
[] -> PixelRGB8 (ci br) (ci bg) (ci bb) --no collision -> Background
|
|
||||||
_ -> PixelRGB8 (ci ar) (ci ag) (ci ab) --collission -> git color
|
|
||||||
where
|
where
|
||||||
(V3 ar ag ab) = materialAmbience $ getMaterial coll
|
(V3 cr cg cb) =
|
||||||
(Background (V3 br bg bb)) = sceneBackground s
|
case raytrace ray s of
|
||||||
pcolls = map fromJust $ filter isJust $ (intersect ray) <$> (sceneObjects s)
|
Nothing -> bgColor $ sceneBackground s
|
||||||
(Collision pos _ coll) = foldl1 min pcolls
|
Just c@(Collision pos _ _ obj) ->
|
||||||
|
-- ambient lighting
|
||||||
|
((*) <$> (ambColor . ambientLight $ s) <*> (materialAmbience . getMaterial $ obj))
|
||||||
|
-- + diffuse lighting
|
||||||
|
^+^ (foldl1 (^+^) $ (diffuse c s) <$> sceneLights s)
|
||||||
|
-- + reflections - TODO
|
||||||
ray = camRay x y (sceneCamera s)
|
ray = camRay x y (sceneCamera s)
|
||||||
y = fromIntegral $ index `mod` w
|
y = fromIntegral $ index `mod` w
|
||||||
x = fromIntegral $ index `div` w
|
x = fromIntegral $ index `div` w
|
||||||
ci = floor . (*255)
|
ci = floor . (clamp 0 255) . (*255)
|
||||||
--wrong format:
|
--wrong format:
|
||||||
--Ray (eye cam) $ rotCam x y w h (center cam ^-^ eye cam) (up cam) (fovy cam)
|
--Ray (eye cam) $ rotCam x y w h (center cam ^-^ eye cam) (up cam) (fovy cam)
|
||||||
--cam = sceneCamera s
|
--cam = sceneCamera s
|
||||||
|
|
||||||
|
diffuse :: Collision -> Scene -> Light -> V3 Float
|
||||||
|
diffuse (Collision pos n _ obj) s (Light lpos color int) =
|
||||||
|
case blocked of
|
||||||
|
Nothing -> ill
|
||||||
|
Just (Collision _ _ dist _) -> if dist < norm lightdir
|
||||||
|
then
|
||||||
|
V3 0 0 0 --light is blocked -> no lighting from here.
|
||||||
|
else
|
||||||
|
ill
|
||||||
|
where
|
||||||
|
ill = (*) (dot n $ normalize lightdir) <$> illumination
|
||||||
|
illumination = (*) <$> color ^* i <*> materialDiffuse mat
|
||||||
|
mat = getMaterial obj
|
||||||
|
blocked = raytrace (Ray pos lightdir) s
|
||||||
|
lightdir = (lpos ^-^ pos)
|
||||||
|
i = case int of
|
||||||
|
Nothing -> 1
|
||||||
|
Just a -> a
|
||||||
|
|
||||||
|
clamp :: Ord a => a -> a -> a -> a
|
||||||
|
clamp min max x
|
||||||
|
| x < min = min
|
||||||
|
| x > max = max
|
||||||
|
| otherwise = x
|
||||||
|
|
||||||
|
raytrace :: Ray -> Scene -> Maybe Collision
|
||||||
|
raytrace r s = case possibleCollisions of
|
||||||
|
[] -> Nothing
|
||||||
|
_ -> Just $ foldl1 min possibleCollisions
|
||||||
|
where
|
||||||
|
possibleCollisions :: [Collision]
|
||||||
|
possibleCollisions = map fromJust $ filter isJust $ (intersect r) <$> (sceneObjects s)
|
||||||
|
|
||||||
camRay :: Float -> Float -> Camera -> Ray
|
camRay :: Float -> Float -> Camera -> Ray
|
||||||
camRay x y c = Ray (eye c) (lowerLeft c ^+^ x *^ xDir c ^+^ y *^ yDir c ^-^ eye c)
|
camRay x y c = Ray (eye c) (lowerLeft c ^+^ x *^ xDir c ^+^ y *^ yDir c ^-^ eye c)
|
||||||
|
|
||||||
@ -52,7 +89,7 @@ rotateDegAx phi axis = rotate q
|
|||||||
|
|
||||||
intersect :: Ray -> Collidable -> Maybe Collision
|
intersect :: Ray -> Collidable -> Maybe Collision
|
||||||
intersect (Ray ro rd) s@(S (Sphere sc sr _)) = if (d > 0 && int > 0) then
|
intersect (Ray ro rd) s@(S (Sphere sc sr _)) = if (d > 0 && int > 0) then
|
||||||
Just (Collision (ro ^+^ (rd ^* int)) int s)
|
Just (Collision pos (normalize $ pos ^-^ sc) int s)
|
||||||
else
|
else
|
||||||
Nothing
|
Nothing
|
||||||
where
|
where
|
||||||
@ -61,6 +98,7 @@ intersect (Ray ro rd) s@(S (Sphere sc sr _)) = if (d > 0 && int > 0) then
|
|||||||
c = dot oc oc - sr*sr
|
c = dot oc oc - sr*sr
|
||||||
d = b * b - 4 * a * c
|
d = b * b - 4 * a * c
|
||||||
oc = ro ^-^ sc
|
oc = ro ^-^ sc
|
||||||
|
pos = ro ^+^ (rd ^* int)
|
||||||
int = case ints of
|
int = case ints of
|
||||||
[] -> 0
|
[] -> 0
|
||||||
a -> foldl1 min a
|
a -> foldl1 min a
|
||||||
@ -77,4 +115,3 @@ rotCam x y w h dir up fovy = rotxy
|
|||||||
dx = (x - (fromIntegral w) / 2)/(fromIntegral w)
|
dx = (x - (fromIntegral w) / 2)/(fromIntegral w)
|
||||||
dy = (y - (fromIntegral h) / 2)/(fromIntegral h)
|
dy = (y - (fromIntegral h) / 2)/(fromIntegral h)
|
||||||
rad = (*pi).(/180)
|
rad = (*pi).(/180)
|
||||||
|
|
||||||
|
@ -20,10 +20,14 @@ data Camera = Camera
|
|||||||
|
|
||||||
type RecursionDepth = Int
|
type RecursionDepth = Int
|
||||||
|
|
||||||
data Background = Background Color
|
data Background = Background
|
||||||
|
{ bgColor :: Color
|
||||||
|
}
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq)
|
||||||
|
|
||||||
data Ambience = Ambience Color
|
data Ambience = Ambience
|
||||||
|
{ ambColor :: Color
|
||||||
|
}
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq)
|
||||||
|
|
||||||
data Light = Light (V3 Float) Color (Maybe Intensity)
|
data Light = Light (V3 Float) Color (Maybe Intensity)
|
||||||
|
Loading…
Reference in New Issue
Block a user