Pure Rb Code 3D – Spinning Cube – Backface Removal

In this project we are going to add the ability to remove backfaces. A back face is a triangle that makes up your 3D object that is facing away from the camera. We’re still in the wire frame stage of our engine, so the models we are drawing can be seen as if they’re see-through. Most of the time this is not what you want, mostly you want a basically opaque model. In addition, when we get to adding textures to our models, we are going to be pushing a lot of math to the screen because of interpolation. The steps that we are exploring at the moment will get more and more complicated (mathematically) and we will be adding a few additional steps as well. So what you say?

One of the challenges in any 3D engine, including hardware accelerated API’s like OpenGL, is to send as few vertex points and its associated properties to the renderer. For example, if a model is behind the camera, you certainly don’t want to spend CPU time transforming its data. You want to identify, as early as you can in your pipeline, which objects will not be included in your scene. Backface removal is a part of this goal of eliminating the data we process in the pipeline. Like an object that is off screen, the polygon faces, in our case triangles, that make up our model that are occluded or not seen can be eliminated from the rendering list that gets sent to the renderer. Less data means a snappier 2D model generation on screen.

To our TCObject4D class we add our removal method,

Sub RemoveBackfaces(obj As TCObject4D, cam As TCCam4D)

// test if the object is culled
if Bitwise.BitAnd(obj.state, STATE_CULLED) = STATE_CULLED Then
Return
End

// process each poly in mesh
Dim index As Integer
Dim vIndex0, vIndex1, vIndex2 As Integer

Dim u, v, n As TCVector4D
Dim currPoly As TCPolyFace4D
u = New TCVector4D
v = New TCVector4D
n = New TCVector4D
Dim view As New TCVector4D
Dim dp As Double
Dim bitParts(-1) As Integer

For index = 0 to obj.NumPolys - 1
// acquire polygon
currPoly = obj.mPolyList(index)
// is this polygon valid?
// test this polygon if and only if it's not clipped, not culled,
// active, and visible and not 2 sided. Note we test for backface in the event that
// a previous call might have already determined this, so why work
// harder!
If (Bitwise.BitAnd(currPoly.State, STATE_ACTIVE) <>STATE_ACTIVE) Or (Bitwise.BitAnd(currPoly.State, STATE_CLIPPED) = STATE_CLIPPED) Or (Bitwise.BitAnd(currPoly.Attribute, TCPolyFace4D.ATTR_2SIDED) = TCPolyFace4D.ATTR_2SIDED) Or (Bitwise.BitAnd(currPoly.State, STATE_BACKFACE) = STATE_BACKFACE) Then
Continue
End
// move onto next poly
vIndex0 = currPoly.VertexList(0).mVertSequence(0)
vIndex1 = currPoly.VertexList(1).mVertSequence(1)
vIndex2 = currPoly.VertexList(2).mVertSequence(2)
// we will use the transformed polygon vertex list since the backface removal
// only makes sense at the world coord stage of the pipeline
// we need to compute the normal of this polygon face, and recall
// that the vertices are in clockwise order, u = p0->p1, v=p0->p2, n=uxv
// build u, v
TCVector4D.Build obj.mVertexListTranslated(vIndex0).Vertex, obj.mVertexListTranslated(vIndex1).Vertex, u
TCVector4D.Build obj.mVertexListTranslated(vIndex0).Vertex, obj.mVertexListTranslated(vIndex2).Vertex, v

// compute cross product
TCVector4D.Cross u, v, n
// now create eye vector to viewpoint
TCVector4D.Build obj.mVertexListTranslated(vIndex0).Vertex, cam.Position(), view
// and finally, compute the dot product
dp = TCVector4D.Dot(n, view)

// if the sign is > 0 then visible, 0 = scathing, < 0 invisible
if dp <= 0 then
currPoly.State = SetBit(currPoly.state, STATE_BACKFACE)
End
Next

The heart of the routine is an algorithm that builds a normal to each triangle in the object. If the normal points away from our camera (the eye point), then it is facing away and it is tagged as being a back facing polygon and hence won’t be drawn. Our rendering routine has a check to see the triangle is back facing or not.

Here’s a really nice web site to brush up and study your math,
Linear Math Site

And another,
Math Site

I’ve added three shared methods to the TCVector4D class to support this routine, TCVector4D.Build, TCVector4D.Cross and TCVector4D.Dot.

Backface removal code is a part of our TCObject4D class and will be done in World Space and will be called in our drawing routine after our ModelTo World call like this,

mController3D.Object4D.RemoveBackfaces objCube, mController3D.Camera

A nice improvement, don’t you think? :)

Download Project Here ….

About bigdaddytom

Hobbyist programmer, self taught, started with Rb in 1999. Xcode, Objective-C iPhone coder too. I have been blessed being able to live in Hawaii for over three decades. Proud father of two. Business owner. The above image is from atop Mauna Kea looking towards Mauna Loa on the big Island of Hawaii.
This entry was posted in Code. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>