抽象的な2Dトップダウン水テクスチャをアニメーション化する方法は?


24

私は現在、海のトップダウンビューでゲームを実装しています。次の、少し抽象的なテクスチャを使用します。ここに画像の説明を入力してください

実際のテクスチャは透明ですが、わかりやすくするために緑色のような色を追加しました。

私が今抱えている問題は、このテクスチャをアニメーション化する方法がわからないため、水がきれいに見えることです。私はサイン波でテクスチャを動かそうとしました: texture.y += sin(angle)。もちろん、今ではテクスチャ全体が動いており、非現実的に見えます。次に試したのは、別のレイヤーを追加して視差効果を実装することです。そのため、水面下の反射も移動しますが、はるかに遅くなります。見た目は少し良くなっていますが、それでもまだ...いい感じです。

個々のセルが拡大したり収縮したりする場合、ウェブや布のように見えるのが最高のアニメーションだと思います。誰かがこれらのセルの1つの頂点をわずかに引っ張り、隣接するセルが拡大し、私が引き寄せる(またはプッシュする)セルが収縮すると想像してください。一種のウェブのようなもの(?)。しかし、私はこのようなものを実装する方法がわかりません:

  • これの数学モデルは何ですか?バネのあるもの、どこで力が押したり引いたりしますか?
  • もしそうなら、このモデルを指定されたテクスチャにどのようにマップしますか?すべての曲線を保持し、そうではない...

(また、与えられたテクスチャをアニメーション化する方法について、さまざまなアイデア/回答を受け入れています。リアリズムはここでのポイントではなく、動きのような見た目の良い水です...)

DMGregoryのソリューション

この投稿にlibgdxの例を投稿しました:2D水アニメーションはギザギザで滑らかではありません(テクスチャフィルタリングに関する回答を参照)

回答:


41

これを行う一般的な方法は、シェーダーで間接的なテクスチャルックアップを使用して表示テクスチャを歪めることです。

水のアニメーションを示すアニメーションgif

ここでは、低周波数のカラーノイズ(ランダムな色の滑らかな塊を並べる)を使用したテクスチャを使用し、時間とともにディスプレイジオメトリをスクロールします。

ここに画像の説明を入力してください

このテクスチャから色を描画する代わりに、代わりに赤と緑のチャンネルを取り、0.5fそれらを減算して、時間と空間にわたって滑らかに変化する擬似ランダム2Dベクトルに変えます。

次に、メインの水テクスチャからサンプリングする前に、このベクトルの小さな倍数をUV座標に追加できます。これにより、読み取りおよび表示しているテクスチャの部分が移動し、歪んでいます。

このノイズから2つのサンプルを平均化し、反対方向にスクロールすることで、動きの方向を非表示にして、目的のないスロッシングのように見せることができます。

Unityでは、シェーダーは次のようになります。選択したシェーダー言語に翻訳するのに十分なシンプルさでなければなりません。

fixed4 frag (v2f i) : SV_Target
{               
    float2 waveUV = i.uv * _NoiseScale;
    float2 travel = _NoiseScrollVelocity * _Time.x;

    float2 uv = i.uv;
    uv += _Distortion * (tex2D(_Noise, waveUV + travel).rg - 0.5f);
    waveUV += 0.2f; // Force an offset between the two samples.
    uv += _Distortion * (tex2D(_Noise, waveUV - travel).rg - 0.5f);

    // Sample the main texture from the distorted UV coordinates.
    fixed4 col = tex2D(_MainTex, uv);

    return col;
}

1
これは本当にすてきです。すべての属性を理解しているかどうかはわかりません:_NoseScale =「ノイズマップ」をスケーリングするためのスカラー。_NoiseScrollVelocity =ノイズマップ上を移動する速度のVector2。_ノイズ=?_Distortion =スカラー歪み係数として選択しますか?v2f =頂点色を決定します。i =?
-morpheus05

