CPU asks GPU “is this triangles visible ?” and then sends what objects to render and to not render, it is done by hardware itself and this technique causes CPU overhead and Hierarchical Z-Buffering is a better technique then this.

Imagine you have a complex object say a detailed castle with 50,000 triangles. Before you commit to rendering all of it, you’d love to ask the GPU: “Hey, can the player even see this thing right now, or is it completely hidden behind a wall?”

That’s exactly what an occlusion query does. You render a cheap stand-in for the object (its bounding box, maybe 12 triangles) in a special mode where the GPU rasterizes those triangles and tests them against the existing z-buffer, but writes nothing no color output, no depth writes. It simply counts how many pixels would have passed the depth test. If the count is zero, the bounding box is entirely behind other geometry, so you can safely skip the expensive castle entirely.

In Vulkan terms, think of this as issuing vkCmdBeginQuery with a VK_QUERY_TYPE_OCCLUSION query pool, drawing the bounding box with depth writes and color writes disabled, then vkCmdEndQuery. Later, you read back the result with vkGetQueryPoolResults.