title: Blur kernel separation for two pass rendering
body: <p>It is necessary for me to calculate the kernel for two-pass blur. Suppose there is a blur kernel 5x5, which is generated as follows:</p>
  
  <pre><code>public static float[][] getKernelf(int size, float sigma) {
      float[][] kernel = new float[size][size];
      int mean = size / 2;
      float sum = 0; // For accumulating the kernel values
      for (int x = 0; x &lt; size; x++)  {
          for (int y = 0; y &lt; size; y++) {
              kernel[x][y] = (float) (Math.exp(-0.5 * (Math.pow((x - mean) / sigma, 2.0) + 
                      Math.pow((y - mean) / sigma, 2.0))) / (2 * Geometry.PI * sigma * sigma));
              // Accumulate the kernel values
              sum += kernel[x][y];
          }
      }
  
      // Normalize the kernel
      for (int x = 0; x &lt; size; x++) 
          for (int y = 0; y &lt; size; y++)
              kernel[x][y] /= sum;
  
      return kernel;
  }
  </code></pre>
  
  <p>With sigma = 1 and size = 5 we have the following kernel:</p>
  
  <pre><code>0.0029690173  0.013306212  0.021938235  0.013306212  0.0029690173
  0.013306212   0.059634306  0.09832035   0.059634306  0.013306212
  0.021938235   0.09832035   0.16210285   0.09832035   0.021938235
  0.013306212   0.059634306  0.09832035   0.059634306  0.013306212
  0.0029690173  0.013306212  0.021938235  0.013306212  0.0029690173
  </code></pre>
  
  <p>The question is how to bring this kernel into a view suitable for two-pass rendering (horizontally and vertically, real time rendering in OpenGL)</p>
  
  <p><strong>EDIT:</strong></p>
  
  <p>Kernel given by book: <code>0.227027  0.1945946  0.1216216  0.054054  0.016216</code></p>
  
  <p>My full <em>fragment_blur_shader.glsl:</em></p>
  
  <pre><code>#version 330
  
  out vec4 fragColor;
  in vec2 texCoords;
  
  uniform sampler2D image;
  uniform bool isHorizontal;
  uniform float weight[5] = float[] (0.227027, 0.1945946, 0.1216216, 0.054054, 0.016216);
  
  void main() {
      vec2 texOffset = 1.0 / textureSize(image, 0); // gets size of single texel
      vec3 result = texture(image, texCoords).rgb * weight[0]; // current fragment’s contribution
      if(isHorizontal) {
          for(int i = 1; i &lt; 5; i++) {
              result += texture(image, texCoords + vec2(texOffset.x * i, 0.0)).rgb * weight[i];
              result += texture(image, texCoords - vec2(texOffset.x * i, 0.0)).rgb * weight[i];
          }
      } else {
          for(int i = 1; i &lt; 5; ++i) {
              result += texture(image, texCoords + vec2(0.0, texOffset.y * i)).rgb * weight[i];
              result += texture(image, texCoords - vec2(0.0, texOffset.y * i)).rgb * weight[i];
          }
      }
      fragColor = vec4(result, 1.0);
  }
  </code></pre>
  
  <p>Also I found the following picture demonstrating the receipt of a 2D kernel from 1D kernel for a two-stage rendering:</p>
  
  <p><a href="https://i.stack.imgur.com/msEbm.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/msEbm.png" alt="Example of a 7x7 convolution kernel done using the two pass separable filter approach"></a></p>
  
  <p>But I have no idea how to get this 1D core. I am hope for your help.</p>
  
  <p><strong>EDIT:</strong></p>
  
  <p>I understood how to get the kernel I needed, but I still do not understand why the book gives this kernel in this form</p>