diff options
Diffstat (limited to 'camera.go')
-rw-r--r-- | camera.go | 26 |
1 files changed, 18 insertions, 8 deletions
@@ -2,6 +2,7 @@ package main import ( "fmt" + maths "math" "os" ) @@ -16,8 +17,11 @@ type Camera struct { MaxDepth uint } -func NewCamera(w uint, ar float64, aa uint, md uint) (cam Camera) { - cam.ImageWidth = w; +func NewCamera(wi uint, ar float64, + aa uint, md uint, + vfov float64, lookfrom Vec3, + lookat Vec3, vup Vec3) (cam Camera) { + cam.ImageWidth = wi; cam.ImageHeight = uint(float64(cam.ImageWidth) / ar); if cam.ImageHeight < 1 { cam.ImageHeight = 1; @@ -25,22 +29,28 @@ func NewCamera(w uint, ar float64, aa uint, md uint) (cam Camera) { cam.AntiAliasing = aa; cam.MaxDepth = md; + cam.Centre = lookfrom; - focal_length := 1.0; - viewport_height := 2.0; + focal_length := lookfrom.Sub(lookat).Mag(); + theta := vfov * maths.Pi / 180; + h := maths.Tan(theta / 2) + viewport_height := 2.0 * h * focal_length; viewport_width := viewport_height * float64(cam.ImageWidth) / float64(cam.ImageHeight); - cam.Centre = SplatVec3(0); - viewport_u := Vec3{viewport_width, 0, 0}; - viewport_v := Vec3{0, -viewport_height, 0}; + w := lookfrom.Sub(lookat).Unit(); + u := vup.Cross(w).Unit(); + v := w.Cross(u); + + viewport_u := SplatVec3(viewport_width).Mul(u); + viewport_v := SplatVec3(viewport_height).Mul(v.Neg()); cam.PDU = viewport_u.Div(SplatVec3(float64(cam.ImageWidth))); cam.PDV = viewport_v.Div(SplatVec3(float64(cam.ImageHeight))); viewport_upperleft := cam.Centre. - Sub(Vec3{0, 0, focal_length}). + Sub(SplatVec3(focal_length).Mul(w)). Sub(viewport_u.Div(SplatVec3(2))). Sub(viewport_v.Div(SplatVec3(2))); cam.Pixel00 = viewport_upperleft. |