From 6fb46021feaea0716e0a9cfb1a11fce7a5f7bfab Mon Sep 17 00:00:00 2001 From: Carlos Sanchez Date: Mon, 5 Aug 2024 04:22:15 -0400 Subject: [PATCH] REALLY don't know why w works but others don't... --- renderer4/hrend/image.go | 2 +- renderer4/hrend/math.go | 42 +++++++++++++++++++-------------------- renderer4/hrend/obj.go | 1 + renderer4/hrend/render.go | 38 ++++++++++++++++++++++++----------- renderer4/main.go | 4 ++-- 5 files changed, 51 insertions(+), 36 deletions(-) diff --git a/renderer4/hrend/image.go b/renderer4/hrend/image.go index 2a63508..2f1751d 100644 --- a/renderer4/hrend/image.go +++ b/renderer4/hrend/image.go @@ -136,7 +136,7 @@ func NewTexture(texture image.Image, stride int) *SimpleFramebuffer { // Fill zbuffer with pixels that are max distance away func (fb *RenderBuffer) ResetZBuffer() { for i := range fb.ZBuffer { - fb.ZBuffer[i] = 65535 //math.MaxFloat32 + fb.ZBuffer[i] = 0 //65535 //math.MaxFloat32 } } diff --git a/renderer4/hrend/math.go b/renderer4/hrend/math.go index 0e4a7c9..5a60308 100644 --- a/renderer4/hrend/math.go +++ b/renderer4/hrend/math.go @@ -110,30 +110,30 @@ func (m *Mat44f) SetProjection(fov float32, aspect float32, near float32, far fl // OK apparently I suck, let's use somebody else's projection matrix: m.ZeroFill() - // fov = fov / 180 * math.Pi // Convert to radians - // e := float32(1 / math.Tan(float64(fov/2))) + fov = fov / 180 * math.Pi // Convert to radians + e := float32(1 / math.Tan(float64(fov/2))) - // m.Set(0, 0, e/aspect) - // m.Set(1, 1, e) - // m.Set(2, 2, (far+near)/(near-far)) - // m.Set(2, 3, 2*far*near/(near-far)) - // m.Set(3, 2, -1) // Might need to be swapped + m.Set(0, 0, e/aspect) + m.Set(1, 1, e) + m.Set(2, 2, (far+near)/(near-far)) + m.Set(2, 3, 2*far*near/(near-far)) + m.Set(3, 2, -1) // Might need to be swapped - DEG2RAD := math.Acos(-1.0) / 180.0 - tangent := math.Tan(float64(fov/2.0) * DEG2RAD) // tangent of half fovY - top := near * float32(tangent) // half height of near plane - right := top * aspect // half width of near plane - // Column major maybe??? - // n/r 0 0 0 - // 0 n/t 0 0 - // 0 0 -(f+n)/(f-n) -1 - // 0 0 -(2fn)/(f-n) 0 + // DEG2RAD := math.Acos(-1.0) / 180.0 + // tangent := math.Tan(float64(fov/2.0) * DEG2RAD) // tangent of half fovY + // top := near * float32(tangent) // half height of near plane + // right := top * aspect // half width of near plane + // // Column major maybe??? + // // n/r 0 0 0 + // // 0 n/t 0 0 + // // 0 0 -(f+n)/(f-n) -1 + // // 0 0 -(2fn)/(f-n) 0 - m.Set(0, 0, near/right) - m.Set(1, 1, near/top) - m.Set(2, 2, -(far+near)/(far-near)) - m.Set(3, 2, -1) - m.Set(2, 3, -(2*far*near)/(far-near)) + // m.Set(0, 0, near/right) + // m.Set(1, 1, near/top) + // m.Set(2, 2, -(far+near)/(far-near)) + // m.Set(3, 2, -1) + // m.Set(2, 3, -(2*far*near)/(far-near)) } func (m *Mat44f) SetViewport(tl Vec3f, br Vec3f) { //width, height, depth int) { diff --git a/renderer4/hrend/obj.go b/renderer4/hrend/obj.go index 1467973..ffdc6ce 100644 --- a/renderer4/hrend/obj.go +++ b/renderer4/hrend/obj.go @@ -24,6 +24,7 @@ type Facei [3]struct { type Facef [3]struct { Pos Vec3f + W float32 Tex Vec3f } diff --git a/renderer4/hrend/render.go b/renderer4/hrend/render.go index 005244e..30905c0 100644 --- a/renderer4/hrend/render.go +++ b/renderer4/hrend/render.go @@ -172,6 +172,23 @@ func TriangleTextured(fb *RenderBuffer, texture Framebuffer, intensity float32, w0_xi, w0_yi := EdgeIncrementi(v1, v2) w1_xi, w1_yi := EdgeIncrementi(v2, v0) w2_xi, w2_yi := EdgeIncrementi(v0, v1) + // I don't know what happened to my z but it's nearly unusable. + // I simply use w instead... don't know if that's ok + tiz0 := 1 / v0v.W + tiz1 := 1 / v1v.W + tiz2 := 1 / v2v.W + // tiz0 := v0v.Pos.Z + // tiz1 := v1v.Pos.Z + // tiz2 := v2v.Pos.Z + // tiz0 := 1 / v0v.Pos.Z + // tiz1 := 1 / v1v.Pos.Z + // tiz2 := 1 / v2v.Pos.Z + tiu0 := v0v.Tex.X * tiz0 //v0v.W //* tiz0 + tiu1 := v1v.Tex.X * tiz1 //v1v.W //* tiz1 + tiu2 := v2v.Tex.X * tiz2 //v2v.W //* tiz2 + tiv0 := v0v.Tex.Y * tiz0 //v0v.W //* tiz0 + tiv1 := v1v.Tex.Y * tiz1 //v1v.W //* tiz1 + tiv2 := v2v.Tex.Y * tiz2 //v2v.W //* tiz2 for y := uint(boundsTL.Y); y <= uint(boundsBR.Y); y++ { w0 := w0_y @@ -183,12 +200,16 @@ func TriangleTextured(fb *RenderBuffer, texture Framebuffer, intensity float32, w0a := float32(w0) * invarea w1a := float32(w1) * invarea w2a := float32(w2) * invarea - pz := w0a*v0v.Pos.Z + w1a*v1v.Pos.Z + w2a*v2v.Pos.Z - if pz < fb.ZBuffer[x+y*fb.Width] { + //pz := w0a*v0v.Pos.Z + w1a*v1v.Pos.Z + w2a*v2v.Pos.Z + pz := w0a*tiz0 + w1a*tiz1 + w2a*tiz2 + if pz > fb.ZBuffer[x+y*fb.Width] { fb.ZBuffer[x+y*fb.Width] = pz + //pw := w0a/tiz0 + w1a/tiz1 + w2a/tiz2 + //pw := w0a/v0v.W + w1a/v1v.W + w2a/v2v.W + pz = 1 / pz r, g, b := 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), + (w0a*tiu0+w1a*tiu1+w2a*tiu2)*pz, + (w0a*tiv0+w1a*tiv1+w2a*tiv2)*pz, ) fb.Data.Set(x, y, byte(float32(r)*intensity), byte(float32(g)*intensity), byte(float32(b)*intensity)) } @@ -220,6 +241,7 @@ func conditionalAddTriangle(sc []HVec3f, tx []Vec3f, out []Facef) []Facef { for i := range 3 { f[i].Pos = sc[i].MakeConventional() f[i].Tex = tx[i] + f[i].W = sc[i].W } // Backface culling: no need to do anything with triangles facing the wrong way if EdgeFunction(f[0].Pos, f[1].Pos, f[2].Pos) <= 0 { @@ -296,21 +318,13 @@ func ClipFace(face Facei, vecs []HVec3f, texs []Vec3f) []Facef { // the original B point that we used, since that's part of the other // triangle. But simply replacing it will make the triangle invisible, // since it inverts the winding order (I think) - //hfa.LerpSelf(hf[ci], tac) hf[bi] = hfa hf[bi].LerpSelf(&hf[ci], tac) tx[bi] = LerpVec3f(txa, tx[ci], tac) - //sct[bi].Pos = LerpVec3f(sc[ai].Pos, sc[ci].Pos, tac) - //sct[bi].Tex = LerpVec3f(sc[ai].Tex, sc[ci].Tex, tac) - //w[bi] = LerpF32(wa, w[ci], tac) - // Now swap the a and b (or we could swap c and b) hf[ai], hf[bi] = hf[bi], hf[ai] tx[ai], tx[bi] = tx[bi], tx[ai] - //w[ai], w[bi] = w[bi], w[ai] - //sct[ai], sct[bi] = sct[bi], sct[ai] - //outfaces = conditionalAddTriangle(sct, w, outfaces) outfaces = conditionalAddTriangle(hf[:], tx[:], outfaces) } else if len(outers) != 3 { // Output the face itself, no modification diff --git a/renderer4/main.go b/renderer4/main.go index ef58d85..4b69221 100644 --- a/renderer4/main.go +++ b/renderer4/main.go @@ -19,8 +19,8 @@ import ( ) const ( - NearClip = 0.0001 - FarClip = 10 + NearClip = 0.01 + FarClip = 100 Movement = 1.0 Rotation = 0.25 LookLock = math.Pi / 32