summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2013-12-03 21:16:59 +0100
committerMatthias P. Braendli <matthias.braendli@mpb.li>2013-12-03 21:16:59 +0100
commit98a7c512b85e99340c10dd4b934ad2ddbcfec246 (patch)
tree2051f3f5657a7197a3402997be94579fbe14761e
parentac83cfc365b5b5bb626d6732868cc479e2325633 (diff)
downloadhaskell-98a7c512b85e99340c10dd4b934ad2ddbcfec246.tar.gz
haskell-98a7c512b85e99340c10dd4b934ad2ddbcfec246.tar.bz2
haskell-98a7c512b85e99340c10dd4b934ad2ddbcfec246.zip
slightly better reflections
-rw-r--r--raytracer.hs46
1 files changed, 32 insertions, 14 deletions
diff --git a/raytracer.hs b/raytracer.hs
index 9f8a184..5b58bd3 100644
--- a/raytracer.hs
+++ b/raytracer.hs
@@ -37,8 +37,8 @@ spherepos = [72]
spheres num = [ trace ("Sphere at " ++
show (round (80 * sin(num * degrees))) ++ "," ++
show (round (80 * cos(num * degrees))) ++ ",5" )
- Sphere (80 * sin(num * degrees), 80 * cos(num * degrees), 5) 10 (255,60,0),
- sphere1, sphere2]
+ Sphere (80 * sin(num * degrees), 80 * cos(num * degrees), 5) 10 (255,60,0),
+ sphere1, sphere2 ]
writenum :: Double -> IO ()
writenum num = trace ("Rendering " ++ show (filename $ round num))
@@ -55,10 +55,10 @@ beta2 = 120 * degrees
floorscale = 4
-w = 192 * 8
-h = 108 * 8
+w = 192 * 4
+h = 108 * 4
-oversampling = 4 -- each pixel is oversampling^2 rays
+oversampling = 1 -- each pixel is oversampling^2 rays
black :: Color
black = (0,0,0)
@@ -95,7 +95,7 @@ spherical_proj (x,y,z) alpha beta dist = (x + dist*(sin beta * cos alpha),
z + dist*cos beta)
cart2spher :: Coord -> Direction
-cart2spher coord = (acos $ z/r, atan2 y x)
+cart2spher coord = ( atan2 y x, acos $ (-z/r))
where (x, y, z) = coord
r = magnitude coord
@@ -107,14 +107,17 @@ spher2cart direction = (sin beta * cos alpha,
-- reflection on sphere
reflect :: Coord -> Direction -> Direction
-reflect normal _ = --trace ("a " ++ show alpha ++ " b " ++ show beta)
- cart2spher normal
+reflect normal incoming = (alph, beta)
where (alpha, beta) = cart2spher normal
+ b = spher2cart incoming
+ n = normalise normal
+ alph = degrees*(fromIntegral (alpha_i `mod` 360) + alpha_f)
+ (alpha_i, alpha_f) = properFraction (alpha/degrees)
reflect2 normal incoming = cart2spher $ ((1) `scale` a) `plus` b
- where a = (b `dot` n) `scale` n
- b = spher2cart incoming
- n = normalise normal
+ where a = (b `dot` n) `scale` n
+ b = spher2cart incoming
+ n = normalise normal
-- intersect sphere
@@ -129,13 +132,27 @@ discr source (alpha, beta) (Sphere centre radius _) = 4*(( aa * u + bb * v + cc
bb = sin beta * sin alpha
cc = cos beta
+--debug
+simplecolor (beta, alpha)
+ | 0 <= alph && alph < 90 = (a,0,0)
+ | 90 <= alph && alph < 180 = (0,a,0)
+ | 180 <= alph && alph < 270 = (0,0,a)
+ | 270 <= alph && alph < 360 = (a,a,0)
+ | otherwise = (0,255,255)
+ where a = trace ("alpha " ++ show (alph)) (if beta > (90*degrees) then 28 else 255)
+ alph = fromIntegral (alpha_i `mod` 360) + alpha_f
+ (alpha_i, alpha_f) = properFraction (alpha/degrees)
+
-- the intersect functions return (Coord, Distance, Color)
-- distance = 0 means no intersection
intersect_sphere :: Coord -> [Sphere] -> Direction -> Sphere -> (Double, Color)
intersect_sphere source spheres (alpha, beta) (Sphere centre radius color)
| delta > 0 = (t,
attenuate_color 0.8 $
- pixel_color intersect_point subspheres reflection_angle
+ pixel_color intersect_point [] reflection_angle
+ --simplecolor reflection_angle
+ --( round $ 200 * ((spher2cart (alpha, beta)) `dot` (normalise normal))
+ -- ,0 ,0)
)
| otherwise = (0, black)
where t = min ((-b - sqrt(delta)) / (2*a)) ((-b + sqrt(delta)) / (2*a))
@@ -149,7 +166,8 @@ intersect_sphere source spheres (alpha, beta) (Sphere centre radius color)
bb = sin beta * sin alpha
cc = cos beta
intersect_point = spherical_proj source alpha beta t
- reflection_angle = reflect (intersect_point `minus` centre) (alpha, beta)
+ reflection_angle = reflect normal (alpha, beta)
+ normal = centre `minus` intersect_point
subspheres = filter ((/=) (Sphere centre radius color)) spheres
@@ -176,7 +194,7 @@ intersect_floor :: Coord -> Direction -> (Coord, Double, Color)
intersect_floor source (alpha, beta)
| x > (-0.5) && x < 0.5 = ((x, y, z), t, (0, attn, attn)) -- x near 0 : cyan
| y > (-0.5) && y < 0.5 = ((x, y, z), t, (attn, attn, 0)) -- y near 0 : yellow
- | beta <= 90*degrees = ((x, y, z), 0, checkerboard_pattern x y 128)
+ | beta <= 90*degrees = ((x, y, z), 0, (128, 128, 128))--checkerboard_pattern x y 128)
| otherwise = ((x, y, z), t, checkerboard_pattern x y attn)
where attn = max 0 (round (255 - 4*(sqrt $ abs t)))
((x, y, z), t) = intersect_point_floor source (alpha, beta)