_Noise上記の小さなブロビーランダムテクスチャ[から読み込むテクスチャサンプラー]です。v2f iは、頂点シェーダーからの補間データですi.uv。主に、描画しているピクセルのテクスチャ座標を取得するために使用します。そして、あなたは他のすべてについて正確に正しいです。
DMGregory

シェーダーを実装しましたが、どういうわけか機能しません(動かないか、歪みが大きい)、値を正しく設定しなかったと思います。時間=最後のフレームとの差(ミリ秒)。noise_scale = 1(テクスチャを使用し、ラップモードを繰り返します)noise_scroll_velocity = [0.01、0.01]歪み= 0.02
morpheus05

変数はDeltaTimeではなくTimeと呼ばれることに注意してください。時間の差を使用し、フレームレートが一貫している場合、常に同じ数値を取得し、同じ入力でシェーダーを再実行し、同じ出力を取得します(何も動きません)。さらに悪いことに、フレームレートに一貫性がない場合、前後に振動が発生します。デルタ時間ではなく、合計経過時間が必要です。
DMGregory

すぐに私は送信をヒットし、私はそれに気づき、今ではほとんど機能しています。アニメーションは右下隅から波を生成し、10秒程度で波が止まるようにフェードアウトします。この理由は何でしょうか?
morpheus05

6

これはコースティクスエフェクトと呼ばれ、実行時にこれらのエフェクトを生成するのはかなり時間がかかるため、これは伝統的に事前にレンダリングされたフレームごとのアニメーションで行われます。Caustics Generatorなど、非営利目的で使用するための無料バージョンが用意されているなど、コースティクスアニメーションフレームを生成するツールがあります。また、私が言及したプロ版のツールよりも大幅に安い価格で購入できる既製のものもあります。

苛性効果は通常、水中の地形または水中の表面に軽いクッキーとして適用される効果でもあることに注意してください。つまり、水面を見下ろしながら水面に置くことは、通常、水がどのように見えるかではありません。


非常に興味深いことです。このジェネレーターも見ていきます(ただし、理解できればシェーダーバリアントを試してみます...)
morpheus05

4

これは、ボロノイグラフから生成できるテクスチャのように見えます。例:

ここに画像の説明を入力してください

ポイントを移動することで、グラフを小さくスムーズに調整できます。各フレームでグラフを再描画するのは非常にコストがかかるため、アニメーションを事前にレンダリングすることをお勧めします。


4
過去にシェーダーでこのようにコースティクスを実際にレンダリングしました。必ずしも思ったほど高価ではありません(ここでは、WebGLシェーダーでボロノイエッジをリアルタイムでレンダリングする例を示します)。
DMGregory

うーん、それはとてもいいです。いくつかのテレインジェネレーターがあり、それらは非常に便利です。
FacticiusVir

0

最下部のテクスチャレイヤーと、最上部に反射するための2つの半透明テクスチャを含むオールドスクール方式があります。

ずっと行きたいので、水がクローン波でいっぱいに見えたり、青みがかったスープのフローマップを表示したくない場合は、目標を達成する必要があります。

https://steamcdn-a.akamaihd.net/apps/valve/2010/siggraph2010_vlachos_waterflow.pdf


3
リンクは役立つかもしれませんが、良い答えは決してありません。これらの方法の両方を拡張できますか?どのように実装しますか?
ベイランクール

最初の方法は、基本的に水をアニメーション化するために使用される非常に古い方法です。UVW座標が選択した方向にシフトされるベースレイヤーの水テクスチャを取得します。次に、別の方向にシフトする法線マップ/バンプマップを追加して適用します。うまくいけば、小さな川に納得できます。ただし、大きな水域では非常に制限されます。波に似たものはすべてモアレ効果を得るためです。リンクでは、フローマップの使用について説明しました。
ピカ

ここで追加した内容で質問を改善するには、編集機能を使用してください:)コメントではなく、投稿で回答を探すために人々が使用されます。
ベイランクール
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.