Try to do the following:
1. Start with something very simple like hardcoding the Gaussian coefficients in a table and iterate on these values in the fragment shader. You can use a Pascal triangle to get discrete Gaussian coefficients. Here’s some glsl fragment shader code to get you started:
in VS_OUT
{
noperspective vec2 uv;
} IN;
out vec4 outColor;
uniform sampler2D offscreen;
const vec4[] gaussKernel3x3 =
{
vec4(-1.0, -1.0, 0.0, 1.0 / 16.0),
vec4(-1.0, 0.0, 0.0, 2.0 / 16.0),
vec4(-1.0, +1.0, 0.0, 1.0 / 16.0),
vec4( 0.0, -1.0, 0.0, 2.0 / 16.0),
vec4( 0.0, 0.0, 0.0, 4.0 / 16.0),
vec4( 0.0, +1.0, 0.0, 2.0 / 16.0),
vec4(+1.0, -1.0, 0.0, 1.0 / 16.0),
vec4(+1.0, 0.0, 0.0, 2.0 / 16.0),
vec4(+1.0, +1.0, 0.0, 1.0 / 16.0),
};
void main(void)
{
const vec2 texelSize = vec2(1.0) / textureSize(offscreen, 0);
vec4 color = vec4(0.0);
for (int i = 0; i < gaussKernel3x3.length(); ++i)
color += gaussKernel3x3[i].w * texture(offscreen, IN.uv + texelSize * gaussKernel3x3[i].xy);
outColor = color;
}
What I like about this approach is that you can easily extend it to any filter. This is not production-ready code though, just to get you up and running (you can also add an offset of 0.5 to get a bilinear filtering for free if you want).
2. Change the 2d kernel into 1d and run 2 passes. Most of the work here is OpenGL / Vulkan and not shader code.
3. Use the bilinear sampling trick to reduce the number of texture fetches. This is a math problem: you want to compute w0 * texture(offscreen, uv) + w1 * texture(offscreen, uv + texelSize * vec2(1.0, 0.0)) in a single fetch by adjusting the weights and offset in between.
I think that should get you started for a fixed size Gaussian blur. If you want a variable size kernel, try to do one of the following:
1. Compute the Gaussian kernel incrementally as described in GPU Gems.
2. Successively apply box blur which can be implemented as a compute shader.
3. Use pre-filtered blurred images and a variable size Poisson disk for sampling (see the bottom of this article: https://john-chapman.github.io/2019/03/29/convolution.html) to keep the number of fetches constant.
Good luck!