I set the background texture to mirroredrepeat so UV coordinates > 1 or < 0 just wrap. The normals for the mesh are all the same and do not change. The shader is using a normal map yes, but it's not used to modify the face normals, it's used to offset the background image:
vec4 norm = texture2D(m_Normal, texCoord2 * vec2(m_repeat_x, m_repeat_y));
vec2 offset = vec2((1.0 / m_screenX) * m_RefractionStrength, (1.0 / m_screenY) * m_RefractionStrength);
offset *= vec2(norm.r, norm.g) * vec2(2.0, 2.0) - vec2(1.0, 1.0);
vec2 wtc = vec2((worldTexCoord.x / m_screenX), (worldTexCoord.y / m_screenY)) - offset;
vec3 back = texture2D(m_background, wtc).rgb;
Made with GIMP and Blender. Used GIMP to create a black and white tileable cloud, then used that as a displace map on sub-divided plane in Blender and saved out the Normal pass after rendering.
P.S. When rendering with Blender Internal the normal pass is in a different format. For anyone wanting to make normal maps that way, you need take the normal pass channel and seperate into individual RGBA components, multiply both the red and green channels by 0.5 then add 0.5. The blue channel is inverted so it needs to be multiplied by -0.5 then add 0.5 then recombine, plug it into the composite node and save.