vec4 lightmap3x3(sampler2D tex, sampler2D depth, sampler2D normals, vec2 coord, const int size) {
    ivec2 pixelPos  = ivec2(coord * viewSize);

    float depthCenter   = depthLinear(texelFetch(depth, pixelPos, 0).x) * far;
    vec3 normalCenter   = texelFetch(normals, pixelPos, 0).xyz * 2.0 - 1.0;
    vec4 colorCenter    = texelFetch(tex, pixelPos, 0);

    #define kernelMidIndex 4

    vec3 totalColor     = colorCenter.rgb * kernelW_3x3[kernelMidIndex];
    float totalWeight   = kernelW_3x3[kernelMidIndex];

    for (int i = 0; i < 9; i++) {
        if (i == kernelMidIndex) continue;

        ivec2 delta     = kernelO_3x3[i] * size;
        float weight    = kernelW_3x3[i];

        ivec2 currPos   = pixelPos + delta;
        if (clamp(currPos, ivec2(0), ivec2(viewSize)) != currPos) continue;

        vec3 normalCurr = texelFetch(normals, currPos, 0).xyz * 2.0 - 1.0;

        float normalWeight = pow(saturate(dot(normalCurr, normalCenter)), 8.0);

        if (normalWeight <= 0.0) continue;

        float depthCurr = texelFetch(depth, currPos, 0).x;
        if (depthCurr == 1.0) continue;
            depthCurr   = depthLinear(depthCurr) * far;
        float depthWeight = expf(-max(abs(depthCurr - depthCenter), 0.0));

        vec3 colorCurr  = texelFetch(tex, currPos, 0).rgb;

        weight *= normalWeight * depthWeight;

        totalColor += colorCurr * weight;
        totalWeight += weight;
    }

    totalColor *= rcp(totalWeight);

    return vec4(totalColor, colorCenter.a);
}