ユニット選択サークルをマージする方法は?


16

サークル選択をマージすることでこの効果をどのように実現するか知りたい 説明する画像は次のとおりです。

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

基本的に私はこの効果を探しています:

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

サークルのマージ効果はどのように達成できますか?この効果に関する説明は見つかりませんでした。これらのテクスチャを投影するために、デカールシステムを開発できることは知っていますが、マージエフェクトを作成する方法はわかりません。

可能であれば、純粋なシェーダーソリューションを探しています。


「マージ効果」とはどういう意味ですか?
ウォンドラ14

もちろん、スクリーンショットの右上の文字を見ると、デカールは互いに交差していませんが、左側の2つは青い円を横切って結合されています。効果を示す新しいスクリーンショットを追加しました。
MaT 14

シェーダーソリューションを主張していますか?そうでない場合は、最後の写真で解決しました。
ウォンドラ14

最後のスクリーンショットは、私がターゲットにしている効果のみを示しています。最終結果は、前のスクリーンショットのようになります。
MaT 14

1
はい、私は同意します、彼らはテクスチャでメッシュ円を動的に構築し、メッシュをカットしてそれらをマージすると思います。それは良い解決策でもありますが、私はあなたができる効果の面でより制限されていると思います。
MaT 14

回答:


8

あなたができるいくつかのトリックがあります:

Z-バッファ

他のすべてのオブジェクトをレンダリングした後、各ユニットに対して、最大Z値の小さいサイズの透明な円をレンダリングします。次に、選択円のデカールを地面にレンダリングします。これらはZオーダーで下にあるため、ユニットの下にある場合は破棄されます。

完全に透明であるということは、円がZバッファー(最大Z値)にのみ書き込まれることを意味します。デカールをレンダリングすると、Zバッファー値に対してテストされ、テストに合格すると、レンダリングされます(これは円の外側でのみ発生します)

ステンシル

前のアプローチと同じですが、今回はステンシルバッファを使用します。ステンシル値を持つユニットの小さな円をレンダリングしてから、選択デカールをレンダリングします。ステンシルを設定して、ステンシル値を持つ要素をすべて破棄します。


Z-Bufferテクニックは興味深いものですが、最初の透明な円が地面のデカールをクリップする方法がわかりません。
MaT 14

0

たとえば、デカールレンダリングピクセルシェーダーで他のデカールとの交差があるかどうかを確認し、ある場合はピクセルを殺すことができます。この種の円形のステッカーには非常に効率的です。


1
私はあなたが答えから一部をスキップしたと仮定します-すべての円の位置と半径をシェーダーに渡します。
Kromsterによると、サポートモニカ14

@Krom OPがソリューションに関心を示している場合、詳細をお知らせします。
JarkkoL 14

0

地面にある青い円のことですか?

これを行うためのよりスマートな方法があるかもしれませんが、これを行う方法の例として私のソリューションを検討してください。画面サイズの別の空のテクスチャに円をレンダリングします。この時点で、必要に応じてそれらをブレンドできます。必要に応じて、フルカラーまたは指定されたピクセルに円が存在するという情報だけを書き込むことができます。ただし、Zテスト効果が必要な場合は、書き込むピクセルごとに深度情報が明確に必要です。

前のステップの後にテレインをレンダリングする場合、ピクセルシェーダーのスクリーン座標をUVとして使用して、以前に作成したテクスチャをサンプリングできます。これで、円が地形の特定のピクセルに投影されるべきか、されないべきかがわかります。ただし、この方法ではZテストが無効になったように動作するため、地形は円を非表示にできません。地形の背後にある円を非表示にするには、円を地形テクスチャとブレンドする前に深度テストを実行します。小さなバイアスを使用して、地形の少し下にある円のレンダリングを有効にすることができますが、それでもレンダリングしたいでしょう。


編集:マージされた円の効果を得るために必要なことは次のとおりです:個別のテクスチャにレンダリングする場合、新しい円をレンダリングしようとしている場所に円が既にレンダリングされているかどうかを確認する必要があります。(テクスチャに値があるかどうかを確認します)その場合、このピクセルを消去します。これにより、2つ以上の円が重なったときに「アウトライン」の効果が得られます。これが正しく機能するためには、境界線ではなく、円の内側に対してのみこのテストを行う必要があります。したがって、円をレンダリングするときは、特定の値を出力テクスチャに書き込みます。これは、内部が円であることを示します。次に、内側の円に何もレンダリングする必要がなく、うまくいくはずです。

