海洋シェーダ(泡)

海洋シェーダ(泡)

 前回の記事(海洋シェーダ(反射と屈折))では、海面に反射して映るオブジェクトや海中の屈折して見えるオブジェクトを追加しました。今回は、海面に生じる泡の追加を行いました。

波の高さにより泡を生成

 波が特定の高さになったときに泡を発生させます。波ごとに高さの判定を行っていますが、その際、波の振幅を計算から除外しています。これにより、振幅が低い波でも泡が発生するように処理をしています。また、泡のテクスチャは波ごとに割り当て、波の移動方向へテクスチャを動かしています。さらに、泡に合わせて求めた法線と最終的に求まった泡を用いて、FoamColorにより泡にハーフランバート反射を追加しています。

泡の生成箇所の計算

 以下のコードにより波の高さを計算しています。波の振幅を含めないことで、振幅が低い波でも泡が発生するように処理をしています。

得られた高さより、泡を発生させる場所を求めます。

最後に、実際の波の高さ(wave_height)を乗算することで、波の高くなっている部分のみに泡が発生するように処理をしています。また、_HeightFoamStrengthによって泡の強さを調整しています。

法線の計算

 ノーマルマップから泡のテクスチャに合わせて法線を取得します。

下記のコードより、上方を示す法線(geo_normal)と泡の法線(foam_normal)を泡の強度(foam_factor)によって線形補間をすることで、泡の強度に応じた法線を求めています。

波ごとに法線を求めBlendNormal_rnmによって法線を順に合成することで最終的な泡の法線を求めています。

さらに、上方を示す法線(tangent_space_geo_normal )と合成した泡の法線を最終的に求まった泡の強度(foam)で線形補間することで、泡の法線を求めています。

ライティング

 求めた泡にハーフランバート反射を追加することで陰影をつけています。

実行結果

 波の高さによって求めた泡を追加すると以下のような結果が得られます。

波の法線により泡を生成

 波の高さを用いて泡を生成すると、波の高い部分のみに泡が発生します。波の低い部分にも泡を発生させるために、波の法線を用いて泡の生成を行います。 上方を示すベクトルと波の法線の内積を求め、その値から波が急になっている部分を求め、この結果にテクスチャを乗算することで泡を生成します。

泡の生成箇所の計算

 波上方を示すベクトル(world_space_geo_normal)と波の法線(wave_normal)の内積を求めます。

この結果を用いて

と処理することで波が急になっている部分を求めています。この結果にテクスチャを乗算することで泡を生成しています。さらに、波の高さにより求めた泡を加算することで最終的な泡を求めています。

法線の計算

 ノーマルマップより法線を取り出し、上方を示す法線(tangent_space_geo_normal)と泡の法線(foam_normal_s )を求めた泡の強度(foam_factor)で線形補間することで泡の法線を求めています。さらに、この法線と波の高さによって求めた泡の法線を合成することで最終的な泡の法線を求めています。

実行結果

波の法線より生成した泡は以下のようになります。

波の高さにより生成した泡と波の法線より生成した泡を組み合わせると以下の結果が得られます。

オブジェクトの周りに発生する泡

 海面に接するオブジェクトの周りに発生する泡を追加しました。

泡の生成箇所の計算

 以下のコードでオブジェクトと海面の深度差を計算しています。

この深度差を用いて泡の生成箇所を計算しています ( fire-face:Water breakdown ) 。この結果に、泡のテクスチャを乗算することでオブジェクト周りに泡を生成しています。

法線の計算

 今までの方法と同様に、上方を示す法線(tangent_space_geo_normal)と泡のノーマルマップより取り出した法線(foam_normal)を泡の強度(depth_foam * _FoamNormalStrength)で線形補完することで泡の法線を求めています。

実行結果

 実行すると、以下のようにオブジェクト周りに泡を発生させることができます。

シェーダ

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

OceanFoam.shader

Ocean.cginc

Noise.cginc

テクスチャ

 この記事で使用したテクスチャは以下の通りです。

・泡テクスチャ(_FoamTex、_FoamNormalTex、_DetailDepthFoamTex、_DetailDepthFoamNormalTex)

Unity Asset Store:Foam Textures

・深度差による泡生成用テクスチャ(_DepthFoamTex)

参考サイト

GPU Gems 2:Chapter 18. Using Vertex Texture Displacement for Realistic Water Rendering

fire-face:Water breakdown

Self Shadow :Blending in Detail