Cara terbaik untuk memungkinkan pemain untuk "Mewarnai" gambar tanpa kehilangan kualitas warna?


41

Saya membuat game 2.5D isometrik (gambar 2D).

Saya ingin para pemain dapat "mewarnai" baju besi, pakaian, dan hal-hal lainnya. Saya menemukan bahwa semua yang abu-abu menyebabkan hilangnya pewarna yang lebih "alami". Misalnya, membuat naga dengan skala abu-abu merah / kuning dan kemudian menerapkan warna overlay, mengarah ke naga merah murni dengan semua kehilangan warna sekunder. Sementara itu, sekarat yang sama Merah / Kuning Naga Biru, membuatnya Biru / Putih yang tampak hebat.

Karakter dalam gim saya tidak memiliki berbagai macam peralatan. Permainan ini lebih dekat dengan bagaimana League of Legends menangani karakter dan grafik. Mungkin ada satu jenis karakter (mis. Pahlawan) tetapi beberapa pakaian untuk karakter sebagai opsi. Saya ingin para pemain dapat memiliki kustomisasi sebanyak mungkin dalam jumlah terbatas "pakaian" dan karakter.

Jadi saya ingin pemain dapat memilih karakter, memilih salah satu dari beberapa senjata, bergantian di antara beberapa pilihan kostum (berlapis ke karakter), dan kemudian mewarnai sebagian besar segalanya (memilih warna metalik khusus untuk senjata, memilih warna apa saja sama sekali untuk pakaian).

Jika saya bisa menggunakan grayscale tanpa kehilangan pewarnaan, saya akan melakukannya.

Berikut adalah contoh tentang apa yang saya bicarakan:

masukkan deskripsi gambar di sini masukkan deskripsi gambar di sini masukkan deskripsi gambar di sini

Bahkan tidak mungkin untuk "mewarnai" Naga, apa pun yang saya gunakan dalam opsi "Hamparan Warna" Photoshop. Jelas, saya melakukan kesalahan jika memungkinkan untuk mewarnainya dengan lebih baik menggunakan skala abu-abu. Untuk warna seperti Hijau atau Kuning atau Lighter Purple, ini berfungsi baik. Untuk warna lain, itu menghancurkan seni.

Namun, itu terlihat jauh lebih baik jika saya TIDAK skala abu-abu, dan alih-alih hanya menerapkan warna "HUE" ke gambar asli (Merah / Kuning).

Hue Merah masukkan deskripsi gambar di sini

Rona ungu masukkan deskripsi gambar di sini

Sekarang para pemain bisa mewarnai warna naga APA SAJA, dan itu akan tetap terlihat hebat! (Kuning berubah putih, sedangkan merah berubah menjadi warna pelangi.)

Apakah ini berarti bahwa PUTIH atau HITAM adalah warna sekunder terbaik? Kemudian gunakan semacam metode atau shader untuk mengubah warna putih (sekunder) menjadi sesuatu yang berbeda?

Apakah ada artikel tentang metode kompleks ini untuk mengambil gambar tunggal, dan berdasarkan pewarnaan, mewarnai piksel yang berbeda?

Untuk Naga, apakah itu akan bekerja dengan baik sebagai Naga Kontras Putih / Hitam tinggi? Apakah Merah / Kuning set warna terbaik? Ternyata jauh lebih baik untuk gambar daripada beberapa warna lain yang saya coba. Apakah Grayscale masih unggul?

Apakah "Blending Options" Photoshop tidak termasuk metode untuk "mewarnai" gambar dengan tepat untuk gim video? Apakah ada Shader / Metode kompleks yang memungkinkan saya untuk mencapai kesuksesan yang lebih baik?

Catatan: Jika GrayScale memungkinkan saya untuk mengurangi konsumsi RAM gambar saya, atau mencegah hilangnya kualitas selama kompresi lossy, itu akan menjadi sesuatu yang saya akan pertimbangkan dengan serius.


