It's free to join Gamasutra!|Have a question? Want to know who runs this site? Here you go.|Targeting the game development market with your product or service? Get info on advertising here.||For altering your contact information or changing email subscription preferences.
Registered members can log in here.Back to the home page.

Search articles, jobs, buyers guide, and more.

By Osnat Levi, Ronen Zohar,
Haim Barad,
Alex Klimovitski

Gamasutra
August 6, 1999

Letters to the Editor:
Write a letter
View all letters


Features

 

Contents

Introduction

Accurate front-end culling using facet normals

Compact culling

Performance results

Appendix

C++ implementation Methods

The compact backface culling routine

The compact SIMD backface culling routine

Accurate front-end culling using facet normals

This technique performs a per-polygon test using the camera position and the polygon's facet normal and position to determine whether it is front or back facing. Its main advantages are its accuracy — the method culls the maximum number of polygons — and the fact that its calculations are done in object space, which eliminates vertices in the pretransform phase.

The classic implementation of this technique requires us to precalculate and store the following information about the polygon:

• The normal of the polygon (facet normal) stored in object space. (Some tools will export the normal, but otherwise it must be calculated using the polygon's vertices.)

• A position on the plane of the polygon in object space — either one of the vertices or the polygon's center.

• A list holding the indices of the polygon's vertices (indices list)

To determine whether a polygon is front or back facing, we must first transform the viewer position (or camera position) to object space, calculate the viewing vector (the vector in which the viewer is "looking" at the polygon), and then calculate the dot product between the viewing vector and the polygon normal. If the result is positive, then the polygon is facing backwards.

Here's an example of the traditional implementation for indexed triangles. The structure we're assuming for each face is 32 bytes in size, and is as follows:

struct {

float x,y,z;

} Vector;

struct {

Vector position;
// position on polygon
// 12 bytes

Vector normal;
// normal of polygon
// 12 bytes

WORD p1, p2, p3;
// indices to vertex pool
// 6 bytes

WORD stub; // needed to avoid 2 byte alignment
// stalls and filling a cache line.

} faceData; //= total size 32 bytes

Here's pseudo-code for the culling (please refer to the appendix for a C++ implementation):

for ( each vertex in pool )
{

mark vertex "not visible"

}

Transform Vw (viewer in world space) to Vo (viewer in object space) using the world-to-object transformation matrix.

for ( each face in array )
{

Calculate vector T = face->position – Vo

T is the viewing vector in object space.

Calculate the dot product between T and the face normal.

(T * face->normal) is the cosine between the face normal and the viewing vector.

If the result <=0 then the polygon is front facing.

if ( dot product <= 0)
// polygon is front facing
{

face->p1, face->p2 and face->p3 are indices to the vertex pool.

Use them to mark the appropriate vertices "visible"

}

}


Compact culling


join | contact us | advertise | write | my profile
news | features | companies | jobs | resumes | education | product guide | projects | store



Copyright © 2003 CMP Media LLC

privacy policy
| terms of service