aboutsummaryrefslogtreecommitdiff
path: root/camera.go
diff options
context:
space:
mode:
Diffstat (limited to 'camera.go')
-rw-r--r--camera.go26
1 files changed, 18 insertions, 8 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.