D3D11 Frustum Culling issue

Started by
7 comments, last by SyncViews 9 years, 7 months ago

This seems to be occasionally culling things that are visible on screen when rendering with all world coordinates within the AABB and the same view and projection matrix... The code is pretty straight forward, so not sure what the issue is?


XMMATRIX xmproj = XMMatrixPerspectiveFovLH(fov, aspectRatio, 0.1f, 1000.0f);

XMMATRIX xmview;
xmview = XMMatrixTranslation(-x, -y, -z);
xmview *= XMMatrixRotationY(-yaw);
xmview *= XMMatrixRotationX(-pitch);
...
class Frustum
{
public:
    void update(XMMATRIX projection, XMMATRIX view)
    {
        frustum.CreateFromMatrix(frustum, projection);
        frustum.Transform(frustum, view);
    }
    bool contains(const AxisAlignedBoundaryBox3F &aabb)const
    {
        //AxisAlignedBoundaryBox3 is (min,max) but DirectX::BoundingBox is (centre,extents)!
        Vector3F p1 = aabb.p1;
        Vector3F p2 = aabb.p2;
        
        Vector3F size = p2 - p1;
        Vector3F centre = p1 + size / 2.f;
        
        XMFLOAT3 xsize(size.x, size.y, size.z);
        XMFLOAT3 xcentre(centre.x, centre.y, centre.z);
        bool ret = frustum.Contains(BoundingBox(xcentre, xsize)) != DISJOINT;
        assert(ret || frustum.Intersects(BoundingBox(xcentre, xsize)) == DISJOINT);
        return ret;
    }
private:
    BoundingFrustum frustum;
};
Advertisement

Since BoundingFrustum is 6 planes, I am not sure why you are creating it and then transforming it.

In Frustum::update(), pass the view-projection matrix and only call frustum.CreateFromMatrix().

You might want to look into naming conventions. It took me a while to realize that “frustum” was a member of “Frustum”. A little “m_” (or whatever) prefix would go a long way in improving the readability of the code.

L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

Well the docs just describe the create from matrix as taking "projection", and the other way does not work either.


XMMATRIX xmviewProj = xmview * xmproj;
...
frustum.CreateFromMatrix(frustum, xmviewProj);

This makes nearly everything vanish as soon as yaw is outside what appears to be a range of -1.0 < yaw < 1.0.

Apparently XNA is weird.
Are these the actual view/projection matrices you use in the shaders (never combine matrices in a shader unless necessary—always pass pre-concatenated matrices such as world-view-projection and perform 1 multiple in the shader unless there is a specific need otherwise).


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

Yes, "xmview * xmproj" is the matrix I am using to test this with a single mul in the vertex shader (all my verticies etc. are already in world space for this). The only special thing is that it seems DirectX Math and D3D11 made a different choice on row and column major, so the shader matrix gets transposed. I guess I can try also transposing the BoundingFrustum when I get home, allthough the docs say nothing about needing to do that.


allthough the docs say nothing about needing to do that.

This link: (emphasis mine)

HLSL itself can support either row-major or column-major matrix formats, so the layout is entirely up to you (for more info, see HLSL, Matrix Ordering; if you use column-major matrix formats in your shaders, you need to transpose the DirectXMath matrix data as you place it into your constant buffer structures).

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

I am not sure what that says is different to what I said (although since the term D3DX does not appear anywhere in my codebase putting that bit of info regarding DirectXMath and HLSL there is not what Id call clear documentation, and I am pretty sure I came across the transpose requirement somewhere else, not on MSDN)?

I said I transpose the matrix for my HLSL shaders (i.e. the constant buffer holding a matrix for the vertex shader), it says nothing about transposing the matrix from DirectX::XMMatrix* stuff for use with other DirectX::* stuff. Anyway, transposing the BoundingFrustrum matrix for CreateFromMatrix does not work at all, it just makes some stuff near to and on one side of the world origin be in the frustum, everything else out, and the camera movement seems to have no/little effect, so going with that random idea being wrong. There must be some other issue? Is my contains method wrong?

Have you tried creating the view matrix in S-R-T order (scale, then rotate, then translate)?

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

Well that had the expected result of making the camera "orbit" the origin, and the frustum culling still culled things on screen.

This topic is closed to new replies.

Advertisement