KhronosGroup / KhronosGroup/Vulkan-Docs

Feature request: Add an "occlusion extents" shader function to enable occlusion culling from within a shader

Open
#2,148 1 comment 0 reactions 0 assignees View on GitHub
Feature Request
Dominant language
JavaScript
Stars
3.3k
Forks
549
Avg merge
5d 5h
Merged PRs (30d)
2

Description

### Mechanism

This "occlusion extents" function would accept a single point[^box] as input, from which a box would be projected against the depth buffer:
[^box]: Simplified for ease of depiction. A signature like `occlusionExtents(inout vec3 bb_min, inout vec3 bb_max)`, which accepts a bounding box rather than just a point, should have even more utility.

![occbox2](https://github.com/KhronosGroup/Vulkan-Docs/assets/103326468/e7ca8831-cb69-4689-bf49-72c33f6dbbc9)
LEFT: depth buffer | RIGHT: view from another angle | ORANGE DOT: input point | FLASHING: output box

Assuming this works as intended, shaders can then use this "occlusion extents box" to test multiple bounding boxes and determine whether their corresponding objects/meshlets should be culled:

![occmeshlet2](https://github.com/KhronosGroup/Vulkan-Docs/assets/103326468/29226391-8be1-4420-bd01-70c39a3fd057)
LEFT: depth buffer | RIGHT: view from another angle | TOP: a sample model divided into meshlets | BOTTOM: the bounding boxes of the meshlets | FLASHING: meshlets being culled by the "occlusion extents box" | GREEN LINE: forgot to hide the Y axis in blender, sorry

Implementations should be free to return any "occlusion extents box", as long as rasterizing it would cause all of its fragments to be discarded via depth, frustum, stencil, or scissor tests. The input merely acts as a suggestion.

### Rationale

Assuming this works as intended, this would provide the convenience of a single shader function that can quickly perform depth, frustum, stencil, and scissor tests for multiple objects all at once.

Since it provides more information than the simple pass/fail result of a standard bounding box test, culling can still be performed for sub-objects even if the main object passes, making this more friendly to wider BVH trees.

This is obviously primarily meant for mesh/task shaders (multiple "occlusion extents boxes" can easily fit into the payload to provide the desired level of occlusion granularity), but it also has benefits for tessellation shaders (which can now cull patches before they are tessellated into potentially hundreds of triangles) and compute pre-passes.

### Engine vs Driver

The standard approach for GPU-based occlusion culling is to do it from within the engine by manually copying the depth buffer, building a mipmap chain, and culling against it.

However, a driver-level solution may likely be more efficient, as it can (theoretically) use the GPU's Hi-Z buffer directly without having to touch the full-resolution depth buffer.

There may also be other behind-the-scenes optimizations that the driver can perform by having access to these boxes. For example, tile-based architectures may be able to use them as hints to bin task shaders, whereas previously they had poor synergy with mesh shading pipelines.

Contributor guide

Open the contributing guide

Research direction

No files, tests, or entry points are named. Start by reviewing the proposed occlusion-extents behavior and its engine-versus-driver rationale; done would require a decided specification design and an identified implementation and validation path.

Written by the indexing model from the issue text.

Assessment

Domain
api, computer-graphics
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.