aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--camera.go30
-rw-r--r--interval.go18
-rw-r--r--rtiaw.go2
-rw-r--r--vec3.go8
4 files changed, 47 insertions, 11 deletions
diff --git a/camera.go b/camera.go
index e460cc0..569d385 100644
--- a/camera.go
+++ b/camera.go
@@ -12,15 +12,18 @@ type Camera struct {
PDU Vec3
PDV Vec3
Pixel00 Vec3
+ AntiAliasing uint
}
-func NewCamera(w uint, ar float64) (cam Camera) {
+func NewCamera(w uint, ar float64, aa uint) (cam Camera) {
cam.ImageWidth = w;
cam.ImageHeight = uint(float64(cam.ImageWidth) / ar);
if cam.ImageHeight < 1 {
cam.ImageHeight = 1;
}
+ cam.AntiAliasing = aa;
+
focal_length := 1.0;
viewport_height := 2.0;
viewport_width := viewport_height *
@@ -51,14 +54,27 @@ func (cam Camera) Render(world Hittable) {
"Scanlines remaining: %3d...",
(cam.ImageHeight - row));
for col := uint(0); col < cam.ImageWidth; col++ {
- pixel_centre := cam.Pixel00.
- Add(cam.PDU.Mul(Splat(float64(col)))).
- Add(cam.PDV.Mul(Splat(float64(row))));
- ray_direction := pixel_centre.Sub(cam.Centre);
- ray := Ray{cam.Centre, ray_direction}
- pixel_colour := ray.Colour(world);
+ pixel_colour := Splat(0);
+ for i := uint(0); i < cam.AntiAliasing; i++ {
+ r := cam.GetRay(row, col);
+ pixel_colour = pixel_colour.Add(r.Colour(world));
+ }
+ pixel_colour = pixel_colour.Div(Splat(float64(cam.AntiAliasing)));
fmt.Printf("%s ", pixel_colour.ToPPM());
}
fmt.Printf("\n");
}
}
+
+func (cam Camera) GetRay(row uint, col uint) Ray {
+ offset := unit_square();
+ pixel_sample := cam.Pixel00.
+ Add(cam.PDU.Mul(Splat(float64(col) + offset.X))).
+ Add(cam.PDV.Mul(Splat(float64(row) + offset.Y)));
+ return Ray{cam.Centre, pixel_sample.Sub(cam.Centre)};
+}
+
+func unit_square() Vec3 {
+ i := Interval{-0.5, 0.5};
+ return Vec3{i.Sample(), i.Sample(), 0};
+}
diff --git a/interval.go b/interval.go
index 5f44f51..763939a 100644
--- a/interval.go
+++ b/interval.go
@@ -1,5 +1,9 @@
package main
+import (
+ "math/rand"
+)
+
type Interval struct {
Min float64
Max float64
@@ -16,3 +20,17 @@ func (i Interval) Include(x float64) bool {
func (i Interval) Surround(x float64) bool {
return i.Min < x && x < i.Max;
}
+
+func (i Interval) Clamp(x float64) float64 {
+ if x < i.Min {
+ return i.Min;
+ }
+ if x > i.Max {
+ return i.Max;
+ }
+ return x;
+}
+
+func (i Interval) Sample() float64 {
+ return rand.Float64() * i.Size() + i.Min;
+}
diff --git a/rtiaw.go b/rtiaw.go
index 03cee09..ec5975e 100644
--- a/rtiaw.go
+++ b/rtiaw.go
@@ -13,7 +13,7 @@ func main() {
world.Add(Sphere{Vec3{0, 0 , -1}, 0.5});
world.Add(Sphere{Vec3{0, -100.5, -1}, 100 });
- cam := NewCamera(400, 16.0/9.0);
+ cam := NewCamera(400, 16.0/9.0, 100);
cam.Render(world);
dur := time.Since(start);
diff --git a/vec3.go b/vec3.go
index 65d14e5..4212b46 100644
--- a/vec3.go
+++ b/vec3.go
@@ -53,9 +53,11 @@ func (v Vec3) Cross(w Vec3) Vec3 {
}
func (v Vec3) ToPPM() string {
- r := uint8(255.999 * v.X);
- g := uint8(255.999 * v.Y);
- b := uint8(255.999 * v.Z);
+ i := Interval{0, 0.999};
+
+ r := uint8(256 * i.Clamp(v.X));
+ g := uint8(256 * i.Clamp(v.Y));
+ b := uint8(256 * i.Clamp(v.Z));
return fmt.Sprintf("%3d %3d %3d", r, g, b);
}