0
\$\begingroup\$

I´m struggling with a weird problem since hours. Ive implemented frustum culling with the help of online articles and a book. The problem is that the objects are not culled correctly. I´m using Spheres, they are scaled correctly - I just dont know what´s wrong!

Ill just show you some code:

First my frustum is just an array of six planes, and a plane is just a Vector4 with x,y,z and w!

Check if sphere is inside frustum. Maybe the problem lies here:

bool Frustum::checkSphere(const PrimitiveSphere& sphere, const WorldPoint& were) const noexcept {

    const auto pos = were.position + sphere.center;
    for (const auto& plane : planes) {

        const float radius = sphere.radius * were.scale.unitMagnitude(); //unit magnitude is just x + y + z / 3
        const float dist = 
            plane.x * pos.x +
            plane.y * pos.y +
            plane.z * pos.z + plane.w;
        if (dist < -radius)
            return false;   
    }
    return true;
}

Build my frustum each frame from ViewProjectionMatrix

void Frustum::fromViewProj(const float* const vp) noexcept {

    const float xw = vp[3];
    const float yw = vp[7];
    const float zw = vp[11];
    const float ww = vp[15];

    const float xz = vp[2];
    const float yz = vp[6];
    const float zz = vp[10];
    const float wz = vp[14];

    PrimitivePlane& near = planes[0];
    PrimitivePlane& far = planes[1];
    PrimitivePlane& left = planes[2];
    PrimitivePlane& right = planes[3];
    PrimitivePlane& top = planes[4];
    PrimitivePlane& bottom = planes[5];

    near.x = xw - xz;
    near.y = yw - yz;
    near.z = zw - zz;
    near.w = ww - wz;

    far.x = xw + xz;
    far.y = yw + yz;
    far.z = zw + zz;
    far.w = ww + wz;

    const float xx = vp[0];
    const float yx = vp[4];
    const float zx = vp[8];
    const float wx = vp[12];

    left.x = xw - xx;
    left.y = yw - yx;
    left.z = zw - zx;
    left.w = ww - wx;

    right.x = xw + xx;
    right.y = yw + yx;
    right.z = zw + zx;
    right.w = ww + wx;

    const float xy = vp[1];
    const float yy = vp[5];
    const float zy = vp[9];
    const float wy = vp[13];

    top.x = xw + xy;
    top.y = yw + yy;
    top.z = zw + zy;
    top.w = ww + wy;

    bottom.x = xw - xy;
    bottom.y = yw - yy;
    bottom.z = zw - zy;
    bottom.w = ww - wy;

    for (auto& plane : planes)
        plane.normalize();
}

Now the problem is, the draw calls are the same if all the orbs are in my frustum or only 5. But when I rotate my camera slowly a bit the drawcalls are decreasing a bit. WTF? Just look for yourself (the red rect marks the drawcalls): enter image description here

enter image description here

enter image description here

Does anybody have an idea what it could be? Or is my code okay and the problem is somewere else? :/

\$\endgroup\$
-1
\$\begingroup\$

You seem to have implemented a basic frustum culling. But unfortunately, frustum culling is an inaccurate method for large objects in view frustum. Its only culling objects completely outside the bounds and including everything which is either intersecting or inside. This introduces some false positives i.e. objects that are not in your practical view but are intersecting the frustum (intersecting with near and far plane) regardless. Prune these scenarios based on your practical viewing range to fix the problem.

You can find some really good illustration and the solution about it in the following posts- https://cesium.com/blog/2017/02/02/tighter-frustum-culling-and-why-you-may-want-to-disregard-it by Austin Eng at Cesium and http://www.iquilezles.org/www/articles/frustumcorrect/frustumcorrect.htm by Inigo Quilez.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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