2D物理ウォーターフォールを作成する方法


8

以下の最初の画像に似たウォーターフォールを作成しようとしています(達成したいことについては、このビデオをチェックしてください)。これは、コース上にコライダーがあるオブジェクトやその周りを移動できるようにするためのものです(下の2番目の画像)。リンクされたウォーターフォールは3dですが、2dの実装に興味があります。

オブジェクトは動的であり、一部は頻繁に移動するため、滝はすべてのフレームを再形成する必要があることに注意してください。オブジェクトはゆっくりと移動し、別の位置に移動するか回転します。これはどのように行うことができますか?

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

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

回答:


13

フレームごとにウォーターフォールのメッシュを動的に再生成せずにこれを引き出すことができるかどうかを確認したかったのです。結局のところ、方法があります。:D

滝の流れのアニメーション

ウォーターフォールをブロックできる各オブジェクト(WaterCatcher私のプロトタイプにスクリプトが含まれているオブジェクト)には、その周囲を囲むアウトラインメッシュがあります。(これは、コライダーの形状を使用して事前に自動生成できます)

このアウトラインメッシュは、オブジェクトに沿って流れる水をレンダリングします。シェーダーを使用しclipて、オブジェクトの下にある部分を除外します。また、オブジェクトに滝が落ちて左または右に流れる左右の「キャッチ」ポイントも追跡するためclip、右の滝の左側と左側の滝の右側にある部分を除外できます。

ウォータースキンメッシュを示すアニメーション

次に、垂直フォールは、基本的なクワッドプリミティブであり、適切な長さに伸ばされます。別のシェーダーを使用して滝のテクスチャーを滝の上にスクロールし、上端と下端でフェードアウトします。次に、インパクトポイントで発泡粒子システムの上に重ねて、ブレンドをカバーします。

これがクローズアップですので、構成部品を見ることができます。

まだ滝効果のクローズアップ

一番上には、物事を始めるための「ルート」滝があります。各フレームは、すべてのUpdate()スクリプトが実行されて移動した後、CircleCast下向きに発射し、水が何かに当たったかどうかを確認します。にヒットするWaterCatcherと、ヒットポイントの下流にあるウォータースキンを表示するように指示します。

ヒット法線を使用して「下流」を決定します。垂直に非常に近い場合、または流入する滝が両方向に傾斜するエッジにまたがる場合は、左と右の両方に波及します。

それぞれにWaterCatcher独自の左と右の滝があり、その方向にこぼれている場合、それを有効にして遠端に配置します。それ以外の場合は非表示のままです。火が順番にこれらの滝CircleCast下りSがものを見つけるために、彼らは、というように上にこぼれます...

プロトタイプにはまだ改善できるいくつかの視覚的な不具合があります。オブジェクトに沿った水の流れは、アニメーション化するのではなく、一度にすべてポップします。流れのルールは、少し余分な許容差またはヒステリシスを使用するため、簡単に切断されません。回転オブジェクト。これらはかなり解決可能な問題だと思います。

ケニーによる背景、岩、回転プラットフォームテクスチャ


ウォーターキャッチャーフラグメントシェーダーで使用するトリックは次のとおりです。

// My wraparound geometry is build so the "x+" UV direction
// points "outward" from the object.
// Using derivatives, I can turn this into a vector in screen space.
// We'll use this below to clip out water hanging off the bottom.
float2 outward = float2(ddx(i.uv.x), ddy(i.uv.x));

// i.worldX is the worldspace x position of this fragment
// (interpolated from the vertex shader)

// _LeftX is a material property representing the worldspace x coordinate
// of the rightmost water flow that's spilling left,
// and _RightX the wold x of the leftmost water flow that's spilling right.
float left = _LeftX - i.worldX;   // +ve if we're to the left of a left spill.
float right = i.worldX - _RightX; // +ve if we're to the right of a right spill.

float limit = max(left, right); // +ve if we're in the path of either flow.

