C
C#7mo ago
MrScautHD

Frustum culling

Hello i try to setup a Frustum culling system but it always returns true even if the object is not in the frustum. What i guess it is: Before normalization, it functions correctly, albeit with an incorrect size. To achieve precision, I must closely inspect my object, making slight rotations. However, after normalization, it consistently returns true and never provides a false outcome. Normalized: https://media.discordapp.net/attachments/1036008388552839169/1173215015948521573/image.png?ex=656324a1&is=6550afa1&hm=7de8eef894c9cf4cb5be82363e2ee0c06aa89034da866294b7d0da3dbc8ce1d4&= Wihout Normalizing: if i look exactly on it i can see it: https://cdn.discordapp.com/attachments/1036008388552839169/1173215314331320440/image.png?ex=656324e8&is=6550afe8&hm=8bf65ae87f380c572e57db16235cfa9e02d8cc827433beea3cf2dc81af6f577b& But if i move more away it is gone: https://cdn.discordapp.com/attachments/1036008388552839169/1173215337727139890/image.png?ex=656324ed&is=6550afed&hm=64e388f63e55102dda61e83af167daf05b5d8bb4fa258eb9dfea8c73362c0193& My class:
public class Frustum {

// View frustum planes
private Plane[] _frustumPlanes;

public Frustum(Matrix4x4 viewProjectionMatrix) {
_frustumPlanes = ExtractPlanes(viewProjectionMatrix);
}

public bool IsSphereInFrustum(Vector3 center, float radius) {
foreach (var plane in _frustumPlanes) {
float distance = Vector3.Dot(plane.Normal, center) + plane.D;

if (distance < -radius) {
// The sphere is entirely behind this plane, it is outside the frustum
return false;
}
}

// The sphere is not entirely behind any plane, it is partially or fully inside the frustum
return true;
}

private Plane[] ExtractPlanes(Matrix4x4 viewProjectionMatrix) {

// Extract view frustum planes from the view-projection matrix
Plane[] planes = new Plane[6];

// Left plane
planes[0] = new Plane(
viewProjectionMatrix.M14 + viewProjectionMatrix.M11,
viewProjectionMatrix.M24 + viewProjectionMatrix.M21,
viewProjectionMatrix.M34 + viewProjectionMatrix.M31,
viewProjectionMatrix.M44 + viewProjectionMatrix.M41
);

// Right plane
planes[1] = new Plane(
viewProjectionMatrix.M14 - viewProjectionMatrix.M11,
viewProjectionMatrix.M24 - viewProjectionMatrix.M21,
viewProjectionMatrix.M34 - viewProjectionMatrix.M31,
viewProjectionMatrix.M44 - viewProjectionMatrix.M41
);

// Bottom plane
planes[2] = new Plane(
viewProjectionMatrix.M14 + viewProjectionMatrix.M12,
viewProjectionMatrix.M24 + viewProjectionMatrix.M22,
viewProjectionMatrix.M34 + viewProjectionMatrix.M32,
viewProjectionMatrix.M44 + viewProjectionMatrix.M42
);

// Top plane
planes[3] = new Plane(
viewProjectionMatrix.M14 - viewProjectionMatrix.M12,
viewProjectionMatrix.M24 - viewProjectionMatrix.M22,
viewProjectionMatrix.M34 - viewProjectionMatrix.M32,
viewProjectionMatrix.M44 - viewProjectionMatrix.M42
);

// Near plane
planes[4] = new Plane(
viewProjectionMatrix.M13,
viewProjectionMatrix.M23,
viewProjectionMatrix.M33,
viewProjectionMatrix.M43
);

// Far plane
planes[5] = new Plane(
viewProjectionMatrix.M14 - viewProjectionMatrix.M13,
viewProjectionMatrix.M24 - viewProjectionMatrix.M23,
viewProjectionMatrix.M34 - viewProjectionMatrix.M33,
viewProjectionMatrix.M44 - viewProjectionMatrix.M43
);

// Normalize the planes
for (int i = 0; i < 6; i++) {
planes[i] = Plane.Normalize(planes[i]);
}

return planes;
}
}
public class Frustum {

// View frustum planes
private Plane[] _frustumPlanes;

public Frustum(Matrix4x4 viewProjectionMatrix) {
_frustumPlanes = ExtractPlanes(viewProjectionMatrix);
}

public bool IsSphereInFrustum(Vector3 center, float radius) {
foreach (var plane in _frustumPlanes) {
float distance = Vector3.Dot(plane.Normal, center) + plane.D;

if (distance < -radius) {
// The sphere is entirely behind this plane, it is outside the frustum
return false;
}
}

// The sphere is not entirely behind any plane, it is partially or fully inside the frustum
return true;
}

private Plane[] ExtractPlanes(Matrix4x4 viewProjectionMatrix) {

// Extract view frustum planes from the view-projection matrix
Plane[] planes = new Plane[6];

// Left plane
planes[0] = new Plane(
viewProjectionMatrix.M14 + viewProjectionMatrix.M11,
viewProjectionMatrix.M24 + viewProjectionMatrix.M21,
viewProjectionMatrix.M34 + viewProjectionMatrix.M31,
viewProjectionMatrix.M44 + viewProjectionMatrix.M41
);

// Right plane
planes[1] = new Plane(
viewProjectionMatrix.M14 - viewProjectionMatrix.M11,
viewProjectionMatrix.M24 - viewProjectionMatrix.M21,
viewProjectionMatrix.M34 - viewProjectionMatrix.M31,
viewProjectionMatrix.M44 - viewProjectionMatrix.M41
);

// Bottom plane
planes[2] = new Plane(
viewProjectionMatrix.M14 + viewProjectionMatrix.M12,
viewProjectionMatrix.M24 + viewProjectionMatrix.M22,
viewProjectionMatrix.M34 + viewProjectionMatrix.M32,
viewProjectionMatrix.M44 + viewProjectionMatrix.M42
);

// Top plane
planes[3] = new Plane(
viewProjectionMatrix.M14 - viewProjectionMatrix.M12,
viewProjectionMatrix.M24 - viewProjectionMatrix.M22,
viewProjectionMatrix.M34 - viewProjectionMatrix.M32,
viewProjectionMatrix.M44 - viewProjectionMatrix.M42
);

// Near plane
planes[4] = new Plane(
viewProjectionMatrix.M13,
viewProjectionMatrix.M23,
viewProjectionMatrix.M33,
viewProjectionMatrix.M43
);

// Far plane
planes[5] = new Plane(
viewProjectionMatrix.M14 - viewProjectionMatrix.M13,
viewProjectionMatrix.M24 - viewProjectionMatrix.M23,
viewProjectionMatrix.M34 - viewProjectionMatrix.M33,
viewProjectionMatrix.M44 - viewProjectionMatrix.M43
);

// Normalize the planes
for (int i = 0; i < 6; i++) {
planes[i] = Plane.Normalize(planes[i]);
}

return planes;
}
}
3 Replies
MrScautHD
MrScautHD7mo ago
Has anyone a idea?
WEIRD FLEX
WEIRD FLEX7mo ago
did you debug it do look if numbers are what you expect? to me the -radius in if (distance < -radius) { seems odd
MrScautHD
MrScautHD7mo ago
i got it already thx:
Matrix4x4 viewProjection = Matrix4x4.Transpose(Rlgl.GetMatrixModelview()) * Matrix4x4.Transpose(Rlgl.GetMatrixProjection());
Matrix4x4 viewProjection = Matrix4x4.Transpose(Rlgl.GetMatrixModelview()) * Matrix4x4.Transpose(Rlgl.GetMatrixProjection());