5
Ini menarik secara sah. Saya akan memilih ini dan berharap mendapat perhatian lebih. Teori warna adalah topik yang bagus.
Evan

Rotasi rona adalah suatu kemungkinan, meskipun ke 2D - Saya tidak tahu apakah itu akan bekerja dalam 3D.
ashes999

Evan terima kasih. Saya juga setuju ini sangat menarik, dan salah satu topik terbaik yang saya teliti pada waktu saya sendiri. Jenis pekerjaan ini, saya bayangkan, jarang dilakukan karena akan membutuhkan seorang seniman - tetapi bukan sembarang seniman - seorang seniman yang berurusan dengan teori warna, video game shaders, atau bahkan seorang artis-coder. Saya hanya bisa membayangkan bahwa menemukan seseorang yang unggul dalam seni dan pemrograman jarang terjadi. Tidak ada penelitian yang dapat ditemukan tentang subjek ini di google. Terutama bagi seseorang yang tidak tahu istilah kunci apa untuk penelitian. Saya jelas bukan seorang seniman.
Carter81

Jawaban:


19

Hue-shifting adalah salah satu kemungkinan yang memungkinkan Anda mendapatkan beragam warna tanpa kehilangan detail warna. Ide dasarnya adalah untuk mengkonversi setiap piksel dari ruang RGB ke HSV, lalu mengimbangi rona dengan jumlah yang ditentukan pengguna, lalu mengonversi kembali ke RGB. Sebenarnya, ini dapat dilakukan lebih efisien dengan menerapkan matriks rotasi ke nilai RGB: buat matriks yang berputar di sekitar sumbu (1, 1, 1) dengan sudut rona yang ditentukan pengguna. Kemudian Anda cukup menerapkan matriks ini untuk setiap nilai RGB di pixel shader Anda.

Ini akan memungkinkan naga merah-kuning untuk dipindahkan ke naga kuning-hijau, hijau-cyan, biru-sian, biru-magenta, atau magenta-merah. Ini agak membatasi karena dua warna tidak dapat diubah secara independen dengan pendekatan ini. Mereka akan mempertahankan rona relatif mereka saat mereka ditulis dalam gambar asli. Ada juga beberapa warna yang tidak dapat Anda akses, misalnya Anda tidak dapat membuat naga hitam-putih dengan cara ini. Namun, ini mungkin cukup untuk keperluan Anda.

Kemungkinan lain, jika model Anda memiliki dua atau tiga "warna kunci" (merah dan kuning di sini), Anda dapat membuat gambar asli menggunakan saluran warna terpisah untuk setiap warna kunci. Dalam hal ini, Anda akan membuat naga merah dan hijau alih-alih merah dan kuning, dan jika Anda memiliki warna ketiga, Anda dapat membuatnya dengan warna biru. Kemudian, Anda dapat membiarkan pengguna memilih tiga warna utama, dan menggunakan nilai-nilai merah, hijau, dan biru pada gambar sebagai jumlah dari warna-warna yang ditentukan pengguna untuk berbaur. Jadi pixel shader Anda akan terlihat seperti

finalColor = image.r * userColor1 + image.g * userColor2 + image.b * userColor3;

Ini akan memungkinkan pengguna memilih kombinasi warna apa pun yang mereka inginkan, termasuk hal-hal seperti hitam dan putih, atau ungu dan emas.


1
Memberi +1 bukan hanya jawaban yang bagus, tetapi juga jawaban untuk topik langka (teori warna). Saya tidak tahu mengapa saya tidak memikirkan itu sebelumnya. RGB. Merah Hijau Biru. DUH! Warna terbaik untuk digunakan mungkin tiga warna yang tepat, karena kemampuan untuk memanipulasi saluran individu.
Carter81

