Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I write simple software renderer. In my pipeline i have stage of backface culling. But looks like it has some error (see picture).

I perform culling right after world transformation (is it correct?).

(i can't insert picture in post coz i don't have enough points, so i just upload it (cube model): http://imageshack.us/photo/my-images/705/bcerror.png/)

Vector3F view_dir(0.0f, 0.0f, 1.0f);

std::vector<Triangle> to_remove;

for (Triangle &t : m_triangles)
{
    Vector4F e1 = t.v2 - t.v1;
    Vector4F e2 = t.v3 - t.v1;
    Vector3F normal(
        e1.y * e2.z - e1.z * e2.y,
        e1.z * e2.x - e1.x * e2.z,
        e1.x * e2.y - e1.y * e2.x
        );
    normal.Normalize();

    float dot = Dot(view_dir, normal);
    if (dot <= 0)
        to_remove.push_back(t);
}

for (Triangle& t : to_remove)
    m_triangles.erase(std::remove(m_triangles.begin(), m_triangles.end(), t), m_triangles.end());

Camera sits in origin and points in screen (RH).

What is the reason?

For better explanation i upload picture with cube rotation screenshots: http://imageshack.us/photo/my-images/842/bcmove.png/

UPDATED: The error occurs only when triangle has non-zero offset from origin

UPDATED 2: If i process backface culling in clip space (after transforming all vertices with view and projection matrix), and just check z coordinate of triangle normal - it works perfect... Can i perform culing RIGHT BEFORE view/proj transforms? In this case looks like culling will not depends of projection and it's not right?..

share|improve this question
    
It could be winding order. Are you sure you wound all your triangles CCW (or CW, whatever your convention is?) –  bobobobo Dec 2 '12 at 10:36
    
yes, i tested it with render just single triangle (from this cube side) - they ccw –  acrilige Dec 2 '12 at 12:49
    
Also i updated post - upload pictures of cube in movement - to make problem clear –  acrilige Dec 2 '12 at 12:54

1 Answer 1

up vote 0 down vote accepted

I had the following error: The direction of the view was always taken constant, whereas it should be taken as the difference between the position of the camera and one of the points of the polygon (or its center). Otherwise it will not be perspective-correct. I don't get this error with zero offset from origin because in this case view direction correctly was (0, 0, 1).

So working code looks like this:

// Calculate view position from view matrix
Vector4F view_pos = m_view_transform * Vector4F(0.0f, 0.0f, 0.0f, 1.0f);
std::vector<Triangle> to_remove;

for (Triangle &t : m_triangles)
{
    Vector4F e1 = t.v2 - t.v1;
    Vector4F e2 = t.v3 - t.v1;
    Vector4F normal(
        e1.y * e2.z - e1.z * e2.y,
        e1.z * e2.x - e1.x * e2.z,
        e1.x * e2.y - e1.y * e2.x,
        0.0f);

    // Calculate actual direction
    Vector4F view_dir = t.v1 - view_pos;
    view_dir.Normalize();

    float dot = Dot(view_dir, normal);
    if (dot <= 0)
        to_remove.push_back(t);
}

for (Triangle& t : to_remove)
    m_triangles.erase(std::remove(m_triangles.begin(), m_triangles.end(), t), m_triangles.end());

Also, looks like there's no reason to do backface culling in world space - it can be done in object space and it can help to increase perfomance. More about front-end backface culling can be read at this page: http://www.gamasutra.com/view/feature/131773/a_compact_method_for_backface_.php?print=1

Hope this will help someone in future :)

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.