XNAのパレットに基づいてテクスチャに色を付けるための良い方法は何ですか?


8

私はXNAを使用して、特にNESをガイドとして使用して、8ビットゲームのようなゲームに取り組んでいます。

NESには非常に特定のパレットがあり、各スプライトはそのパレットから最大4色を使用できます。これをどのようにエミュレートできますか?私がこれを達成する現在の方法は、GPUに渡す色の配列へのインデックスとして機能する定義された値を持つテクスチャーを持っていることです。これより良い方法があるに違いないと思いますが、おそらくこれが最善の方法でしょうか?

パレットを動的に変更できるようにしたいので、すべてのスプライトを適切な色で描画することを確認したくありません。また、CPUを使用してテクスチャを直接変更したくない場合もあります。

回答:


7

あなたがやっていることは大丈夫だと思います。

4つを超える色がある場合、依存テクスチャの読み取りを行うことをお勧めします。テクスチャの値を使用して色の配列を検索する代わりに(これらをシェーダーパラメーターとして渡すと想定しています)、それを使用して検索できます。パレットを含む別の1Dテクスチャの色。

ただし、これはパフォーマンスに影響を及ぼします。PS2.0に制限されると思います。

(すべてのスプライトのパレットを切り替える必要があり、余分なバッチがすべてパフォーマンスを低下させている場合は、他にもいくつかの卑劣な最適化が考えられます。しかし、NESのようなゲームではそうではないと思います。)

あなたの状況で役立つかもしれないと思うのは、XNAコンテンツパイプラインを使用して、簡単に編集可能なカラーバージョンのスプライトを取得し、4色のみを使用することを確認し、4レベルのグレースケールを持つテクスチャーに変換することです(シェーダ)、およびおそらくテクスチャと一緒に元のカラーパレットも出力します。

コンテンツパイプラインのクリエーターズクラブのサンプルから始めるとよいでしょう。


1
+1コンテンツパイプラインは時々あなたの友達になることができます。あなたの利点にそれを使用してください。
マイケルコールマン

1

スプライトの各色の1つである最大4つのオブジェクトを含むことができる複合クラスを作成し、それを描画されるスプライトに組み合わせるのは遅くなりますか?したがって、各スプライトは最大4つのスプライトを組み合わせて描画されます。

次に、そのクラスを介して1色を変更すると、スプライト全体が変更されます。

(私はXNAを実行していませんが、これによりいくつかのアイデアが浮かぶかもしれません。)


1

メモリのパフォーマンスをまったく気にしない場合は、スプライトを圧縮せずに保存して、色0のピクセルが純粋な赤、1が純粋な緑、2が純粋な青、3が純粋なアルファになるようにします。

スプライトをレンダリングするときは、色0、1、2、3に対応する4つのベクトルで構成されるマトリックスピクセルシェーダー定数を設定します。ピクセルシェーダーで、次のコードを実行してスプライトテクセルの色を変更します。

float4 unpaletted = tex2D( texture, uv );
float4 paletted = mul( unpaletted, paletteMatrix );

これは、ピクセルがカラー0の場合、純粋な赤であり、最終的に次のようになるため機能します。

1 * palette[0] + 0 * palette[1] + 0 * palette[2] + 0 * palette[3]

または

1 * palette[0]

同じことがカラー1、2、3にも当てはまります。

メモリパフォーマンスを重視する場合は、必ずNESパレットを256x1 RGB非圧縮テクスチャとして保存し、テクスチャフィルタリングを最近傍に設定し、スプライトを非圧縮8ビットシングルチャネルテクスチャとして保存し、次のようなシェーダーコードを実行します。 :

float palette_index = tex2D( texture, uv );
float4 color = tex1D( palette, palette_index * 255 );
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.