1
Pergeseran warna adalah topik yang sangat sulit karena sebagian besar informasi gambar disampaikan oleh kecerahan, dan pergeseran rona sederhana tidak mempertahankan kecerahan. Rona yang berbeda memiliki nilai kecerahan bawaan yang berbeda. Anda perlu algoritma yang lebih canggih untuk itu.
API-Beast

10

Masalah yang Anda hadapi adalah bahwa Anda tidak bisa begitu saja "mewarnai" seluruh gambar, penampilan yang Anda lihat lebih dari sekadar warna dasar. Untuk satu Anda memiliki gradien halus dari satu bahan ke yang lain, tetapi yang lebih penting Anda juga memiliki refleksi, highlight dan bayangan, yang tidak dipengaruhi oleh warna dasar. (Itu pada dasarnya ditambahkan di atasnya.)

Jadi, Anda perlu menguraikan gambar menjadi komponen-komponennya.

Contoh A :

Gambar yang Didekonstruksi Contoh Berwarna

Dalam hal ini kami memiliki 3 lapisan:

  • Latar Belakang - Ini berisi elemen yang tidak boleh diwarnai.
  • Bagian yang harus diwarnai - Ini dikalikan dengan warnanya. (OpenGL mengalikan secara default jika Anda menentukan warna selain putih.)
  • Sorotan - Ini ditarik aditif di atas seluruh gambar. Bukan putih tapi kuning, untuk meniru perubahan rona. Objek bukan hanya satu warna, rona berubah bersamaan dengan kecerahan.

+1. Tapi "Anda tidak bisa begitu saja" mewarnai "seluruh gambar" agak menyesatkan. Itu semua tergantung pada pilihan OP untuk gimnya. Misalnya Diablo II yang melakukannya. Jadi saya tidak akan terlalu ketat dengan bagian "Anda tidak bisa / Anda perlu". Ini hanyalah salah satu opsi, lebih tampan tetapi lebih banyak memakan RAM.
Kromster mengatakan mendukung Monica

1
@KromStern Point adalah, terlihat mengerikan jika Anda melakukannya, selalu.
API-Beast

Jawaban yang bagus Apakah ini mungkin, melalui otomatisasi? Jika seseorang memiliki ribuan gambar animasi untuk satu karakter, tidak layak untuk memilih sendiri setiap lapisan atau menguraikan gambar satu per satu. Namun, saya dapat melihat beberapa solusi untuk membantu mengotomatiskannya jika rendering dari 3D menggunakan masking, tetapi terlepas dari itu masih merupakan jawaban yang bagus.
Carter81

Sangat mungkin untuk mengotomatiskannya dengan menemukan warna dominan dan mengekstraksinya (dengan menggunakan algoritma "warna ke alfa" terbalik). Tapi bukan berarti saya pernah menerapkan sesuatu seperti itu.
API-Beast

Untuk mengekstraksi highlight, Anda dapat mengambil mask yang sebelumnya Anda ekstrak dan memfilternya sehingga Anda hanya memiliki komponen yang paling cerah.
API-Beast

3

Saya pribadi akan merekomendasikan menggunakan tekstur topeng untuk mencapai apa yang Anda inginkan. Ini akan memastikan bahwa tekstur RGB24 utama Anda akan menjaga kualitas warna aslinya tanpa mengorbankan presisi. Ini juga akan memberi Anda banyak kebebasan artistik untuk memadukan tekstur utama Anda dengan topeng warna Anda.

Setiap topeng dapat dilihat sebagai tekstur skala abu-abu yang secara linier akan menginterpolasi warna tekstur dasar Anda dengan warna kustom Anda. Katakanlah Anda membiarkan pengguna Anda menyesuaikan dua warna, pixel shader akan terlihat seperti ini:

input: MainTexture (RGB), Mask1Texture (A), Mask2Texture (A), Colour1 (float), Colour2 (float)

output: (Mask1Texture + Mask2Texture) -MainTexture + Colour1 * Mask1Texture + Colour2 * Mask2Texture

