git.haldean.org artray / e0ad60e
Update to [Option] instead of everything being a top-level field in Scene Will Brown 10 years ago
8 changed file(s) with 66 addition(s) and 96 deletion(s). Raw diff Collapse all Expand all
00 module ArtRay.Primitives where
11
2 import Graphics.GD
2 import Data.Maybe
33 import Data.Vect.Double
44 import Debug.Trace
5 import Graphics.GD
56
67 data Scene =
78 Scene {
89 background :: ColorTriple,
9 globalAmbient :: ColorTriple,
10 subpixels :: Int,
10 options :: [Option],
1111 geom :: [Primitive],
1212 lights :: [Light],
1313 viewer :: Viewer
1414 } deriving (Show, Read)
15
16 data Option
17 = Antialiased Double
18 | GlobalAmbient ColorTriple
19 deriving (Show, Read)
1520
1621 data Primitive
1722 = Sphere {
6570 | NullMaterial
6671 deriving (Show, Read, Eq)
6772
68 transmittance :: Material -> Double
69 transmittance (TransparentMaterial _ (WeightSum op) _) = op
70 transmittance _ = 0
71
7273 data Viewer = Viewer {
7374 -- | The location of the viewer
7475 location :: Vec3,
8889 -- field goes from zero to one.
8990 | RelPoint2D Double Double
9091 deriving (Show)
92
93
94 transmittance :: Material -> Double
95 transmittance (TransparentMaterial _ (WeightSum op) _) = op
96 transmittance _ = 0
97
98 glambient :: Scene -> ColorTriple
99 glambient scene =
100 case mapMaybe
101 (\opt -> case opt of GlobalAmbient t -> Just t; otherwise -> Nothing)
102 (options scene) of
103 amb:_ -> amb
104 otherwise -> (0, 0, 0)
105
106 subpixels :: Scene -> Maybe Double
107 subpixels scene =
108 case mapMaybe
109 (\opt -> case opt of Antialiased t -> Just t; otherwise -> Nothing)
110 (options scene) of
111 subp:_ -> Just subp
112 otherwise -> Nothing
113
114 p2d :: Int -> Int -> Point2D
115 p2d x y = Point2D (fromIntegral x) (fromIntegral y)
91116
92117 color :: Double -> Double -> Double -> ColorTriple
93118 color r g b = (r, g, b)
3333 baseColor = colorFor scene shape basemat direction location depth
3434
3535 PhongMaterial spec diff amb exp ->
36 sumLight ((combine amb (globalAmbient scene)) :
36 sumLight ((combine amb (glambient scene)) :
3737 (phongLight scene shape mat ray norm `map` lights scene))
3838 where ray = Ray direction location
3939 norm = normal shape location
44 import ArtRay.RayTrace
55 import Graphics.GD
66 import ArtRay.Geometry
7 import Debug.Trace
8
79
810 -- | Raytrace an image without antialiasing
9 rayTraceImage :: Scene -> Size -> Point2D -> ColorTriple
10 rayTraceImage scene size point@(Point2D x y) =
11 rayTraceImage' :: Scene -> Size -> Point2D -> ColorTriple
12 rayTraceImage' scene size point@(Point2D x y) =
1113 pixelColor size scene (viewer scene) point
1214
1315 -- | Raytrace an image with antialiasing by subpixel sampling
14 rayTraceImage' :: Scene -> Size -> Point -> ColorTriple
15 rayTraceImage' scene size (x, y) =
16 meanColor $ map (rayTraceImage scene size)
17 [Point2D (fromIntegral x + x') (fromIntegral y + y')
18 | x' <- [(-0.5),inc..0.5], y' <- [(-0.5),inc..0.5]]
19 where inc = (-0.5) + (1 / (fromIntegral $ subpixels scene))
16 rayTraceImage :: Scene -> Size -> Point -> ColorTriple
17 rayTraceImage scene size (x, y) =
18 case subpixels scene of
19 Just subpixels ->
20 meanColor $ map (rayTraceImage' scene size)
21 [Point2D (fromIntegral x + x') (fromIntegral y + y')
22 | x' <- [(-0.5),inc..0.5], y' <- [(-0.5),inc..0.5]]
23 where inc = (-0.5) + 1 / subpixels
24 otherwise -> rayTraceImage' scene size (p2d x y)
2025
2126 applyToImage :: (Size -> Point -> ColorTriple) -> Image -> IO()
2227 applyToImage imFunc im =
2934 render scene size outfile =
3035 do
3136 im <- newImage (size, size)
32 applyToImage (rayTraceImage' scene) im
37 applyToImage (rayTraceImage scene) im
3338 savePngFile outfile im
2424 * Point light sources
2525 * Basic reflection model
2626 * Basic refraction model
27 * Anti-aliasing (new!)
2728
2829 Planned Features:
2930
3031 * Triangle meshes
3132 * Texturing
32 * Anti-aliasing
33 * B-Spline surfaces
34 * Parallel rendering
+0
-33
scenes/noisetest.ar less more
0 Scene {
1 geom = [
2 Sphere {
3 center = Vec3 10.0 0 0,
4 radius = 2.0,
5 material = TransparentMaterial {
6 base = ColorMaterial {
7 basecolor = (0, 1, 0)
8 },
9 opacity = 0.5,
10 refindex = 1
11 }
12 }
13 ],
14
15 background = (0.0,0.0,0.0),
16 global_ambient = (0.4,0.4,0.4),
17 lights = [
18 PhongLight {
19 speclight = (1.0,1.0,1.0),
20 difflight = (1.0,1.0,1.0),
21 loclight = Vec3 6.0 4.0 0.0
22 }
23 ],
24
25 viewer = Viewer {
26 location = Vec3 0.0 0.0 0.0,
27 u = Vec3 0.0 0.422 0.0,
28 v = Vec3 0.0 0.0 0.422,
29 f = Vec3 1.0 0 0.0
30 }
31 }
32
+0
-34
scenes/rect.ar less more
0 Scene {
1 geom = [
2 RectPrism {
3 corner = Vec3 5 (-1) 0,
4 x = Vec3 1 0 0,
5 y = Vec3 0 2 0,
6 z = Vec3 0 0 1,
7 material = PhongMaterial {
8 specular = (0.0,0.0,0.0),
9 diffuse = (0.4,0.4,0.7),
10 ambient = (0.0,0.0,0.2),
11 phongexp = 4
12 }
13 }
14 ],
15
16 background = (0.0,0.0,0.0),
17 global_ambient = (0.4,0.4,0.4),
18 lights = [
19 PhongLight {
20 speclight = (1.0,1.0,1.0),
21 difflight = (1.0,1.0,1.0),
22 loclight = Vec3 5 2 (-2)
23 }
24 ],
25
26 viewer = Viewer {
27 location = Vec3 0.0 0.0 0.0,
28 u = Vec3 0 0.9 0,
29 v = Vec3 0 0 0.9,
30 f = Vec3 1 0 0
31 }
32 }
33
00 Scene {
1 background = (0.0, 0.0, 0.0),
2 options = [
3 GlobalAmbient (0.4, 0.4, 0.4),
4 Antialiased 4
5 ],
6
17 geom = [
28 Sphere {
39 center = Vec3 14.0 (-4.0) 0.0,
3642 }
3743 ],
3844
39 subpixels = 4,
40 background = (0.0, 0.0, 0.0),
41 globalAmbient = (0.4, 0.4, 0.4),
42
4345 lights = [
4446 PhongLight {
45 speclight = (1.0, 1.0, 1.0),
46 difflight = (1.0, 1.0, 1.0),
47 loclight = Vec3 6.0 4.0 0.0
48 }],
47 speclight = (1.0, 1.0, 1.0),
48 difflight = (1.0, 1.0, 1.0),
49 loclight = Vec3 6.0 4.0 0.0
50 }
51 ],
4952
5053 viewer = Viewer {
5154 location = Vec3 0.0 0.0 0.0,
00 Scene {
1 background = (0.0,0.0,0.0),
2 options = [
3 GlobalAmbient (0.4, 0.4, 0.4)
4 ],
5
16 geom = [
27 Sphere {
38 center = Vec3 14.0 (-4.0) 0.0,
3338 }
3439 ],
3540
36 background = (0.0,0.0,0.0),
37 globalAmbient = (0.4,0.4,0.4),
3841 lights = [
3942 PhongLight {
4043 speclight = (1.0,1.0,1.0),
5053 f = Vec3 1.0 (-0.2) 0.0
5154 }
5255 }
53