title: Simple GLSL convolution shader is atrociously slow
body: <p>I'm trying to implement a 2D outline shader in OpenGL ES2.0 for iOS. It is insanely slow. As in 5fps slow. I've tracked it down to the texture2D() calls. However, without those any convolution shader is undoable. I've tried using lowp instead of mediump, but with that everything is just black, although it does give another 5fps, but it's still unusable.</p>
  
  <p>Here is my fragment shader.</p>
  
  <pre><code>    varying mediump vec4 colorVarying;
      varying mediump vec2 texCoord;
  
      uniform bool enableTexture;
      uniform sampler2D texture;
  
      uniform mediump float k;
  
      void main() {
  
          const mediump float step_w = 3.0/128.0;
          const mediump float step_h = 3.0/128.0;
          const mediump vec4 b = vec4(0.0, 0.0, 0.0, 1.0);
          const mediump vec4 one = vec4(1.0, 1.0, 1.0, 1.0);
  
          mediump vec2 offset[9];
          mediump float kernel[9];
          offset[0] = vec2(-step_w, step_h);
          offset[1] = vec2(-step_w, 0.0);
          offset[2] = vec2(-step_w, -step_h);
          offset[3] = vec2(0.0, step_h);
          offset[4] = vec2(0.0, 0.0);
          offset[5] = vec2(0.0, -step_h);
          offset[6] = vec2(step_w, step_h);
          offset[7] = vec2(step_w, 0.0);
          offset[8] = vec2(step_w, -step_h);
  
          kernel[0] = kernel[2] = kernel[6] = kernel[8] = 1.0/k;
          kernel[1] = kernel[3] = kernel[5] = kernel[7] = 2.0/k;
          kernel[4] = -16.0/k;  
  
          if (enableTexture) {
                mediump vec4 sum = vec4(0.0);
              for (int i=0;i&lt;9;i++) {
                  mediump vec4 tmp = texture2D(texture, texCoord + offset[i]);
                  sum += tmp * kernel[i];
              }
  
              gl_FragColor = (sum * b) + ((one-sum) * texture2D(texture, texCoord));
          } else {
              gl_FragColor = colorVarying;
          }
      }
  </code></pre>
  
  <p>This is unoptimized, and not finalized, but I need to bring up performance before continuing on. I've tried replacing the texture2D() call in the loop with just a solid vec4 and it runs no problem, despite everything else going on.</p>
  
  <p>How can I optimize this? I know it's possible because I've seen way more involved effects in 3D running no problem. I can't see why this is causing any trouble at all.</p>