Apa metode yang baik untuk mewarnai tekstur berdasarkan palet di XNA?


8

Saya telah mencoba untuk mengerjakan game dengan tampilan game 8-bit menggunakan XNA, khususnya menggunakan NES sebagai panduan.

SEN memiliki palet yang sangat spesifik dan setiap sprite dapat menggunakan hingga 4 warna dari palet itu. Bagaimana saya bisa meniru ini? Cara saya saat ini mencapai hal ini adalah saya memiliki tekstur dengan nilai-nilai yang ditetapkan yang bertindak sebagai indeks untuk berbagai warna yang saya berikan ke GPU. Saya membayangkan harus ada cara yang lebih baik dari ini, tetapi mungkin ini cara terbaik?

Saya tidak ingin memastikan saya menggambar setiap sprite dengan warna yang tepat karena saya ingin dapat mengubah palet secara dinamis. Saya juga lebih suka untuk tidak mengubah tekstur secara langsung menggunakan CPU.

Jawaban:


7

Saya pikir apa yang Anda lakukan baik-baik saja.

Jika Anda memiliki lebih dari empat warna, saya mungkin menyarankan untuk melakukan pembacaan tekstur dependen: Alih-alih menggunakan nilai tekstur untuk mencari array warna (Saya menganggap Anda melewatkan ini sebagai parameter shader), Anda dapat menggunakannya untuk mencari warna dalam tekstur 1D lain yang mengandung palet Anda.

Tetapi ini memiliki beberapa implikasi kinerja - dan saya pikir itu membatasi Anda untuk PS 2.0.

(Ada beberapa optimisasi licik lainnya yang mungkin terjadi jika Anda harus mengganti palet setiap sprite dan semua batch tambahan membunuh kinerja. Tapi saya membayangkan dalam permainan seperti NES, ini bukan masalahnya.)

Saya pikir apa yang mungkin berguna dalam situasi Anda adalah menggunakan pipa konten XNA untuk mengambil versi warna sprite yang mudah diedit, periksa hanya menggunakan empat warna, ubah menjadi tekstur dengan empat tingkat skala abu-abu (dapat digunakan oleh Anda shader), dan mungkin juga menampilkan palet warna asli di sepanjang tekstur.

Sampel Creators Club untuk saluran konten mungkin merupakan tempat yang baik untuk memulai.


1
+1 Pipa konten terkadang bisa menjadi teman Anda. Gunakan untuk keuntungan Anda.
Michael Coleman

1

Apakah lambat untuk membuat kelas komposit yang dapat berisi hingga 4 objek yang merupakan salah satu dari masing-masing warna untuk sprite dan menggabungkannya ke dalam sprite yang digambar. Jadi masing-masing sprite adalah gabungan hingga 4 sprite yang digabungkan dan kemudian digambar.

Kemudian Anda bisa mengubah 1 warna melalui kelas itu dan seluruh sprite akan berubah.

(perhatikan, saya belum melakukan XNA tetapi ini mungkin memicu beberapa ide dengan Anda.)


1

Jika Anda sama sekali tidak peduli dengan kinerja memori, Anda dapat menyimpan sprite Anda tanpa kompresi sehingga piksel dengan warna 0 berwarna merah murni, 1 berwarna hijau murni, 2 berwarna biru murni, dan 3 adalah alpha murni.

Saat hendak membuat sprite, tetapkan konstanta pixel shader matriks yang terbuat dari empat vektor yang sesuai dengan warna 0, 1, 2, 3. Dalam pixel shader, jalankan kode berikut untuk mewarnai ulang sprite texel:

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

Ini berfungsi karena ketika sebuah pixel berwarna 0, itu adalah merah murni, dan akhirnya akan menjadi

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

atau

1 * palette[0]

dan hal yang sama berlaku untuk warna 1, 2, dan 3.

Jika Anda peduli dengan kinerja memori, maka simpan palet NES Anda sebagai 256x1 RGB tekstur terkompresi, atur penyaringan tekstur ke tetangga terdekat, simpan sprite Anda sebagai tekstur 8-channel single-channel terkompresi, dan lakukan kode shader seperti ini :

float palette_index = tex2D( texture, uv );
float4 color = tex1D( palette, palette_index * 255 );
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.