Ini menunjukkan bahwa semakin banyak topeng memiliki nilai besar untuk satu piksel, semakin sedikit tekstur utama Anda akan berdampak pada warna keluaran piksel itu. Misalnya Anda dapat mengubah tekstur naga Anda menjadi skala abu-abu dan menghapus semuanya kecuali sayap Anda untuk memiliki warna sayap kustom, apa pun warna tubuhnya.

Saya telah menggunakan teknik ini untuk permainan seluler dan itu tidak akan memengaruhi kinerja Anda secara keseluruhan. Mungkin dikenakan biaya 33% lebih banyak RAM per tekstur tetapi trade-off untuk kualitas mungkin sepadan.

Ps Jika Anda hanya berpikir untuk menggunakan satu warna khusus, Anda cukup menggunakan saluran Alpha dari tekstur utama RGBA32 Anda sebagai masker.


2

Anda dapat menggunakan palet warna dan membiarkan pemain mengedit palet. Jika Anda menggunakan shader, Anda dapat menggunakan tekstur 1D sebagai palet dan nilai abu-abu asli sebagai indeks.

Untuk mengonversi gambar warna asli menjadi gambar dengan 255 warna, Anda dapat mengambil semua nilai warna piksel Anda dan mengelompokkannya dalam ruang warna 3d hingga 255 cluster dengan algoritma k-means. Atau gunakan alat konversi gambar umum. Maka penting untuk menyebutkan bahwa interpolasi tekstur nilai abu-abu akan menjadi interpolasi indeks dalam tekstur warna Anda. Ini dapat menyebabkan hasil di mana Anda memiliki beberapa warna antara dua texel dari gambar asli Anda. Ini dapat diselesaikan dengan menonaktifkan interpolasi (saya pikir Anda tidak ingin melakukan itu) atau dengan menyortir palet warna Anda dengan cara yang bermanfaat.


Ini pada dasarnya apa yang saya pikirkan juga. Anda mungkin ingin memperluas jawaban untuk sesuatu yang sedikit lebih lengkap. Pada dasarnya, Anda membiarkan pengguna memilih dua warna (atau lebih atau lebih sedikit, tetapi demi argumen, 2), buat tekstur 1D yang memudar dari dua warna. Gunakan tekstur skala abu-abu pada geometri yang berfungsi sebagai referensi dalam tekstur 1D. Masih mungkin bagi pengguna untuk mengatur warna yang jelek, tetapi mereka setidaknya memiliki pilihan untuk membuat pilihan warna yang kontras.
wrosecrans

ya Anda juga dapat memperoleh palet warna penuh 255 dari warna pengguna yang lebih sedikit, tetapi di sini saya hanya dapat menyarankan Anda untuk mencobanya. Saya tahu bahwa banyak game lama menggunakan perubahan pada palet warna untuk membuat variasi pada monster mereka. Saya pikir Diablo melakukan itu.
Arne

1

Anda bisa mengonversi gambar menjadi gambar abu-abu tetapi tetap menyimpannya dengan saluran rgba. simpan nilai bobot di saluran alfa lalu gunakan ini untuk memutuskan berapa banyak pewarna yang diterapkan pada piksel. berat ini dapat dihitung berdasarkan seberapa dekat warnanya dengan putih. semakin mendekati putih pikselnya, semakin sedikit pewarna yang berlaku atau semakin rendah beratnya. ini akan meninggalkan sorotan paling terang dengan aslinya, tetapi menerapkan sedikit pewarna untuk itu. warna piksel akhir kemudian dapat ditemukan dengan menghitung setiap saluran Ro + (Rd * Ao) di mana Ro adalah merah asli, Rd adalah merah dalam warna pewarna dan Ao adalah Alpha dari aslinya. jadi semua piksel putih tidak mendapat warna baru dan semua piksel hitam menganggap warna pewarna.

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.