From 438b1e9105aa0b34a5f41afacc6a5bfa29cbca73 Mon Sep 17 00:00:00 2001 From: Luxdragon Date: Mon, 12 Feb 2024 13:05:10 +0100 Subject: [PATCH] Implemented fast inverse square --- main.go | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/main.go b/main.go index 634b79b..0400c38 100644 --- a/main.go +++ b/main.go @@ -3,6 +3,7 @@ package main import "fmt" // for IO and standard library import "os" // for handling the progress bar import "math" // for maths +import "unsafe" // ================ VEC3 CLASS ===================== @@ -93,8 +94,16 @@ func Cross(v1 Vec3, v2 Vec3) Vec3 { v1.E[0]*v2.E[1] - v1.E[1]*v2.E[0]) } +func q_rsqrt(v Vec3) float32 { + var x float32 = v.E[0]*v.E[0] + v.E[1]*v.E[1] + v.E[2]*v.E[2] + i := *(*int32)(unsafe.Pointer(&x)) // evil floating point bit level hacking + i = 0x5f3759df - (i >> 1) // what the fuck? + y := *(*float32)(unsafe.Pointer(&i)) + return y +} + func Unit_vector(v Vec3) Vec3 { - new_v := v.Div(v.Length()) + new_v := v.Mult(q_rsqrt(v)) return new_v } @@ -141,8 +150,10 @@ func (r *Ray) At(t float32) Vec3 { } func Ray_color(r *Ray) Vec3 { - if (hit_sphere(NewPoint3(0,0,-1), 0.5, r)) { - return NewColor(1, 0, 0) + var t float32 = hit_sphere(NewPoint3(0,0,-1), 0.5, r) + if (t > 0.0) { + N := Unit_vector(r.At(t).Sub(NewVec3(0,0,-1))) + return NewColor(N.X()+1, N.Y()+1, N.Z()+1).Mult(0.5) } unit_direction := Unit_vector(r.Direction()) @@ -153,16 +164,16 @@ func Ray_color(r *Ray) Vec3 { // =============== SPHERE =================== -func hit_sphere(center Vec3, radius float32, r *Ray) bool { +func hit_sphere(center Vec3, radius float32, r *Ray) float32 { oc := r.Origin().Sub(center) a := Dot(r.Direction(), r.Direction()) b := Dot(oc, r.Direction()) * 2.0 c := Dot(oc, oc) - radius*radius discriminant := b*b - 4*a*c - if discriminant >= 0 { - return true + if (discriminant < 0) { + return -1.0 } else { - return false + return (-b-float32(math.Sqrt(float64(discriminant)))) / (2.0*a) } }