I am building a 3d renderer in C++ using Vulkan.hpp. The renderer uses a deferred shading model. I have implemented Spherical Harmonics (SH) coefficients for diffuse radiance as part of global illumination. I now want to apply depth testing in the lighting shader for each of the probes to approximate ambient shadows to compliment the SSAO. I believe this is called probe occlusion or probe masking. Right now I am starting with a single probe and will expand the entire process to multiple probes once I have the basics working. In my lighting shader I am passing the world position information from the g-buffer, the SH coefficient buffer, the probe position information and the depth cubemap generated at the probe position. The depth cubemap has the extents 0 to 1 based on the near plane = 0.1 and the far plane = 100.0. Based on the below excerpts of the lighting fragment shader, can you write or modify a function to perform the depth check and produce an ambient shadow for the diffuse radiance of the SH coefficients?

layout(input_attachment_index = 0, set = 0, binding = 0) uniform subpassInputMS gPosition;
layout(input_attachment_index = 1, set = 0, binding = 1) uniform subpassInputMS gNormal;
layout(input_attachment_index = 2, set = 0, binding = 2) uniform subpassInputMS gAlbedo;
layout(input_attachment_index = 3, set = 0, binding = 3) uniform subpassInputMS gSpecular; // R = metallic B = roughness G = ambient occlusion
layout(input_attachment_index = 4, set = 0, binding = 4) uniform subpassInputMS gDirectionalShadow;
layout(input_attachment_index = 5, set = 0, binding = 5) uniform subpassInputMS gPointShadow;
layout(input_attachment_index = 6, set = 0, binding = 13) uniform subpassInputMS gTangent;
layout(input_attachment_index = 7, set = 0, binding = 14) uniform subpassInputMS gBitangent;

layout(scalar, set = 0, binding = 18) buffer SHBuffer {
    vec3 shCoeffs[];
} shBuffer;
layout(set = 0, binding = 19) uniform samplerCube SHdepthMap;

layout(set = 0, binding = 20) uniform ProbePosition {
    vec3 probePos;
} probePosition;

// shCoeffs is an array of vec3, length 9
// normal is the world space normal vector (unit length)
vec3 evalDiffuseIrradiance(vec3 normal) {
    normal = normalize(normal);
    float x = normal.x;
    float y = normal.y;
    float z = normal.z;

    float shBasis[9];
    shBasis[0] = 0.282095;         // 0: Y0^0
    shBasis[1] = 0.488603 * y;     // 1: Y1^-1
    shBasis[2] = 0.488603 * z;     // 2: Y1^0
    shBasis[3] = 0.488603 * x;     // 3: Y1^1
    shBasis[4] = 1.092548 * x * y; // 4: Y2^-2
    shBasis[5] = 1.092548 * y * z; // 5: Y2^-1
    shBasis[6] = 0.315392 * (3.0 * z * z - 1.0); // 6: Y2^0
    shBasis[7] = 1.092548 * x * z; // 7: Y2^1
    shBasis[8] = 0.546274 * (x * x - y * y); // 8: Y2^2

    vec3 irradiance = vec3(0.0);
    for (int i = 0; i < 9; ++i) {
        irradiance += shBuffer.shCoeffs[i] * shBasis[i];
    }

    // Clamp to zero or small epsilon to avoid negative lighting artifacts
    irradiance = max(irradiance, vec3(0.0));

    return irradiance;
}

void main() {
...

    vec3 irradiance = evalDiffuseIrradiance(fragNormal);

    vec3 ambientDiffuse = irradiance * fragAlbedo * (1.0 - metallic) * kPi;
    float subsurfaceStrength = (1.0 - metallic) * roughness;
    if (subsurfaceStrength > 0.3) { // Threshold for SSS materials
        float wrap = subsurfaceStrength * 1.0; // Wrap factor for ambient
        vec3 wrappedIrradiance = evalDiffuseIrradiance(normalize(fragNormal + view_dir * wrap)).rgb;
        ambientDiffuse = wrappedIrradiance * fragAlbedo * (1.0 - metallic) * kPi;
    }
...
}