implement face culling in shader

Hello,


With metal 2 is it possible to implement frustum/occlusion culling on geometries. From the talks in WWDC2019 https://developer.apple.com/videos/play/wwdc2019/601/
I noticed that the ModernMetal rendering pipelines support occlusion culling on geometry chunks.

More specifically, in my case, I have a custom vertex and fragment shader like so,

vertex VertexOut textureSamplerVertex(VertexInput in [[ stage_in ]],
                                      constant NodeBuffer& scn_node [[buffer(0)]],
                                      constant SCNSceneBuffer& scn_frame [[buffer(1)]],
                                      texture2d<float, access::sample=""> customTexture [[texture(2)]],
                                      constant float4x4& displayTransform [[buffer(3)]],
                                      constant float4x4& viewTransform [[buffer(4)]],
                                      unsigned int v_id [[ vertex_id ]]
                                      ) {
...
}
fragmentfloat4 textureSamplerFragment(VertexOut out [[ stage_in ]], texture2d<float, access::sample=""> customTexture [[texture(0)]]) {
...
}


How can I modify/cull the faces inside the shader? Is this possible using metal shaders?

Answered by Graphics and Games Engineer in 612272022
The Modern Rendering sample culls complete objects or chunks of triangles that are occluded or outside the frustum. It sounds like you're asking if you can cull individual triangles.

You can do this in a kernel or shader using the same technique (testing a bounding box or sphere for intersection). However this would be less efficient than using the GPUs built-in frustum clipping and hidden surface removal (using a depth buffer).


Accepted Answer
The Modern Rendering sample culls complete objects or chunks of triangles that are occluded or outside the frustum. It sounds like you're asking if you can cull individual triangles.

You can do this in a kernel or shader using the same technique (testing a bounding box or sphere for intersection). However this would be less efficient than using the GPUs built-in frustum clipping and hidden surface removal (using a depth buffer).


Great! Is there sample code for such a kernel?

Also, would it possible to access the culled geometry inside the shader?
Code Block
VertexInput in [[ stage_in ]] has all the geometry
// something like
// if(!culled) {
// access the non- culled geometry here
//}
We have this sample that does this with 2D objects using indirect command buffers. It uses a compute kernel to check a bounding circle against the screen edges. If any part of the circle is on screen, the kernel adds a draw command in the indirect command buffer for that circle, otherwise it calls reset on the command on the command buffer to skip drawing this.

The modern rendering sample does something like this, but is a bit more complex. It does it for 3D objects and lights and includes some optimizations for for 3D n 3D and B) uses some more complex optimizations to batch mesh chunks who's vertices are contiguous in a mesh so that fewer draw calls are made.
implement face culling in shader
 
 
Q