Z-only pre-pass for opaque objects, using the shared DepthMaterial pipeline (same
one-pipeline-for-everyone approach CascadedShadowPassGPU/SpotShadowPassGPU already use for
shadow casters). Populates the main depth buffer BEFORE MainRenderPass's color pass runs, so
its unchanged depthCompare:"less-equal" test rejects occluded fragments via hardware early-Z
before their (often expensive, PBR + clustered-lighting) fragment shader ever runs -- no
change to depthWrite/depthCompare needed there, the win comes from the depth buffer already
holding the frontmost value by the time the color pass draws. MainRenderPass's opaque pass
switches depthLoadOp from "clear" to "load" to build on top of what this pass writes, instead
of erasing it -- this pass owns the once-per-frame clear now.
Z-only pre-pass for opaque objects, using the shared DepthMaterial pipeline (same one-pipeline-for-everyone approach CascadedShadowPassGPU/SpotShadowPassGPU already use for shadow casters). Populates the main depth buffer BEFORE MainRenderPass's color pass runs, so its unchanged depthCompare:"less-equal" test rejects occluded fragments via hardware early-Z before their (often expensive, PBR + clustered-lighting) fragment shader ever runs -- no change to depthWrite/depthCompare needed there, the win comes from the depth buffer already holding the frontmost value by the time the color pass draws. MainRenderPass's opaque pass switches depthLoadOp from "clear" to "load" to build on top of what this pass writes, instead of erasing it -- this pass owns the once-per-frame clear now.