// If the "outward" vector is pointing down, make this negative.
limit = min(limit, outward.y + 0.001f);

// If any of the conditions above make limit <= 0, abort this fragment.
clip(limit);

// Otherwise, scroll the water texture!
// Counter-clockwise if we're in the left flow, clockwise otherwise.
i.uv.y -= sign(left) * _Time.y;

これは素晴らしい。コミュニティが改善に貢献できるように、ここまたはGitHubでコードを提供する計画はありますか?そうでない場合は、そうすることを検討してください。
封じ込め

現在そのような計画はありません。上記の画像は、そのような用途に適したスタンドアロンパッケージではなく、迅速かつハックな概念実証で作成されました。それを複製する手が必要な場合はお知らせください。必要なものをご案内します。
DMGregory

私は泡の粒子を作ることができましたが、ウォーターシェーダーを作成し、次にシェイプの周りにウォーターシェーダーをクリッピングする手助けが必要です(WaterCatcher)。
封じ込め

クリッピングシェーダーの動作を示すシェーダーコードのスニペットを追加しました。
DMGregory

@DMGregory WoooW !!! 申し訳ありませんが、しばらくここにいません。他のいくつかのものに取り組んでいました。私は今あなたの解決策を進めています
OnlyCodeMatters '

1
  1. オブジェクトの衝突時にウォーターフォールメッシュを変形して、必要なコライダーパターンに一致させることができます。

  2. より簡単で正確ですが、パフォーマンスが高くなります-パーティクルシステムを使用-コライダーを使用してパーティクルシステムを作成し、すべてのパーティクルを水滴として使用します。しかし、デフォルトのスプライトがあり、パーティクル数が少なく、大きすぎる場合は、少し奇妙に見えます。しかし、それはパフォーマンスが重いので、ゲームで分子シミュレーションをしたくありません。

私は1で行きます。

  • しかし、 メッシュ変形CPU-遅いですが、うまくいくかもしれません。
  • 私はこれを達成するためにシェーダーを使用します- ウォーターシェーダーの例 -メッシュは他のメッシュと衝突するような効果があり、以前の方法よりも高速です。メッシュを作成して、いくつかの投影された形状でレンダリングを停止することは可能だと思います。これは、通常のウォーターシェーダーに加える必要がある変更です。シェーダーに慣れていない場合、達成するのは複雑です。

良いパフォーマンスの簡単な解決策はありません。

パーティクルシステムの結果:( 値を変更するには、約3〜4秒待つ必要があり、時間がかかります) パーティクルシステムの衝突結果


ポイント1に代わるものですが、少し複雑かもしれませんが、ポイント/球のコライダーをドロップし、物理を遵守する独自の「パーティクル」システムがあります。そして、それらのポイントに基づいてメッシュを「単純に」生成します。ラインレンダラーの動作方法のほとんど。解決する必要があるのは、スクリーンショットのようにコライダーを打ったときにポイントを2方向に分割する方法だけです。しかし、それは難しい必要があるとは思わないでください。または、ポイントを静的に配置して、それらの間に線を引くこともできます。かなりのシェーダーが必要です。
Sidar 2018年

@サイダーうん、面白いアプローチ。その方法の1つは、複数のトレイルレンダラーを作成し、それらを分割ポイントから相対的に移動することです。そして、いくつかのコライダーコンポーネントを介して衝突をチェックします-しかし、それは単に回避策です。
率直な月_Max_

いずれにせよ、OPが手動で設定したくない場合は、データを動的または静的にベイクする必要があります。コリジョンが有効になっている通常のパーティクルシステムを使用して、ポイント間を近接させて四角形のストリップを描画できるかどうかを考えます。このため、粒子数を多くする必要はありません。
Sidar 2018年


粒子ごとにそうではありませんか?あなたがしようとしているスタイルによってはかなりうまくいくと思います。
Sidar 2018年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.