title: Reflection/refraction with chromatic aberration - eye correction
body: <p>I am writing a GLSL shader that simulates chromatic aberration for simple objects. I am staying OpenGL 2.0 compatible, so I use the built-in OpenGL matrix stack. This is the simple vertex shader:</p>
  
  <pre><code>uniform vec3 cameraPos;
  
  varying vec3 incident;
  varying vec3 normal;
  
  void main(void) {
      vec4 position = gl_ModelViewMatrix * gl_Vertex;
      incident = position.xyz / position.w - cameraPos;
      normal   = gl_NormalMatrix * gl_Normal;
  
      gl_Position = ftransform();
  }
  </code></pre>
  
  <p>The <code>cameraPos</code> uniform is the position of the camera in model space, as one might imagine. Here is the fragment shader:</p>
  
  <pre><code>const float etaR = 1.14;
  const float etaG = 1.12;
  const float etaB = 1.10;
  const float fresnelPower = 2.0;
  const float F = ((1.0 - etaG) * (1.0 - etaG)) / ((1.0 + etaG) * (1.0 + etaG));
  
  uniform samplerCube environment;
  
  varying vec3 incident;
  varying vec3 normal;
  
  void main(void) {
      vec3 i = normalize(incident);
      vec3 n = normalize(normal);
  
      float ratio = F + (1.0 - F) * pow(1.0 - dot(-i, n), fresnelPower);
  
      vec3 refractR = vec3(gl_TextureMatrix[0] * vec4(refract(i, n, etaR), 1.0));
      vec3 refractG = vec3(gl_TextureMatrix[0] * vec4(refract(i, n, etaG), 1.0));
      vec3 refractB = vec3(gl_TextureMatrix[0] * vec4(refract(i, n, etaB), 1.0));
  
      vec3 reflectDir = vec3(gl_TextureMatrix[0] * vec4(reflect(i, n), 1.0));
  
      vec4 refractColor;
      refractColor.ra = textureCube(environment, refractR).ra;
      refractColor.g  = textureCube(environment, refractG).g;
      refractColor.b  = textureCube(environment, refractB).b;
  
      vec4 reflectColor;
      reflectColor    = textureCube(environment, reflectDir);
  
      vec3 combinedColor = mix(refractColor, reflectColor, ratio);
  
      gl_FragColor = vec4(combinedColor, 1.0);
  }
  </code></pre>
  
  <p>The <code>environment</code> is a cube map that is rendered live from the drawn object's environment.</p>
  
  <p>Under normal circumstances, the shader behaves (I think) like expected, yielding this result:</p>
  
  <p><img src="https://i.stack.imgur.com/Namyb.png" alt="correct shader behavior"></p>
  
  <p>However, when the camera is rotated 180 degrees around its target, so that it now points at the object from the other side, the refracted/reflected image gets warped like so (This happens gradually for angles between 0 and 180 degrees, of course):</p>
  
  <p><img src="https://i.stack.imgur.com/YzJip.png" alt="incorrect shader behavior"></p>
  
  <p>Similar artifacts appear when the camera is lowered/raised; it only seems to behave 100% correctly when the camera is directly over the target object (pointing towards negative Z, in this case).</p>
  
  <p>I am having trouble figuring out which transformation in the shader that is responsible for this warped image, but it should be something obvious related to how <code>cameraPos</code> is handled. What is causing the image to warp itself in this way?</p>