-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathCamera.roc
More file actions
64 lines (53 loc) · 1.67 KB
/
Camera.roc
File metadata and controls
64 lines (53 loc) · 1.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
interface Camera
exposes [Camera, make, ray]
imports [Vec.{ Vec }, Ray.{ Ray }, RNG.{ RNG }, Math]
Camera : {
origin : Vec,
lowerLeftCorner : Vec,
horizontal : Vec,
vertical : Vec,
u : Vec,
v : Vec,
w : Vec,
lensRadius : F64,
}
make : { lookFrom : Vec, lookAt : Vec, up : Vec, fov : F64, aspectRatio : F64, aperture : F64, focusDist : F64 } -> Camera
make = \{ lookFrom, lookAt, up, fov, aspectRatio, aperture, focusDist } ->
theta = Math.degToRad fov
h = Num.tan (theta / 2)
viewportHeight = 2 * h
viewportWidth = aspectRatio * viewportHeight
w = Vec.sub lookFrom lookAt |> Vec.unit
u = Vec.cross up w |> Vec.unit
v = Vec.cross w u
origin = lookFrom
horizontal = Vec.scale u (viewportWidth * focusDist)
vertical = Vec.scale v (viewportHeight * focusDist)
lowerLeftCorner =
origin
|> Vec.sub (Vec.shrink horizontal 2)
|> Vec.sub (Vec.shrink vertical 2)
|> Vec.sub (Vec.scale w focusDist)
lensRadius = aperture / 2
{
origin,
lowerLeftCorner,
horizontal,
vertical,
u,
v,
w,
lensRadius,
}
ray : Camera, F64, F64, RNG, (RNG, Ray -> a) -> a
ray = \{ u, v, lowerLeftCorner, lensRadius, horizontal, vertical, origin }, s, t, rng, fn ->
newRng, unitDisk <- RNG.vecInUnitDisk rng
rd = Vec.scale unitDisk lensRadius
offset = Vec.add (Vec.scale u rd.x) (Vec.scale v rd.y)
direction =
lowerLeftCorner
|> Vec.add (Vec.scale horizontal s)
|> Vec.add (Vec.scale vertical t)
|> Vec.sub origin
|> Vec.sub offset
fn newRng { origin: Vec.add origin offset, direction }