Bagaimana mewarnai bagian-bagian tertentu dari model - seperti game RTS yang memiliki warna tim?

16

Saya perlu mengimplementasikan sesuatu yang kita lihat di game RTS: warna tim. Pada dasarnya, saya mencari cara untuk mewarnai bagian-bagian tertentu dari model. Bagaimana saya mencapai ini? Saya tidak tahu harus mulai dari mana. Apakah saya perlu melakukan beberapa penyesuaian pada model 3d terlebih dahulu?

rFaktor
sumber

Jawaban:

18

Cara saya akan melakukan ini didasarkan pada peta tekstur yang Anda terapkan ke unit. Untuk sebagian besar barang Anda akan memiliki beberapa daerah yang perlu diwarnai dan beberapa yang tidak. Jadi misalnya, Anda mungkin memiliki tangki normal tetapi Anda hanya ingin mengubah warna beberapa bendera.

Jika Anda mengecat tekstur seolah-olah daerah berwarna berwarna abu-abu, Anda kemudian dapat menggunakan saluran alpha untuk menentukan daerah mana yang perlu diwarnai.

Jadi di shader Anda, Anda bisa pergi (dengan cara paling sederhana):

float3 finalColor;
if (colorFromTex.a > 0)
 finalColor = colorFromTex.rgb;
else
 finalColor = colorFromTex.rgb*myTintColor.rgb;

Namun itu tidak optimal karena Anda akan mengalami transisi yang sulit dan memiliki cabang di shader Anda. Sebaliknya lebih baik pergi:

float3 finalColor = lerp(colorFromTex.rgb, 
    colorFromTex.rgb*myTintColor.rgb, colorFromTex.a);
Lucas
sumber
Apakah Anda tahu cara mendapatkan shader DirectX ke model 3d dalam 3ds Max? Ketika saya mencoba mengatur bahan dengan jenis shader dan mengatur shader ke ReplaceColor.fx dan mengekspor model, hasilnya adalah Error 1 Missing asset "C:\Users\Kai\AppData\Local\Temp\fbx.shader.temp.1064.2756\ReplaceColor.fx". Saya tidak mengerti bagaimana saya bisa memperbaikinya.
rFactor
Apakah itu ketika Anda memuatnya? Tampaknya aneh bahwa jalur di FBX akan menunjuk ke folder temp. Apakah file itu ada? Saya tidak terlalu familiar dengan mengekspor FBX dari 3ds Max tapi mungkin Anda perlu mengedit file (atau mengatur opsi) untuk membuat jalur relatif.
Lucas
Teknik yang bagus, tetapi jika Anda menggunakan saluran alpha untuk menunjukkan "tintability", jangan lupa untuk mereset komponen alpha di finalColor Anda.
charstar
3

Satu teknik adalah memiliki dua set tekstur untuk masing-masing model - satu merah, yang lain biru. Kemudian tergantung pada tim mana karakter ditugaskan untuk Anda menerapkan set tekstur itu.

Jelas ini hanya bekerja jika Anda hanya memiliki dua tim. Meskipun Anda mungkin lolos dengan lebih dari dua, itu mulai menjadi tidak efisien.

Cara lain adalah memadukan dua tekstur - yang pertama adalah tekstur dasar untuk model, yang kedua adalah overlay berwarna yang dapat Anda hasilkan saat runtime.

Cara ketiga bisa dengan mengubah warna model dasar dan tidak memiliki tekstur (atau sebagian tekstur transparan) di atas bagian-bagian model yang Anda ingin menunjukkan warna tim.

ChrisF
sumber
2

Mengabdikan saluran alpha tekstur ke warna tim membuat tekstur DXT 2x lebih besar, jadi saya lebih suka menggunakan kunci kroma untuk menghitung warna tim. Tentukan satu warna (misalnya hijau, biru, magenta) sebagai "warna yang dicadangkan" dalam tekstur Anda.

Saat mesin dinyalakan, buat matriks untuk setiap warna tim yang memutar "warna yang dipesan" ke warna tim. Tepat sebelum menggambar objek tim, tetapkan matriks ini sebagai konstanta piksel shader.

Dalam pixel shader, ubah warna pixel dengan matriks warna tim. Lerp warna piksel yang tidak diubah dengan warna piksel yang diubah, dengan jumlah yang sebanding dengan sudut kroma piksel dengan kroma "warna yang dipesan".

Ini akan membebani Anda beberapa instruksi ALU dan memicu pixel shader, tapi itu jauh lebih murah daripada membengkak cache tekstur Anda dengan tekstur 2x lebih besar.

Anda juga memiliki kemampuan untuk memiliki beberapa kunci kroma (mis. Magenta dan cyan dipetakan ke warna tim primer dan sekunder) tanpa mencurahkan satu saluran tekstur untuk setiap warna.

bmcnett
sumber
1

Teknik saya adalah: Memiliki 2 tekstur: satu tekstur utama, satu tekstur kedua overlay utama tetapi hanya bagian yang ingin diwarnai. Ubah warna tekstur kedua sesuai keinginan.

daemonfire300
sumber