Simple occlusion culling algorithm is not culling out any of the objects

65 views Asked by At

I have some issues with implementing occlusion culling. For me, it doesn't seem to work as intended. Basically, on images I have my view frustum and object right in front of the camera. Unfortunately, the objects are still being visible. Don't quite understand why. Debuging camera frustum view(right in front of the object) for easier debugging Just a closer look

Shadow map and its mipmaps are being generated correctly, I checked this one. For generating mipmaps I am using max function on texels.

The first compute shader program is being executed before any object rendering(frustum culling):

  uint DrawIndex = gl_GlobalInvocationID.x;
  if(DrawIndex >= MeshCullingCommonInput.DrawCount) return;

  if(!MeshDrawCommandData[DrawIndex].IsVisible)
  {
    return;

  // Frustum Culling and populating indirect commands if object is actually visible
        .....

After this shader I am rendering all visible objects. Then I am generating mipmaps for my depth buffer via Hierarchy-Z. After that next shader program is for occlusion culling:

  uint DrawIndex = gl_GlobalInvocationID.x;
  if(DrawIndex >= MeshCullingCommonInput.DrawCount) return;

  uint MeshIndex = MeshDrawCommandData[DrawIndex].MeshIndex - 1;

  mat4 Proj = MeshCullingCommonInput.Proj;
  mat4 View = MeshCullingCommonInput.View;

  vec3 BoxMin = MeshOffsets[MeshIndex].AABB.Min.xyz * MeshDrawCommandData[DrawIndex].Scale.xyz + MeshDrawCommandData[DrawIndex].Translate.xyz;
  vec3 BoxMax = MeshOffsets[MeshIndex].AABB.Max.xyz * MeshDrawCommandData[DrawIndex].Scale.xyz + MeshDrawCommandData[DrawIndex].Translate.xyz;
  vec4 TransBoxMin = Proj * View * vec4(BoxMin, 1);
  vec4 TransBoxMax = Proj * View * vec4(BoxMax, 1);
  BoxMin = TransBoxMin.xyz / TransBoxMin.w;
  BoxMax = TransBoxMax.xyz / TransBoxMax.w;
  float BoxWidth  = ((BoxMax - BoxMin).x *  0.5 + 0.5) * MeshCullingCommonInput.HiZWidth ;
  float BoxHeight = ((BoxMax - BoxMin).y * -0.5 + 0.5) * MeshCullingCommonInput.HiZHeight;

        bool IsVisible = true;
        // Frustum Culling
        ........

  // Occlusion Culling
  if(IsVisible && MeshCullingCommonInput.OcclusionCullingEnabled)
  {
    float Lod = floor(log2(max(BoxWidth, BoxHeight)));

    vec2  BoxCoord = (BoxMin + BoxMax).xy * 0.5;
    vec2  UVCoords = BoxCoord * vec2(0.5, -0.5) + 0.5;
    float PyramidDepth = textureLod(DepthPyramid, UVCoords, Lod).x;

    IsVisible = IsVisible && (BoxMax.z > PyramidDepth);
  }

  MeshDrawCommandData[DrawIndex].IsVisible = IsVisible;

The main issue is with the Occlusion Culling, as there is nothing being occluded really. Don't really understand what I've done wrong, as algorithm is looking more or less fine. The desired behavior expected by me is that all of the objects behind shouldn't be visible, but, as seen on the image, nothing happened.

EDIT1 I've tried another approach to use Bounding Sphere instead of using AABB Results are something like this: enter image description here There are still some of the objects remaind if I look through this one. But if I look through this objects, non of the other objects is being culled: enter image description here

Right now I am trying this approach:

uint DrawIndex = gl_GlobalInvocationID.x;
if(DrawIndex >= MeshCullingCommonInput.DrawCount) return;

uint MeshIndex = MeshDrawCommandData[DrawIndex].MeshIndex - 1;

mat4 Proj = MeshCullingCommonInput.Proj;
mat4 View = MeshCullingCommonInput.View;

vec3 _SphereCenter = MeshOffsets[MeshIndex].BoundingSphere.Center.xyz * MeshDrawCommandData[DrawIndex].Scale.xyz + MeshDrawCommandData[DrawIndex].Translate.xyz;
vec4  SphereCenter = View * vec4(_SphereCenter, 1);
vec3  SphereRadius = vec3(MeshOffsets[MeshIndex].BoundingSphere.Radius) * MeshDrawCommandData[DrawIndex].Scale.xyz;

vec4 TransSphereCenter = Proj * SphereCenter;
vec3 Center = TransSphereCenter.xyz / TransSphereCenter.w;

vec4 TransSphereRadius = Proj * View * vec4(SphereRadius, 1);
vec3 Radius = TransSphereRadius.xyz / TransSphereRadius.w;

vec3 BoxMin = Center - Radius;
vec3 BoxMax = Center + Radius;
float BoxWidth  = ((BoxMax - BoxMin).x * 0.5 + 0.5) * MeshCullingCommonInput.HiZWidth ;
float BoxHeight = ((BoxMax - BoxMin).y * 0.5 + 0.5) * MeshCullingCommonInput.HiZHeight;

// Occlusion Culling
if(IsVisible && MeshCullingCommonInput.OcclusionCullingEnabled)
{
    float Lod = floor(log2(max(BoxWidth, BoxHeight)));

    vec2  BoxCoord = (BoxMin + BoxMax).xy * 0.5;
    float PyramidDepth = textureLod(DepthPyramid, BoxCoord * vec2(0.5, -0.5) + 0.5, Lod).x;
    float ObjectDepth  = BoxMax.z;
    
    IsVisible = IsVisible && (ObjectDepth > PyramidDepth);
}

MeshDrawCommandData[DrawIndex].IsVisible = IsVisible;
0

There are 0 answers