海洋シェーダ(反射と屈折)

海洋シェーダ(反射と屈折)

 前回の記事(海洋シェーダ(海の色))では、ノイズで変形させたゲルストナー波によって生成された波に、フレネル反射等を追加することで海を表現しました。この海へ、海面に反射して映るオブジェクトや海中にあるオブジェクトが透過して見える様子を追加しました。

海面の反射

 以前作成した平面の鏡面反射を利用して、海面に反射して映る画像を取得します。取得した画像をそのまま表示するのではなく、スクリーン座標を海の法線によって歪めています。さらに、GetSkyColorで処理し、海面に反射する色を求めています。

海中の屈折

 以前作成した水中の屈折(shader)を利用しています。これを使用することで海面下のオブジェクトを歪ませて表示することができます。

歪ませたオブジェクト以外の場所に海が表示されるようにコードを変更します。base_colorは海の色、_RefractionDepthで海面下のオブジェクトが表示される深さを変更できます。

オブジェクトの後ろに灰色の領域ができています。これは、カメラの深度テクスチャ(_CameraDepthTexture)全体を歪ませたまま深度差を計算しているためです。そこで以下のように、 カメラの深度テクスチャを海面下のみ歪ませ(ref_fix_f)、これを元に深度差を計算することで修正しました。

さらに、深くなるにつれ_SeaBaseColorへ変化した後に徐々に見えなくなるように処理を変更しました。これにより、一定の深さの間はオブジェクトのシルエットが表示されるようになります。_SilhouetteDepthによってシルエットが見える深さを調整することができます。

Shader

 作成したシェーダは以下の通りです。

Ocean.cginc

Noise.cginc