rafx-plugins 0.0.16

Rendering framework built on an extensible asset pipeline
Documentation
#version 450

// @[export]
// @[internal_buffer]
layout(set = 0, binding = 0) uniform DepthPyramidConfig
{
    // Size of image in pixels
    uint input_width;
    uint input_height;
    bool odd_width;
    bool odd_height;
} config;

// @[export]
layout (set = 0, binding = 1) uniform texture2D src_depth_tex;

// @[immutable_samplers([
//     (
//         mag_filter: Nearest,
//         min_filter: Nearest,
//         mip_map_mode: Nearest,
//         address_mode_u: ClampToEdge,
//         address_mode_v: ClampToEdge,
//         address_mode_w: ClampToEdge,
//     )
// ])]
layout (set = 0, binding = 2) uniform sampler smp;

// @[export]
layout (set = 0, binding = 3) writeonly uniform image2D dst_depth_tex;

layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
void main()
{
    if (gl_GlobalInvocationID.x >= config.input_width / 2) {
        return;
    }

    if (gl_GlobalInvocationID.y >= config.input_height / 2) {
        return;
    }

    //
    // Do 2x2 gather and take minimum value
    //
    vec2 texel_size = vec2(1.0 / config.input_width, 1.0 / config.input_height);
    vec2 src_uv = (gl_GlobalInvocationID.xy * 2 + vec2(0.5, 0.5)) * texel_size;
    vec4 gathered = textureGather(sampler2D(src_depth_tex, smp), src_uv);
    float min_value = min(min(gathered.x, gathered.y), min(gathered.z, gathered.w));

    //
    // In the case where we have odd source input, we actually need to do three samples. For example, a 5x5 mip
    // becomes 2x2 in the next mip, and each pixel in the 2x2 mip actually overlaps 3 pixels in the original mip.
    // 0 samples [0, 2.5] which is {0,1,2} and 1 samples [2.5, 5] which is {2,3,4}
    //
    if (config.odd_width) {
        float a = texture(sampler2D(src_depth_tex, smp), src_uv + vec2(2, 0) * texel_size).x;
        float b = texture(sampler2D(src_depth_tex, smp), src_uv + vec2(2, 1) * texel_size).x;
        min_value = min(min_value, min(a, b));
    }

    if (config.odd_height) {
        float a = texture(sampler2D(src_depth_tex, smp), src_uv + vec2(0, 2) * texel_size).x;
        float b = texture(sampler2D(src_depth_tex, smp), src_uv + vec2(1, 2) * texel_size).x;
        min_value = min(min_value, min(a, b));
    }

    if (config.odd_width && config.odd_height) {
        float a = texture(sampler2D(src_depth_tex, smp), src_uv + vec2(2, 2) * texel_size).x;
        min_value = min(min_value, a);
    }

    //
    // Write the minimum of all
    //
    imageStore(dst_depth_tex, ivec2(gl_GlobalInvocationID.xy), vec4(min_value));
}