Maybe you cna share your algorithm for frustum culling? Maybe I am missing something here (some space translations or something else?

Certainly, though it is quite old and could probably do with a revision.

I'm using axis aligned bounding boxes by the way, storing the min and max extents along the X/Y/Z axes in object space:

void BoundingBox::Transform(const XMMATRIX& mat, XMFLOAT3& vecMin, XMFLOAT3& vecMax) const { XMFLOAT3 coord[8]; // Front Vertices XMStoreFloat3(&coord[0], XMVector3TransformCoord(XMVectorSet(vecBaseMin.x, vecBaseMin.y, vecBaseMin.z, 1.0f), mat)); XMStoreFloat3(&coord[1], XMVector3TransformCoord(XMVectorSet(vecBaseMin.x, vecBaseMax.y, vecBaseMin.z, 1.0f), mat)); XMStoreFloat3(&coord[2], XMVector3TransformCoord(XMVectorSet(vecBaseMax.x, vecBaseMax.y, vecBaseMin.z, 1.0f), mat)); XMStoreFloat3(&coord[3], XMVector3TransformCoord(XMVectorSet(vecBaseMax.x, vecBaseMin.y, vecBaseMin.z, 1.0f), mat)); // Back Vertices XMStoreFloat3(&coord[4], XMVector3TransformCoord(XMVectorSet(vecBaseMin.x, vecBaseMin.y, vecBaseMax.z, 1.0f), mat)); XMStoreFloat3(&coord[5], XMVector3TransformCoord(XMVectorSet(vecBaseMax.x, vecBaseMin.y, vecBaseMax.z, 1.0f), mat)); XMStoreFloat3(&coord[6], XMVector3TransformCoord(XMVectorSet(vecBaseMax.x, vecBaseMax.y, vecBaseMax.z, 1.0f), mat)); XMStoreFloat3(&coord[7], XMVector3TransformCoord(XMVectorSet(vecBaseMin.x, vecBaseMax.y, vecBaseMax.z, 1.0f), mat)); }

void Camera::ReconstructFrustumPlanes() { // Left Frustum Plane // Add first column of the matrix to the fourth column frustumPlane[0].a = viewProj._14 + viewProj._11; frustumPlane[0].b = viewProj._24 + viewProj._21; frustumPlane[0].c = viewProj._34 + viewProj._31; frustumPlane[0].d = viewProj._44 + viewProj._41; // Right frustum Plane // Subtract first column of matrix from the fourth column frustumPlane[1].a = viewProj._14 - viewProj._11; frustumPlane[1].b = viewProj._24 - viewProj._21; frustumPlane[1].c = viewProj._34 - viewProj._31; frustumPlane[1].d = viewProj._44 - viewProj._41; // Top frustum Plane // Subtract second column of matrix from the fourth column frustumPlane[2].a = viewProj._14 - viewProj._12; frustumPlane[2].b = viewProj._24 - viewProj._22; frustumPlane[2].c = viewProj._34 - viewProj._32; frustumPlane[2].d = viewProj._44 - viewProj._42; // Bottom frustum Plane // Add second column of the matrix to the fourth column frustumPlane[3].a = viewProj._14 + viewProj._12; frustumPlane[3].b = viewProj._24 + viewProj._22; frustumPlane[3].c = viewProj._34 + viewProj._32; frustumPlane[3].d = viewProj._44 + viewProj._42; // Near frustum Plane // We could add the third column to the fourth column to get the near plane, // but we don't have to do this because the third column IS the near plane frustumPlane[4].a = viewProj._13; frustumPlane[4].b = viewProj._23; frustumPlane[4].c = viewProj._33; frustumPlane[4].d = viewProj._43; // Far frustum Plane // Subtract third column of matrix from the fourth column frustumPlane[5].a = viewProj._14 - viewProj._13; frustumPlane[5].b = viewProj._24 - viewProj._23; frustumPlane[5].c = viewProj._34 - viewProj._33; frustumPlane[5].d = viewProj._44 - viewProj._43; // Normalize planes for(unsigned int p = 0; p < 6; p++) { float length = sqrt( (frustumPlane[p].a * frustumPlane[p].a) + (frustumPlane[p].b * frustumPlane[p].b) + (frustumPlane[p].c * frustumPlane[p].c) ); frustumPlane[p].a /= length; frustumPlane[p].b /= length; frustumPlane[p].c /= length; frustumPlane[p].d /= length; } }

bool Camera::FrustumCullBoundingBox(const XMFLOAT3 &vecMin, const XMFLOAT3& vecMax) { for(unsigned int p = 0; p < 6; p++) { if(XMlaneDotCoord(&frustumPlane[p], &XMVectorSet(vecMin.x, vecMin.y, vecMin.z, 1)) >= 0.0f) continue; if(XMPlaneDotCoord(&frustumPlane[p], &XMVectorSet(vecMax.x, vecMin.y, vecMin.z, 1)) >= 0.0f) continue; if(XMPlaneDotCoord(&frustumPlane[p], &XMVectorSet(vecMin.x, vecMax.y, vecMin.z, 1)) >= 0.0f) continue; if(XMPlaneDotCoord(&frustumPlane[p], &XMVectorSet(vecMin.x, vecMin.y, vecMax.z, 1)) >= 0.0f) continue; if(XMPlaneDotCoord(&frustumPlane[p], &XMVectorSet(vecMax.x, vecMax.y, vecMin.z, 1)) >= 0.0f) continue; if(XMPlaneDotCoord(&frustumPlane[p], &XMVectorSet(vecMax.x, vecMin.y, vecMax.z, 1)) >= 0.0f) continue; if(XMPlaneDotCoord(&frustumPlane[p], &XMVectorSet(vecMin.x, vecMax.y, vecMax.z, 1)) >= 0.0f) continue; if(XMPlaneDotCoord(&frustumPlane[p], &XMVectorSet(vecMax.x, vecMax.y, vecMax.z, 1)) >= 0.0f) continue; return false; } return true; }