From 18616b3578cdd73872e4830bb851d3030baffa94 Mon Sep 17 00:00:00 2001 From: Carlos Sanchez Date: Mon, 29 Jul 2024 23:09:23 -0400 Subject: [PATCH] Seems fast enough? --- tinyrender5/image.go | 11 +++++------ tinyrender5/main.go | 10 ++++------ tinyrender5/obj.go | 1 + tinyrender5/render.go | 10 ++-------- tinyrender5/run.sh | 2 +- 5 files changed, 13 insertions(+), 21 deletions(-) diff --git a/tinyrender5/image.go b/tinyrender5/image.go index 8b36935..17432cc 100644 --- a/tinyrender5/image.go +++ b/tinyrender5/image.go @@ -6,7 +6,7 @@ import ( "image" "image/color" "log" - //"math" + "math" "strings" ) @@ -29,7 +29,7 @@ func Uint2Col(col uint) (byte, byte, byte) { // Color is in ARGB (alpha not used right now) type Framebuffer struct { Data []uint - ZBuffer []uint16 //[]float32 //uint16 // Apparently 16 bit z-buffers are used + ZBuffer []float32 //uint16 // Apparently 16 bit z-buffers are used Width uint Height uint } @@ -38,7 +38,7 @@ type Framebuffer struct { func NewFramebuffer(width uint, height uint) Framebuffer { return Framebuffer{ Data: make([]uint, width*height), - ZBuffer: make([]uint16, width*height), + ZBuffer: make([]float32, width*height), Width: width, Height: height, } @@ -70,7 +70,6 @@ func (fb *Framebuffer) ResetZBuffer() { } func (fb *Framebuffer) GetUv(u float32, v float32) uint { - // log.Print(u, v) x := uint(float32(fb.Width) * u) y := uint(float32(fb.Height) * (1 - v)) return fb.Data[x+y*fb.Width] @@ -116,7 +115,7 @@ func (fb *Framebuffer) ExportPPMP6() []byte { return result.Bytes() } -/*func (fb *Framebuffer) ZBuffer_ExportPPM() string { +func (fb *Framebuffer) ZBuffer_ExportPPM() string { var result strings.Builder mini := float32(math.MaxFloat32) maxi := float32(-math.MaxFloat32) @@ -140,4 +139,4 @@ func (fb *Framebuffer) ExportPPMP6() []byte { result.WriteRune('\n') } return result.String() -}*/ +} diff --git a/tinyrender5/main.go b/tinyrender5/main.go index cb9c8a9..632906b 100644 --- a/tinyrender5/main.go +++ b/tinyrender5/main.go @@ -79,12 +79,15 @@ func main() { var projection Mat44f var worldToCamera Mat44f var viewport Mat44f + projection.SetProjection(float32(*fov), NearClip, FarClip) worldToCamera.SetTranslation(float32(*xofs), 0, float32(*zofs)) - viewport.SetViewportSimple(int(fb.Width), int(fb.Height), 65535) + viewport.SetViewportSimple(int(fb.Width), int(fb.Height), 1) //65535) // Premultiply all the translation/etc matrices. Why do we do world to camera THEN // projection? I guess that makes sense actually, oops... projection is the last step. + // Since we're doing row major, we multiply going from the raw coords "up to" the + // screen screenmat := worldToCamera.Multiply(&projection) screenmat = screenmat.Multiply(&viewport) // light = worldToCamera.MultiplyPoint3(light) @@ -99,20 +102,15 @@ func main() { // is not considered: is this orthographic projection? Yeah probably... var fpt [3]Vec3f for i := range 3 { // Triangles, bro - //fp := screenmat.MultiplyPoint3(f[i].Pos) sc[i] = f[i] sc[i].Pos = screenmat.MultiplyPoint3(f[i].Pos) fpt[i] = worldToCamera.MultiplyPoint3(f[i].Pos) - // sc[i].Pos.X = (fp.X + 1) * halfwidth - // sc[i].Pos.Y = hi - (fp.Y+1)*halfheight - // sc[i].Pos.Z = fp.Z } l1 := fpt[2].Sub(fpt[0]) n := l1.CrossProduct(fpt[1].Sub(fpt[0])) n = n.Normalize() intensity := n.MultSimp(&light) - // intensity := float32(1) if intensity > 0 { Triangle3t(&fb, &texture, intensity, sc[0], sc[1], sc[2]) } diff --git a/tinyrender5/obj.go b/tinyrender5/obj.go index cf08ff6..08070c2 100644 --- a/tinyrender5/obj.go +++ b/tinyrender5/obj.go @@ -256,5 +256,6 @@ func ParseObj(reader io.Reader) (*ObjModel, error) { result.Faces = append(result.Faces, face) } } + log.Printf("Obj had %d vertices, %d faces", len(result.Vertices), len(result.Faces)) return &result, nil } diff --git a/tinyrender5/render.go b/tinyrender5/render.go index 62c0a54..61d8157 100644 --- a/tinyrender5/render.go +++ b/tinyrender5/render.go @@ -80,7 +80,7 @@ func Triangle3(fb *Framebuffer, color uint, v0f Vec3f, v1f Vec3f, v2f Vec3f) { w0a := float32(w0) * invarea w1a := float32(w1) * invarea w2a := float32(w2) * invarea - pz := uint16(w0a*v0f.Z + w1a*v1f.Z + w2a*v2f.Z) + pz := w0a*v0f.Z + w1a*v1f.Z + w2a*v2f.Z if pz < fb.ZBuffer[x+y*fb.Width] { //log.Print(pz) fb.ZBuffer[x+y*fb.Width] = pz @@ -124,11 +124,6 @@ func Triangle3t(fb *Framebuffer, texture *Framebuffer, intensity float32, v0v Ve } // Where to start our scanning pstart := Vec2i{boundsTL.X, boundsTL.Y} - // if parea < 0 { - // v1, v2 = v2, v1 - // v1f, v2f = v2f, v1f - // parea = EdgeFunctioni(v0, v1, v2) - // } invarea := 1 / float32(parea) w0_y := EdgeFunctioni(v1, v2, pstart) w1_y := EdgeFunctioni(v2, v0, pstart) @@ -146,10 +141,9 @@ func Triangle3t(fb *Framebuffer, texture *Framebuffer, intensity float32, v0v Ve w0a := float32(w0) * invarea w1a := float32(w1) * invarea w2a := float32(w2) * invarea - pz := uint16(w0a*v0v.Pos.Z + w1a*v1v.Pos.Z + w2a*v2v.Pos.Z) + pz := w0a*v0v.Pos.Z + w1a*v1v.Pos.Z + w2a*v2v.Pos.Z if pz < fb.ZBuffer[x+y*fb.Width] { fb.ZBuffer[x+y*fb.Width] = pz - // if math.IsNaN(v0v.Tex.X) || math.IsNaN(v1v.Tex.X) || math.IsNaN col := texture.GetUv( (w0a*v0v.Tex.X + w1a*v1v.Tex.X + w2a*v2v.Tex.X), (w0a*v0v.Tex.Y + w1a*v1v.Tex.Y + w2a*v2v.Tex.Y), diff --git a/tinyrender5/run.sh b/tinyrender5/run.sh index 99f5ade..c8b6997 100755 --- a/tinyrender5/run.sh +++ b/tinyrender5/run.sh @@ -10,5 +10,5 @@ fi echo "Building" go build -o render echo "Running" -./render "-cpuprofile=$1.prof" "-p6file=$1.ppm" "-repeat=500" +./render "-cpuprofile=$1.prof" "-p6file=$1.ppm" "-repeat=60" "-zofs=-0.75" # ./render "-zbuffer" >"$1_zbuffer.ppm"