From c64284af4f5fd44360b88261a1c49a36f8bc7344 Mon Sep 17 00:00:00 2001 From: Nat Lasseter Date: Mon, 24 Jun 2024 23:23:45 +0100 Subject: Chapter 12 --- camera.go | 26 ++++++++++++++++++-------- rtiaw.go | 5 ++++- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/camera.go b/camera.go index f33d98a..66981aa 100644 --- a/camera.go +++ b/camera.go @@ -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. diff --git a/rtiaw.go b/rtiaw.go index 1427fbf..25dd971 100644 --- a/rtiaw.go +++ b/rtiaw.go @@ -22,7 +22,10 @@ func main() { world.Add(Sphere{Vec3{-1.0, 0 , -1 }, 0.4, mat_bubble}); world.Add(Sphere{Vec3{ 1.0, 0 , -1 }, 0.5, mat_right}); - cam := NewCamera(400, 16.0/9.0, 100, 50); + cam := NewCamera(400, 16.0/9.0, + 100, 50, + 20, Vec3{-2, 2, 1}, + Vec3{0, 0, -1}, Vec3{0, 1, 0}); cam.Render(world); dur := time.Since(start); -- cgit v1.2.1