// Sample triangular depth map
// see CoD SIGGRAPH 2017 "Advances in Real-Time Graphics in Games" course
// depth is encoded as 4 * uint32
float GetDepthForTetrahedronProbe(vec2 bary, uvec4 encodedDepth)
{
    float sampleY = floor(bary.y * 4.0f);
    float sampleX = floor(bary.x * 4.0f);

    int baseIndex = int((((11.0f - sampleY) * sampleY) * 0.5f + sampleX + 0.5f));
    int lineLength = 5 - int(sampleY);

    vec2 baseBary = vec2(sampleX * 0.25f, sampleY * 0.25f);

    ivec3 indices = ivec3(baseIndex + 1, baseIndex + lineLength, baseIndex);

    // figure out barycentric coordinates within the triangular sample, this will be needed for bilinear interpolation
    vec3 sampleBary;
    sampleBary.x = (bary.x - baseBary.x) * 4.0f;
    sampleBary.y = (bary.y - baseBary.y) * 4.0f;

    if (sampleBary.x + sampleBary.y > 1.0f)
    {
        // above the diagonal
        indices = ivec3(baseIndex + lineLength, baseIndex + 1, baseIndex + lineLength + 1);

        vec3 newSampleBary;

        newSampleBary.x = -(sampleBary.y - 1.0f);
        newSampleBary.y = -(sampleBary.x - 1.0f);

        sampleBary = newSampleBary;
    }

    sampleBary.z = 1.0f - sampleBary.x - sampleBary.y;

    // perform bilinear interpolation of depth
    float result = 0.0f;
    for (int i = 0; i < 3; ++i)
    {
        uint currIndex = indices[i];

        int intDepth = (encodedDepth[currIndex / 4] >> ((currIndex % 4) * 8)) & 0xFF;

        float depth = float(intDepth / 255.0f);

        result += sampleBary[i] * depth;
    }

    return result;
}
