ひとことで
水面の頂点を上下だけでなく前後にも円を描くように動かして、波頭の尖った海の波を作る方法です。正弦波で上下に揺らすだけだと山も谷も同じ丸い形になりますが、ゲルストナー波では水の粒が山で前へ寄り集まり、谷で離れるので、本物の海のように山は鋭く、谷は平らになります。
ゲームでの使いどころ
- 海や湖の水面:船が進む海原、港、ビーチ。頂点変位だけで作れるので、多くのゲームで海の基本形として使われます。
- CPU と GPU で同じ波を計算できる:波の式が単純なので、描画用の頂点シェーダーと、船を浮かべる浮力の計算で同じ高さを求められます。見た目と物理がずれません。
- 波頭の泡:水面がどれだけ縮んだか(ヤコビアン)も式から求まるので、尖った波頭だけを白く泡立たせられます(ホワイトウォーター)。
- 遠景とのつなぎ:近くはゲルストナー波、遠くは法線マップだけ、という使い分けがよく行われます。
しくみ
水面上の元の位置 にある点を、次の位置へ動かします。
- は振幅、 は進む向き、 は波数(波長 の逆数)、 はばらばらの初期位相です。
- (深い海の分散関係)とすると、長い波ほど速く進むという本物の海の性質が再現されます。
- 水平方向の項 があるので、各点は縦の円( で真円)を描きます。山()では 付近で点が前へ寄り、尖ります。
波の向きや長さを少しずつ変えて 4〜12 本ほど重ねると、規則的すぎない海面になります。多くの場合、風向きの周りに向きを散らし、波長の短い波ほど振幅を小さくします。
尖り の上限に注意します。 になると、隣の点を追い越して水面が裏返り、輪(ループ)ができてしまいます。そこで、各波の を「全体の尖り ÷( 波の本数)」とし、合計が 1 を超えないようにします。
実装のポイント
- 法線は解析的に:式を微分すれば法線が求まるので、周りの頂点から差分で計算する必要はありません。細かい波は頂点を増やさず、法線にだけ足す(または法線マップを重ねる)とコストを抑えられます。
- ある地点の水面の高さ:点は水平にも動くので、 の真上の高さは式にそのまま代入しても求まりません。「代入 → ずれた分だけ戻す」を数回くり返して、元の位置を逆算します(浮力の計算で必要になります)。
- タイル状の繰り返しを隠す:本数が少ないと周期が目立ちます。互いに割り切れない波長を選び、遠くは霧や空気遠近法でぼかします。
つまずきやすい点
- 尖らせすぎて水面が裏返る:尖りを上げすぎると、波頭で三角形が裏返ってちらつきます。上に書いた の正規化を入れます。
- 頂点が足りない:波長より頂点の間隔が粗いと、波がカクカクに折れて見えます。カメラの近くほど細かい格子(LOD)にします。
- 法線を変位前の位置で使う:シェーダーで法線を計算し忘れると、形は波打っているのに陰影が平らなままになります。
デモで試すこと
- 「波の動かし方」を「正弦波(上下だけ)」に切り替えると、山も谷も同じ丸い形になります。「ゲルストナー波(円運動)」に戻すと、山が尖り谷が広がります。
- 光る点の列は、最初は一直線に並んだ水の粒です。波が通るたびに縦の円を描いて元に戻る様子と、山の所で点が詰まる様子を見てください。
- 「尖り具合 Q」を 0 にすると正弦波と同じになり、1 に近づけるほど波頭が鋭くなります。
- 「重ねる波の数」を 1 にすると、規則正しい 1 本の波になります。本数を増やすほど自然な海に近づきます。