回答:
これを実行する最も簡単な方法(パフォーマンスに本当に縛られていない限り、おそらく最良の方法です)は、スプライトのコピーを2つ持つことです。
「ファット」バージョンを使用してオブジェクト全体を描画し、その上に通常バージョンを描画します。
「脂肪」バージョンを白にすることにより、SpriteBatchの組み込みのカラーティントを使用して、選択色を動的に変更できます。
「ファット」バージョンを生成するには、元のスプライトを自動的に取得し、アルファチャンネルを読み取り、元の画像の最大アルファチャンネルをサンプリングして新しいアルファチャンネルを作成できるContent Pipeline Extensionを作成することをお勧めします。設定RGB =(1,1,1)。
スプライトにはすべて、アウトラインを追加するのに十分な透明な境界線があることを確認する必要があります(コンテンツプロセッサでこれを確認し、必要に応じてスペースを空けることもできます)。
スプライトが数個しかない場合は、適切な画像エディター(GIMP、Photoshop)を使用して手動で実行できます:アルファチャンネルから選択、展開、選択からアルファ、カラーチャンネルを白で塗りつぶします。
最初に各オブジェクトを単一のスプライトに描画する必要があると思います。次に、スプライトのエッジを検出するためにシェーダーを作成し、エッジが見つかったところにピクセルを描画する必要があると思います。これを行うには、既にいくつかのシェーダーが存在している必要があり、使用または移植することができます。
要件に応じて、スプライトのアウトラインをオンデマンドで作成することも効果的です。私はあなたのスプライトに透明性があり、単なる長方形ではなく不規則な形であると仮定しています(これではうまくいきますが、輪郭の長方形は些細なはずです)。
when selected:
outline = new sprite canvas of appropriate size
for sprite in object:
# use larger numbers for thicker outlines
for x in (-1, 0, 1) and y in (-1, 0, 1):
render sprite mask into canvas at x,y with desired color
描画するたびにこれを行う必要はないことに注意してください(可能であれば)が、スプライトを切り替えるときに新しいアウトラインスプライトを作成するだけです。
最も単純なブルートフォースアプローチは、各スプライトの2つのコピーを作成することです。通常のコピーと強調表示されたコピーです。次に、強調表示されたらそれらを交換します。
メモリに余裕がある場合は、それ以上複雑にする必要はありません。さらに、アーティストは、強調表示されたときに外観を完全に制御できるため、アウトラインやその他の任意の操作を実行できます。
スプライトごとに、ベーススプライトのアウトラインである別のスプライトもあります。アウトラインオブジェクトを描画するときは、ベーススプライトを描画し、結合レンダリングのマスクを作成してから、マスクを除くアウトラインスプライトを描画します。
トレードオフが異なるいくつかの異なるソリューション。
最も簡単:フラットカラーを複数回使用してオブジェクトをレンダリングし、位置(左、上、下、右などのオフセット)を揺らします。これにより、その上にレンダリングするもののアウトラインバージョンが作成されますが、パフォーマンスコストが発生します。多くの余分なレンダリングなしで太い境界線を考慮します。4xでは、1ピクセルまたは2ピクセルの境界線で問題ありません。
最速:テクスチャを前処理して、既に境界線が付いているコピー、または単に境界線であるコピー、またはシェーダーでカラー化できるフラットグレースケール8ビットマスクをコピーします。これはおそらくメモリを犠牲にして高速になります。
ベスト:私の意見ですが、オブジェクトの符号付き距離フィールド(SDF)表現を生成するのが最善の解決策となるでしょう。これらのテクスチャは、ソーステクスチャよりはるかに小さくても、有用なデータをキャプチャできます。基本的に、各ピクセルは、生成に使用したオブジェクトからの距離をエンコードします。このデータを手に入れると、グローからアウトラインまで、あらゆる種類のエフェクトを作成できます。境界線のサイズや色などが変更される可能性がありますが、依然として比較的安価なシェーダーであり、余分な描画は1つだけです。欠点は、ツーリングと前処理です。
効率がよくわかりませんが、一番簡単な方法は、最初に選択したい色でスプライトの大きなバージョンを描画することです。その上にスプライトを描画します。最初のスプライトのエッジのみが表示され、選択の効果が得られます。
編集:ただし、コメントからわかるように、これは良い考えではありません。
私はスプライトを拡大することに同意します。最も簡単なルートであり、特にこの目的のために追加のスプライトを作成することなく、任意のスプライトの選択に適用できます。