GPU Gemsのこの記事では、屈折について深く掘り下げています。これにより、かなり良い結果が得られます。

最も基本的な意味で
基本的な屈折テクニックの最初のステップは、すべての屈折メッシュをスキップして、シーンジオメトリをテクスチャにレンダリングすることです。このテクスチャを使用して、後続のパスでレンダリングされる屈折オブジェクトの背後に表示されるオブジェクトを決定できます。このテクスチャをSと表します。
2番目のステップでは、屈折メッシュをレンダリングし、テクスチャSから摂動を適用して値を調べ、屈折の外観をシミュレートします。摂動は、法線マップNを使用して実現できます。この場合、法線マップの赤と緑(XY)コンポーネントが使用され、投影されたテクスチャ座標に変位を追加するために、いくつかの小さな値でスケーリングされます。このアプローチは、シェーダーに実装するのが簡単です。
- テクスチャNをフェッチする
- 小さな値(0.05など)でスケーリングされたXYコンポーネントを使用する
- この変位値をSの投影されたテクスチャ座標に追加する
次のリストは、このアプローチを示すシェーダーを示しています
half4 main(float2 bumpUV : TEXCOORD0,
float4 screenPos : TEXCOORD1,
uniform sampler2D tex0,
uniform sampler2D tex1,
uniform float4 vScale) : COLOR
{
// fetch bump texture, unpack from [0..1] to [-1..1]
half4 bumpTex=2.0 * tex2D(tex0, bumpUV.xy) - 1.0;
// displace texture coordinates
half2 newUV = (screenPos.xy/screenPos.w) + bumpTex.xy * vScale.xy;
// fetch refraction map
return tex2D(tex1, newUV);
}
次の画像は、これらの3つのステップを示しています

同じ記事に、より魅力的な外観を実現できるより高度なテクニックがあります。
Unityで同様の効果を得るには、The Refraction Shader wikiページをご覧ください。