編集2:単純な赤/緑の例:ピクセルをレンダリングする前に、このピクセルがまだ緑でないかどうかを確認します。もしそうなら、レンダリングしないでください。これでうまくいきます。実際、テクスチャへの書き込み中に円の外側/内側に赤/緑を使用し、地形のレンダリング中にこれらの値を読み取り、それらを目的の色に変換することもできます。

万が一私の回答が抽象的すぎる場合はお知らせください。


私は一般的なアイデアを取得しますが、あなたが言うように、マージされたサークルに関して私にとって抽象化するのは少しです:)
MaT

0

いくつかのオプションがあります。一般的な方法として、ステンシルバッファは、例で円が重なっているアウトラインのように、特定の描画をマスクする必要がある場合に非常に便利です。

この場合、ステンシルバッファがなくても同じように簡単にできると思います。深度バッファを使用して、円が重なるアウトラインを削除できます。アイデアは、円の内部を深さバッファーだけに描画し(内部を表示したくないため)、アウトラインを描画することです。このように、別の円と重なるアウトラインの部分は、深度テストによって削除されます。

唯一の注意点は、深度の戦いに注意する必要があるということです。小さなオフセットを使用して、輪郭が実際に内部の背後にあることを確認し、深度テストで除去することができます。代わりに使用することですglPolygonOffset()です。

xy平面に平行な2つの円があり、中心が(x1、y1、z)と(x2、y2、z)にあるとします。そして、これらの描画関数があります:

// Draw interior part of circle, shown in green in the schematic in the question.
drawInterior(x, y, z);

// Draw outline of circle, shown in red in the schematic in the question.
drawOutline(x, y, z);

描画の順序は次のようになりますdeltaが、小さなオフセットがあります。

glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
drawInterior(x1, y1, z + delta);
drawInterior(x2, y2, z + delta);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
drawOutline(x1, y1, z);
drawOutline(x2, y2, z);

0

これらのデカールがディスクとして描かれている場合、頭のてっぺんから離れて、各円と他の円との交差をテストし、交差点を配列に入れます。次に、交差点内にない円弧を描きます。ただし、これはシェーダーソリューションではありません。


ええ、私もそれについて考えました:)しかし、あなたが言ったように、それはシェーダーソリューションではなく、それは非常に一般的なソリューションではありません。しかし、ありがとう!
MaT

それはかなり曖昧な説明です
-Kromsterはサポートモニカを言う14

0

ここにステンシルが必要です。最初のパスでは、円がステンシルバッファーにレンダリングされます。2番目のパスは、ステンシルバッファーが変更されていない場所に表示されるアウトラインをレンダリングします 2番目のパスでは、最初のパスよりも大きいジオメトリを使用する必要があります。この場合、単純な線形スカラーで十分です。

ここでアウトラインを描画するための解決策は必要以上のものです(シェーダーはすべてのメッシュエッジを完全なクワッドに変換するため)が、このアプローチに従います:元のモデルをステンシルバッファーに描画して、ステンシルバッファはまだ0です。


ありがとう!したがって、最初に可視部分を描画する代わりに、透明な円をステンシルにレンダリングすることから始めます。しかし、丸い透明な円をどのようにレンダリングしますか?画像の一部をステンシルにレンダリングするように制限することはできません。ステンシルにレンダリングすると、すべてがそこに行きます、私は正しいですか?
Doodlemeat

はい、それが2番目のパス(表示部分)が大きくスケーリングされる理由です。そのため、その境界はステンシルバッファーより大きくなります。2番目のパスで頂点スカラーを適用する必要があります(アウトラインシェーダーを見てください。それらのほとんどは、私が参照しているより単純なスカラーを使用しています)。色が透明な場合、ステンシルバッファを変更することもできません。この場合、おそらく2番目のテクスチャマスクが必要になります。または、代わりに距離を計算して円を決定できます。コードを提供するには、数時間とUnityにアクセスする必要があります。
Draco18sは、

うーん、ステンシルで黒が0になり、白が1になるように、最初のパスでステンシルバッファーに書き込むためだけに黒/白のイメージを作成するのはどうでしょうか。それも可能ですか?
Doodlemeat

これが、2番目のテクスチャマスクの意味です。私はそれがうまくいくと確信しています。Unityを目の前に置いていないと実際には検証できません。
Draco18sは、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.