サークル選択をマージすることでこの効果をどのように実現するか知りたい 説明する画像は次のとおりです。
基本的に私はこの効果を探しています:
サークルのマージ効果はどのように達成できますか?この効果に関する説明は見つかりませんでした。これらのテクスチャを投影するために、デカールシステムを開発できることは知っていますが、マージエフェクトを作成する方法はわかりません。
可能であれば、純粋なシェーダーソリューションを探しています。
サークル選択をマージすることでこの効果をどのように実現するか知りたい 説明する画像は次のとおりです。
基本的に私はこの効果を探しています:
サークルのマージ効果はどのように達成できますか?この効果に関する説明は見つかりませんでした。これらのテクスチャを投影するために、デカールシステムを開発できることは知っていますが、マージエフェクトを作成する方法はわかりません。
可能であれば、純粋なシェーダーソリューションを探しています。
回答:
あなたができるいくつかのトリックがあります:
Z-バッファ
他のすべてのオブジェクトをレンダリングした後、各ユニットに対して、最大Z値の小さいサイズの透明な円をレンダリングします。次に、選択円のデカールを地面にレンダリングします。これらはZオーダーで下にあるため、ユニットの下にある場合は破棄されます。
完全に透明であるということは、円がZバッファー(最大Z値)にのみ書き込まれることを意味します。デカールをレンダリングすると、Zバッファー値に対してテストされ、テストに合格すると、レンダリングされます(これは円の外側でのみ発生します)
ステンシル
前のアプローチと同じですが、今回はステンシルバッファを使用します。ステンシル値を持つユニットの小さな円をレンダリングしてから、選択デカールをレンダリングします。ステンシルを設定して、ステンシル値を持つ要素をすべて破棄します。
たとえば、デカールレンダリングピクセルシェーダーで他のデカールとの交差があるかどうかを確認し、ある場合はピクセルを殺すことができます。この種の円形のステッカーには非常に効率的です。
地面にある青い円のことですか?
これを行うためのよりスマートな方法があるかもしれませんが、これを行う方法の例として私のソリューションを検討してください。画面サイズの別の空のテクスチャに円をレンダリングします。この時点で、必要に応じてそれらをブレンドできます。必要に応じて、フルカラーまたは指定されたピクセルに円が存在するという情報だけを書き込むことができます。ただし、Zテスト効果が必要な場合は、書き込むピクセルごとに深度情報が明確に必要です。
前のステップの後にテレインをレンダリングする場合、ピクセルシェーダーのスクリーン座標をUVとして使用して、以前に作成したテクスチャをサンプリングできます。これで、円が地形の特定のピクセルに投影されるべきか、されないべきかがわかります。ただし、この方法ではZテストが無効になったように動作するため、地形は円を非表示にできません。地形の背後にある円を非表示にするには、円を地形テクスチャとブレンドする前に深度テストを実行します。小さなバイアスを使用して、地形の少し下にある円のレンダリングを有効にすることができますが、それでもレンダリングしたいでしょう。
編集:マージされた円の効果を得るために必要なことは次のとおりです:個別のテクスチャにレンダリングする場合、新しい円をレンダリングしようとしている場所に円が既にレンダリングされているかどうかを確認する必要があります。(テクスチャに値があるかどうかを確認します)その場合、このピクセルを消去します。これにより、2つ以上の円が重なったときに「アウトライン」の効果が得られます。これが正しく機能するためには、境界線ではなく、円の内側に対してのみこのテストを行う必要があります。したがって、円をレンダリングするときは、特定の値を出力テクスチャに書き込みます。これは、内部が円であることを示します。次に、内側の円に何もレンダリングする必要がなく、うまくいくはずです。
編集2:単純な赤/緑の例:ピクセルをレンダリングする前に、このピクセルがまだ緑でないかどうかを確認します。もしそうなら、レンダリングしないでください。これでうまくいきます。実際、テクスチャへの書き込み中に円の外側/内側に赤/緑を使用し、地形のレンダリング中にこれらの値を読み取り、それらを目的の色に変換することもできます。
万が一私の回答が抽象的すぎる場合はお知らせください。
いくつかのオプションがあります。一般的な方法として、ステンシルバッファは、例で円が重なっているアウトラインのように、特定の描画をマスクする必要がある場合に非常に便利です。
この場合、ステンシルバッファがなくても同じように簡単にできると思います。深度バッファを使用して、円が重なるアウトラインを削除できます。アイデアは、円の内部を深さバッファーだけに描画し(内部を表示したくないため)、アウトラインを描画することです。このように、別の円と重なるアウトラインの部分は、深度テストによって削除されます。
唯一の注意点は、深度の戦いに注意する必要があるということです。小さなオフセットを使用して、輪郭が実際に内部の背後にあることを確認し、深度テストで除去することができます。代わりに使用することです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);
これらのデカールがディスクとして描かれている場合、頭のてっぺんから離れて、各円と他の円との交差をテストし、交差点を配列に入れます。次に、交差点内にない円弧を描きます。ただし、これはシェーダーソリューションではありません。
ここにステンシルが必要です。最初のパスでは、円がステンシルバッファーにレンダリングされます。2番目のパスは、ステンシルバッファーが変更されていない場所に表示されるアウトラインをレンダリングします。 2番目のパスでは、最初のパスよりも大きいジオメトリを使用する必要があります。この場合、単純な線形スカラーで十分です。
ここでアウトラインを描画するための解決策は必要以上のものです(シェーダーはすべてのメッシュエッジを完全なクワッドに変換するため)が、このアプローチに従います:元のモデルをステンシルバッファーに描画して、ステンシルバッファはまだ0です。