I am trying to do Frustum Culling based on Goemetric Approach, however don't matter how much i try, the frustrum rotate to opposite side, i tried to find a solution over all internet, but couldn't find any, really need help with this.
FOV is 35.0f (in Radians value) [fov = glm::radians(35.0f);] UP is (0.0f, 0.0f, 1.0f) Width : 1280 Height : 720 AspectRatio : 16:9
The API what i am using is DirectX 11, actually it works perfectly, the entire map is being rendered perfectly, if i disable frustum culling, however when i enable the frustum culling it's only rendering a part on the wrong direction.
i am doing this:
Calculate Camera View
UP = EVector3(0.0f, 0.0f, 1.0f);
view = glm::lookAtRH(CameraPosition, PlayerPosition, UP);
Calculate Frustum
EFloat tan = EMath::Tan(fov * 0.5f);
_NearWidth = _Near * tan;
_NearHeight = _NearWidth / _AspectRatio;
_FarWidth = _Far * tan;
_FarHeight = _FarWidth / _AspectRatio;
position = PlayerPosition; // Force frustum at player position for see where it points, if i put camera position when i move the camera the view frustum goes on different way, and it already rotates on opposite direction
direction = EMath::Normalize(PlayerPosition - _CameraPosition);
right = EMath::Normalize(EMath::Cross(direction, UP));
up = EMath::Cross(right, direction);
direction = -direction; // glm::LookAtRH does this inside, if i don't do this the frustum doesn't work, but it still going on opposite direction
EVector3 nearCenter = position + (direction * _Near);
EVector3 farCenter = position + (direction * _Far);
EVector3 upNear = up * _NearHeight;
EVector3 rightNear = right * _NearWidth;
EVector3 upFar = up * _FarHeight;
EVector3 rightFar = right * _FarWidth;
EVector3 nearTL = nearCenter + upNear - rightNear;
EVector3 nearTR = nearCenter + upNear + rightNear;
EVector3 nearBR = nearCenter - upNear + rightNear;
EVector3 nearBL = nearCenter - upNear - rightNear;
EVector3 farTL = farCenter + upFar - rightFar;
EVector3 farTR = farCenter + upFar + rightFar;
EVector3 farBR = farCenter - upFar + rightFar;
EVector3 farBL = farCenter - upFar - rightFar;
EVector3 nearTop = nearTR - nearTL;
EVector3 nearLeft = nearBL - nearTL;
EVector3 topLeft = farTL - nearTL;
EVector3 bottomRight = nearBR - farBR;
EVector3 farRight = farTR - farBR;
EVector3 farBottom = farBL - farBR;
_Planes[WP_NEAR] = EMathPlane(EMath::Cross(nearTop, nearLeft), nearTL);
_Planes[WP_LEFT] = EMathPlane(EMath::Cross(nearLeft, topLeft), nearTL);
_Planes[WP_TOP] = EMathPlane(EMath::Cross(topLeft, nearTop), nearTL);
_Planes[WP_BOTTOM] = EMathPlane(EMath::Cross(farBottom, bottomRight), farBR);
_Planes[WP_RIGHT] = EMathPlane(EMath::Cross(bottomRight, farRight), farBR);
_Planes[WP_FAR] = EMathPlane(EMath::Cross(farRight, farBottom), farBR);
EMathPlane:
EMathPlane(const EVector3 &normal, const EVector3 &point)
{
_Normal = EMath::Normalize(normal);
_Distance = -EMath::Dot(_Normal, point);
_AbsNormal = EMath::Abs(_Normal);
}
all functions of my math library are redirected to GLM, for some reason the frustrum points to different area, i am doing a quadtree frustum culling, and i have static boxes prepared for each test, for example:
// First bounding box to check
{0.0f, 0.0f, 0.0f, // min x, y, z
25600.0f, 25600.0f, 1000.0f} // max x, y, z
// Another bounding box
{12800.0f, 12800.0f, 0.0f, // min x, y, z
19200.0f, 19200.0f, 1000.0f} // max x, y, z
here is the (IsVisible) function:
EVector3 center = (min + max) * 0.5f;
EVector3 half = (max - min) * 0.5f;
EVector3 absHalf = EMath::Abs(half);
EUInt32 isInside = 0x80000000;
for (EInt32 index = EMathFrustum::WP_NEAR;index < EMathFrustum::WP_MAX;index++)
{
EVector3 &normal = frustum._Planes[index]._Normal;
EFloat &dist = frustum._Planes[index]._Distance;
EVector3 tmpHalf = EVector3(EMath::ForceSign(absHalf.x, frustum._SignFlip[index][0]),
EMath::ForceSign(absHalf.y, frustum._SignFlip[index][1]),
EMath::ForceSign(absHalf.z, frustum._SignFlip[index][2]));
EVector3 corner = center - tmpHalf;
EFloat dot = EMath::Dot(corner, normal) + dist;
isInside &= RetrieveSign<EUInt32>(dot);
}
return isInside > 0;
it is based on Intel Software Culling sample, if the dot value is negative means the object is visible.
Resume of problem: It works(partially), the frustum is working well on the right player position(except when i put camera position, for some reason it goes to another way), however it rotates to wrong direction, if i rotate the camera to right, it rotates to left, i tried to find the problem in the code but i couldn't.
Really thanks everyone for your time, i am with this problem since 2 weeks, and tried everything for sure there is something what i am not doing well, but i don't know what it is, i am getting really stressed about it.