diff --git a/scenes/test.sce b/scenes/test.sce index a2fbc30..4a70eef 100644 --- a/scenes/test.sce +++ b/scenes/test.sce @@ -21,4 +21,4 @@ sphere -1.0 0.5 2.0 0.5 0.0 1.0 0.0 0.0 1.0 0.0 1.0 1.0 1.0 200.0 0.2 sphere 3.0 2.0 1.5 2.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 1.0 1.0 50.0 0.2 # planes: center, normal, material -#plane 0 0 0 0 1 0 0.2 0.2 0.2 0.2 0.2 0.2 0.0 0.0 0.0 100.0 0.1 +plane 0 0 0 0 1 0 0.2 0.2 0.2 0.2 0.2 0.2 0.0 0.0 0.0 100.0 0.1 diff --git a/src/Scene/Parser.hs b/src/Scene/Parser.hs index b140354..98a200f 100644 --- a/src/Scene/Parser.hs +++ b/src/Scene/Parser.hs @@ -122,7 +122,7 @@ parsePlane = do endOfLine return $ OpP Plane { planeCenter = c - , planeNormal = n + , planeNormal = normalize n , planeMaterial = m } diff --git a/src/Scene/Renderer.hs b/src/Scene/Renderer.hs index 29d0d25..050bd88 100644 --- a/src/Scene/Renderer.hs +++ b/src/Scene/Renderer.hs @@ -15,7 +15,7 @@ import Linear import Scene.Parser import Scene.Types -import Debug.Trace +import Debug.Trace as D data Ray = Ray (V3 Float) (V3 Float) @@ -26,6 +26,9 @@ data Collision = Collision (V3 Float) (V3 Float) Float Collidable instance Ord Collision where compare (Collision _ _ a _) (Collision _ _ b _) = compare a b +epsilon :: Float +epsilon = 0.00001 + render :: Int -> Int -> Scene -> Int -> PixelRGB8 render w h s index = PixelRGB8 (ci cr) (ci cg) (ci cb) where @@ -36,14 +39,14 @@ render w h s index = PixelRGB8 (ci cr) (ci cg) (ci cb) -- ambient lighting ((ambColor . ambientLight $ s) * (materialAmbience . getMaterial $ obj)) -- + diffuse lighting - ^+^ (foldl1 (^+^) $ (diffuse c s) <$> sceneLights s) + + (foldl1 (+) $ (diffuse c s) <$> sceneLights s) -- + reflections - TODO ray = camRay x y (sceneCamera s) y = fromIntegral $ index `mod` w x = fromIntegral $ index `div` w ci = floor . (clamp 0 255) . (*255) --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 diffuse :: Collision -> Scene -> Light -> V3 Float @@ -59,7 +62,7 @@ diffuse (Collision pos n _ obj) s (Light lpos color int) = ill = i * dot n (normalize lightdir) *^ color * materialDiffuse mat mat = getMaterial obj blocked = raytrace (Ray pos lightdir) s - lightdir = (lpos ^-^ pos) + lightdir = (lpos - pos) i = case int of Nothing -> 1 Just a -> a @@ -79,7 +82,7 @@ raytrace r s = case possibleCollisions of possibleCollisions = map fromJust $ filter isJust $ (intersect r) <$> (sceneObjects s) 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) rotateDegAx :: Float -> V3 Float -> V3 Float -> V3 Float rotateDegAx phi axis = rotate q @@ -88,7 +91,7 @@ rotateDegAx phi axis = rotate q intersect :: Ray -> Collidable -> Maybe Collision intersect (Ray ro rd) s@(S (Sphere sc sr _)) = if (d > 0 && int > 0) then - Just (Collision pos (normalize $ pos ^-^ sc) int s) + Just $ Collision pos (normalize $ pos - sc) int s else Nothing where @@ -96,12 +99,21 @@ intersect (Ray ro rd) s@(S (Sphere sc sr _)) = if (d > 0 && int > 0) then b = 2 * dot rd oc c = dot oc oc - sr*sr d = b * b - 4 * a * c - oc = ro ^-^ sc - pos = ro ^+^ (rd ^* int) + oc = ro - sc + pos = ro + (rd ^* int) int = case ints of [] -> 0 a -> foldl1 min a - ints = filter (uncurry (&&).(&&&) (>0.00001) (not.isNaN)) [(-b-(sqrt d))/(2*a),(-b+(sqrt d))/(2*a)] + ints = filter (uncurry (&&).(&&&) (>epsilon) (not.isNaN)) [(-b-(sqrt d))/(2*a),(-b+(sqrt d))/(2*a)] +intersect (Ray ro rd) p@(P (Plane pc pn _)) = if det == 0 || t < epsilon + then Nothing + else Just -- $ D.trace (show (det, t, pos)) + $ Collision pos pn t p + where + pos = ro + t *^ rd' + det = dot rd' pn + t = (dot (pc - ro) pn)/det + rd' = normalize rd intersect _ _ = undefined