Last active
August 29, 2015 14:26
-
-
Save jrraymond/70803b1fccc221efe580 to your computer and use it in GitHub Desktop.
vectors_conundrum
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type Point = (Float,Float) | |
type GridU = U.Vector Point | |
{- Explanation: colorPixel evaluates to the color of a pixel for a given world | |
- Antialiasing is tracing > 1 rays through each pixel and averaging the results. | |
- Soft shadows are shadows that do not have a hard edge, this requires sending multiple shadow rays to each light. | |
- Depth of field: only objects at a certain distance are in focus. To do this we send multiple rays though each antialising | |
- point with each base perturbed slightly. Objects are in focus if they are at the distance the view plane is at. | |
- | |
- Three arguments: | |
- World -> all the information needed to color a pixel, objects, lights, eye point, view plane distance etc etc | |
- (Point,(V.Vector (U.Vector Point),(GridU,GridU))) -> | |
- The first element (Point) is the screen cordinates of the pixel ex: (0,0) (0,1) | |
- The (V.Vector (U.Vector Point)) is a two dimensional vector of Points used to perturb the base of the ray being traced | |
- to simulate a depth of field effect . | |
The length of the U.Vector Point == the number of depth of field rays being used. | |
The length of V.Vector (U.Vector Point) == the number of antialiasing rays. | |
- (GridU,GridU) -> Two unboxed vectors of points used for antialiasing and soft shadows respectively. | |
- The first is the screen coordinates through which to send the rays. These are randomly jittered. | |
- The second is the first grid shuffled. | |
- The length of each GridU == the number of antialiasing rays. | |
- For the first point in the antialising grid, we send (# depth of field rays) rays through that point and average the results. | |
- We repeat this for all points in the antialiasing grid. | |
- Performance wise this ended up being 2x as slow on a given scene as the list version but ran in 30% space. | |
-} | |
{- world, image plane point, list of list of points for dof pertubations, | |
- jittered grid for antialiasing, shuffled jittered grid for soft shadows -} | |
colorPixel :: World | |
-> (Point,(V.Vector (U.Vector Point),(GridU,GridU))) | |
-> Color | |
colorPixel w ((i,j),(rrs,(pts,sh_grid))) = avgColorsU (U.convert cs0) where | |
d = wMaxDepth w | |
cs0 = V.imap (\ix rs -> let (p,q) = pts U.! ix | |
rfts = sh_grid U.! ix --this is used to create soft shadows and is passed along by ray (read Random FloaT Shadow) | |
rays = U.map (getRay w (i+p,j+q)) rs | |
colors = U.map (raytrace w d rfts) rays | |
in avgColorsU colors) rrs | |
-- in Main this is how colorPixel is used | |
wd = cImageWidth c | |
ht = cImageHeight c | |
rs0 = chunksOf (wAntiAliasing w) (chunksOf (wDOF w) (randomPairs rng)) | |
rs = V.map (V.map U.fromList . V.fromList) (V.fromListN (cImageWidth c + 10) rs0) | |
grids = generateGridsU rng (cImageWidth c + 10) (wAntiAliasing w) | |
info = V.zip rs grids | |
infol = V.length info | |
img = U.generate (wd * ht) | |
(\i -> colorPixel w (pixelIx wd ht i, info V.! mod i infol)) | |
{-if you we interested in pixlelIx | |
- For 8x6 image it turns [0..n] into (0,5),(1,5),(2,5)..(7,5), | |
(0,4),(1,4).. (7,4), | |
(0,3),(1,3).. (7,3)... | |
-} | |
pixelIx :: Int -> Int -> Int -> (Float,Float) | |
pixelIx wd ht i = (fromIntegral (mod i wd), fromIntegral (ht - 1 - div i wd)) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{- Explanation: colorPixel evaluates to the color of a pixel for a given world | |
- Three arguments: | |
- World -> all the information needed to color a pixel, objects, lights, etc etc | |
- (Point,(U.Vector Point,(GridU,GridU))) -> | |
- The first element (Point) is the screen cordinates of the pixel ex: (0,0) (0,1) | |
- The (U.Vector Point)) is the previous vector but smushed into a 1 dimensional vector. | |
- The length == num depth of field rays * num anti aliasing rays. | |
- (GridU,GridU) -> Two unboxed vectors of points used for antialiasing and soft shadows respectively. | |
- The first is the screen coordinates through which to send the rays. These are randomly jittered. | |
- The second is the first grid shuffled. | |
- The length of each GridU == the number of antialiasing rays. | |
- | |
- This ended up being much slower. Previously took 340 seconds on a complex scene with 64 antialiasing rays. Now takes > 20 minutes. I didn't wait to learn how long it actually would take. | |
-} | |
{- world, image plane point, points for dof pertubations, | |
- jittered grid for antialiasing, shuffled jittered grid for soft shadows -} | |
colorPixel :: World | |
-> (Point,(U.Vector Point,(GridU,GridU))) | |
-> Color | |
colorPixel w ((i,j),(rrs,(pts,sh_grid))) = avgColorsU cs0 where | |
d = wMaxDepth w | |
dof = wDOF w | |
cs0 = U.izipWith f pts sh_grid | |
f ix (p,q) rfts = let rs = U.slice (ix * dof) dof rrs --TODO try unsafe slice | |
in avgColorsU $ U.map (raytrace w d rfts . getRay w (i+p,j+q)) rs | |
--and it is used in main in the same way: | |
wd = cImageWidth c | |
ht = cImageHeight c | |
rs0 = chunksOf (cAntiAliasing c) (chunksOf (wDOF w) (randomPairs rng)) | |
rs = V.map (U.fromList . concat) (V.fromListN (cImageWidth c + 10) rs0) | |
grids = generateGridsU rng (cImageWidth c + 10) (wAntiAliasing w) | |
info = V.zip rs grids | |
infol = V.length info | |
img = U.generate (wd * ht) | |
(\i -> colorPixel w (pixelIx wd ht i, info V.! mod i infol)) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment