回答:
フレームごとにウォーターフォールのメッシュを動的に再生成せずにこれを引き出すことができるかどうかを確認したかったのです。結局のところ、方法があります。: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;
オブジェクトの衝突時にウォーターフォールメッシュを変形して、必要なコライダーパターンに一致させることができます。
より簡単で正確ですが、パフォーマンスが高くなります-パーティクルシステムを使用-コライダーを使用してパーティクルシステムを作成し、すべてのパーティクルを水滴として使用します。しかし、デフォルトのスプライトがあり、パーティクル数が少なく、大きすぎる場合は、少し奇妙に見えます。しかし、それはパフォーマンスが重いので、ゲームで分子シミュレーションをしたくありません。
私は1で行きます。
良いパフォーマンスの簡単な解決策はありません。