Cara mentransfer shader dari mesin game ke Substance Painter

Nama saya Taras Uleisky, saya seorang Artis Teknis di Plarium Kharkiv. Untuk mengoptimalkan grafik Survival RPG kami di perangkat seluler, kami menggunakan shader kustom kami. Mereka melibatkan penggunaan tekstur dan peta unik yang tidak serupa dengan tekstur dan peta dalam metode naungan populer lainnya. Akibatnya, tidak sepenuhnya jelas bagi seniman 3D cara membuat tekstur ini untuk aset dalam game. Untuk segera melihat bagaimana model 3D akan terlihat di mesin game pada tahap texturing, saya memindahkan shader ke Substance Painter. Praktis tidak ada bahan API di Substance Painter saat ini, saya mempelajari topik ini sendiri, jadi saya memutuskan untuk membagikan ide-ide saya sendiri.



Unity shader


Game ini menggunakan naungan matcap. Selain tekstur diff biasa, dua tekstur Matcap yang telah dibuat sebelumnya juga ditransfer ke shader. Mereka diinterpolasi dan kabur masing-masing menggunakan dua topeng. Akibatnya, tekstur Matcap dikalikan dengan silau difus dan palsu dan refleksi dapat dilihat pada materi.



Contoh di bawah ini menunjukkan bagaimana Matcap diimplementasikan dalam grafik shader. Dalam hal ini, dua tekstur Matcap dikemas menjadi satu dan dibagi menjadi beberapa saluran. Yaitu, logam dan non-logam di saluran R dan G, masing-masing.



Dua Matcaps diinterpolasi sebagai contoh oleh pemeriksa.



Hasilnya adalah analogi tertentu dengan logam dan non-logam seperti dalam naungan PBR.

Kami ingin menambahkan kekasaran dan kotoran pada bahan, untuk membuat semacam analog kekasaran dalam naungan PBR. Untuk melakukan ini, kami menggunakan metode texturing.pemetaan-mip . Urutan tekstur menciptakan piramida MIP yang disebut dengan resolusi maksimum hingga 1x1. Misalnya: 1 × 1, 2 × 2, 4 × 4, 8 × 8, 16 × 16, 32 × 32, 64 × 64, 128 × 128. Masing-masing tekstur ini disebut level MIP. Untuk menerapkan pertengkaran dalam pixel shader demi pixel, berdasarkan mask, Anda harus memilih level MIP yang diperlukan. Ternyata begini: di mana piksel pada topeng berwarna hitam, tingkat MIP maksimum dipilih pada Matcap, dan di mana warna piksel putih, tingkat MIP adalah 0.





Sebagai hasilnya, shader memungkinkan untuk mensimulasikan pantulan dan sorotan, menambah kekasaran cahaya dan benturan. Dan semua ini tanpa menggunakan Cubemap, tanpa perhitungan pencahayaan yang rumit dan teknik lain yang secara signifikan mengurangi kinerja perangkat seluler.



Menyiapkan Pelukis Zat untuk membuat shader


Semua shader yang tersedia di Substance Painter ditulis dalam GLSL.
Khususnya, untuk menulis shader untuk Substance Painter, saya menggunakan Kode VS gratis. Untuk penyorotan sintaks, lebih baik menggunakan dukungan bahasa Shader untuk ekstensi VS Code.



Ada sangat sedikit materi tentang API di Substance Painter, sehingga dokumentasi standar yang ditemukan di Help / Documentation / Shader API sangat berharga.



Hal kedua yang akan membantu dalam penulisan shader adalah standar shader di Substance Painter. Untuk menemukannya, buka ... / Allegorithmic / SubstancePainter / sumber daya / rak / algoritma / shader.

Mari kita coba menulis shader unlit paling sederhana yang akan menunjukkan warna Base. Pertama, buat file teks dengan ekstensi .glsl dan tulis shader sederhana tersebut. Mungkin, sementara tidak ada yang jelas, saya akan bercerita lebih banyak tentang struktur shader di Substance Painter lebih lanjut.



Buat proyek baru dan seret shader ke shell Anda. Di daftar turun bawah Impor sumber daya Anda , pilih project 'project_name' .



Ini diperlukan agar semua perubahan dapat diperbarui.

Sekarang pergi ke Pengaturan Window / Views / Shader dan pilih shader baru Anda di jendela yang muncul. Anda dapat menggunakan pencarian.



Jika Anda melihat bahwa seluruh model berwarna putih dan Anda dapat menggambar warna Basis di atasnya, maka Anda melakukan segalanya dengan benar. Sekarang Anda dapat menyimpan proyek dan pergi ke bagian selanjutnya.



Jika model berwarna merah muda, maka kemungkinan besar ada kesalahan dalam shader - pemberitahuan tentang ini akan ada di konsol.

Membangun shader di Substance Painter


Pertimbangkan struktur shader menggunakan shader unlit yang dijelaskan sebelumnya sebagai contoh.



Metode naungan adalah bagian dasar shader, itu tidak akan berfungsi tanpanya. Segala sesuatu yang akan dijelaskan di dalamnya dapat ditampilkan pada model 3D. Semua perhitungan akhir adalah output melalui fungsi difuseShadingOutput () .

Baris 3 dan 4 masing-masing membuat parameter dan variabel. Parameter mengaitkan saluran warna Base dengan variabel di mana tekstur dicat akan disimpan. Semua parameter dijabarkan dalam bantuan , dalam hal warna Dasar semuanya harus dijabarkan seperti pada contoh. Baris 8 menjabarkan tekstur dalam koordinat uv dari model 3D. Saya perhatikan bahwa untuk tekstur dengan warna dasar, sistem Sparse Virtual Textures digunakan , karena perpustakaan terhubung dengan baris pertamalib-sparce.glsl .

Anda dapat menemukan banyak implementasi Matcap, tetapi poin utamanya adalah bahwa normals model diarahkan ke kamera dan teksturnya diputar sepanjang sumbu x dan y. Untuk memutar yang normal ke arah kamera kita perlu melihat matriks, atau jenis matriks . Anda dapat menemukannya di sertifikat yang disebutkan di atas.



Jadi, ini adalah nama yang dideklarasikan sama dengan warna dasar. Sekarang kita perlu mendapatkan normals dari model 3D.


Nol sebagai elemen keempat vektor diperlukan.

Mengalikan matriks tampilan dengan vektor normal akan memperluas normal ke kamera.



Jangan lupa bahwa ketika mengalikan matriks, urutan faktor penting. Jika Anda mengubah urutan perkalian, hasilnya akan berbeda.

Sekarang Anda dapat membuat koordinat uv dari viewNormal .



Sudah waktunya untuk menghubungkan tekstur matcap.



Dalam hal ini, parameter akan membuat bidang tekstur di antarmuka shader, dan jika proyek memiliki tekstur dengan nama "Matcap_mip", maka Pelukis Substance akan secara otomatis menariknya ke atas.



Mari kita periksa apa yang terjadi.



Di sini tekstur Matcap diperluas dalam koordinat baru dan dikalikan dengan warna dasar pada output. Saya ingin memperhatikan fakta bahwa tekstur Matcap diperluas melalui fungsi tekstur () , dan warna Dasar - melalui fungsi teksturSparse () . Ini karena tekstur yang ditentukan melalui antarmuka shader tidak boleh bertipe SamplerSparse .

Hasilnya akan terlihat seperti ini:



Sekarang tambahkan topeng yang akan mencampur dua Matcap. Untuk kenyamanan, tambahkan dua Matcap'a dalam satu tekstur, pisahkan menjadi beberapa saluran. Akibatnya, dua tekstur Matcap akan masing-masing berada di saluran R dan G.

Ini akan menghasilkan sesuatu seperti ini:



Mari kita mulai menambahkan topeng ke shader. Prinsipnya mirip dengan penambahan warna Dasar.



Cukup untuk mengganti nilai basecolor dengan user0 pada parameter.

Sekarang dapatkan nilai mask di pixel shader dan campurkan tekstur matcap.



Di sini, hanya saluran R yang digunakan dalam topeng, karena itu akan menjadi hitam dan putih. Dua saluran matcap dicampur menggunakan fungsi mix () , analog lerp di Unity.

Mari perbarui shader dan tambahkan saluran khusus di antarmuka. Untuk melakukan ini, buka Pengaturan Window / Views / Texture Set, di jendela dekat tajuk Channels, klik plus dan pilih user0 dari daftar besar.



Saluran bisa disebut apa pun yang Anda suka.

Sekarang, menggambar di saluran ini, Anda dapat melihat bagaimana dua tekstur Matcap dicampur.



Shader untuk Unity juga menggunakan peta normal untuk Matcap, yang dipanggang dari model poly-tinggi. Mari kita coba melakukan hal yang sama di Substance Painter.

Untuk menggunakan semua operasi pada normals, Anda perlu menghubungkan perpustakaan yang sesuai :



Sekarang kita menghubungkan peta normal. Ada dua di antaranya dalam Substance Painter: satu diperoleh dengan memanggang, dan yang kedua dapat ditarik.



Menurut parameter, Anda dapat menebak bahwa channel_normal adalah peta normal, yang menurutnya Anda dapat menggambar, dan tekstur_normal- Peta normal yang dipanggang. Saya juga mencatat bahwa nama variabel text_normal tertanam di API dan Anda tidak dapat menamainya sesuai kebijaksanaan Anda.

Selanjutnya, bongkar kartu-kartu dalam pixel shader:



Kemudian kita campurkan peta normal dan normals yang ada di vertex model. Untuk melakukan ini, di perpustakaan yang terhubung di atas, ada fungsi normalBlend () .



Pertama kita mencampur dua peta normal, dan kemudian normal normal. Meskipun itu tidak terlalu penting untuk mencampurnya.

Rotasi normals ke arah pandangan kamera akan terlihat seperti ini:



Maka Anda tidak dapat mengubah apa pun, semuanya akan tetap sama. Seharusnya seperti ini:



Mip-mapping, seperti yang disebutkan di atas, dalam hal ini diperlukan untuk mensimulasikan pertengkaran, seperti kartu kekasaran dalam naungan PBR. Tetapi masalah utama adalah bahwa piramida dari kartu-mip tidak dihasilkan untuk tekstur, yang ditransmisikan dari antarmuka shader, dan karenanya metode teksturLod () dari glsl tidak akan berfungsi. Orang bisa pergi ke arah lain dan memuat tekstur Matcap melalui saluran pengguna, seperti yang dilakukan untuk mencampur Matcap. Tapi kemudian kualitas tekstur akan sangat menurun dan artefak aneh akan muncul.

Solusi alternatif adalah membuat piramida kartu MIPsecara manual, dalam Adobe Photoshop atau editor serupa lainnya, lalu pilih level MIP. Piramida dibangun cukup sederhana. Perlu untuk melanjutkan dari ukuran tekstur asli - dalam kasus saya itu adalah 256x256. Kami membuat file dengan ukuran 384x256 (384, karena 256 + 256/2) dan sekarang mengurangi tekstur aslinya hingga setengahnya menjadi satu piksel. Semua versi tekstur yang diperkecil ditempatkan di sebelah kanan tekstur asli dalam urutan menaik. Seharusnya berubah seperti ini:



Sekarang Anda dapat mulai menulis fungsi yang akan menemukan koordinat setiap tekstur dalam piramida tergantung pada warna setiap piksel pada topeng.

Cara termudah adalah dengan menyimpan koordinat uv yang akan dihitung untuk setiap tekstur dalam array. Ukuran array akan ditentukan sebagai log2 (tinggi). Kami membutuhkan uv asli , jadi kami menambahkannya ke argumen fungsi. Untuk menentukan elemen array mana yang akan digunakan pada piksel tertentu, tambahkan level ke argumen fungsi.



Sekarang hitung uv untuk tekstur asli, yaitu memotong 128 piksel ekstra lebarnya. Untuk melakukan ini, kalikan x koordinat dengan ⅔.



Untuk menggunakan sisa tekstur dari piramida, Anda perlu menemukan pola. Ketika kami membuat piramida dari tekstur, kami bisa melihat bahwa setiap kali tekstur berkurang setengah dari ukuran sebelumnya. Artinya, berapa kali ukuran tekstur berkurang, Anda dapat menentukan dengan menaikkan 2 pangkat MIP .



Ternyata, jika Anda memilih level, misalnya, 4, maka tekstur akan berkurang sebanyak 16 kali. Sebagaikoordinat uv ditentukan dari 0 hingga 1, maka ukurannya perlu dinormalisasi, yaitu, 1 dibagi dengan berapa kali teksturnya menurun, misalnya 1 dibagi dengan 16.

Dengan menggunakan nilai yang diperoleh dari variabel ukuran, Anda dapat menghitung koordinat untuk level MIP tertentu .



Ukuran uv dikurangi dengan cara yang sama seperti ukuran tekstur. Pada koordinat x, tekstur selalu bergeser ⅔. Pergeseran koordinat y dapat didefinisikan sebagai jumlah dari semua nilai variabel ukuran untuk setiap nilai level . Artinya, jika nilainya level = 1 , maka uv dalam koordinat y akan bergeser 0 piksel, dan jika level = 2 , maka pergeseran akan menjadi setengah tinggi tekstur - 128 piksel. Jika level = 3, maka shift akan berubah menjadi 128 + 64 piksel dan sebagainya. Jumlah semua shift dapat diperoleh dengan menggunakan siklus.



Sekarang, setiap iterasi, variabel offset akan bertambah dan menggeser tekstur sepanjang sumbu y dengan jumlah piksel yang diinginkan. Algoritme langkah-demi-langkah terlihat seperti ini:



Langkah terakhir adalah menampilkan saluran yang akan memilih level yang diinginkan pada setiap piksel. Kami sudah melakukan ini, tidak ada yang baru.





Untuk memilih level MIP sebagai tekstur, cukup gandakan panjang array dengan tekstur. Sekarang Anda dapat menghubungkan koordinat uv baru melalui metode yang baru saja ditulis.



Jangan lupa menerjemahkan tekstur ke dalam tipe int, karena ini sekarang merupakan indeks untuk array.
Selanjutnya, Anda perlu menambahkan saluran khusus di Substance Painter, seperti yang kami lakukan sebelumnya. Seharusnya berubah seperti ini:





Satu-satunya hal yang hilang untuk shader adalah sumber cahaya dan kemampuan untuk memutarnya dengan menekan shift. Pertama-tama, untuk ini kita perlu parameter yang akan menghasilkan sudut rotasi dengan menekan shift, dan matriks rotasi .





Kami secara acak menempatkan sumber cahaya dan mengalikan posisi dengan matriks rotasi.



Sekarang sumber cahaya akan berputar di sekitar sumbu y dengan menekan shift, tetapi sejauh ini ini hanya vektor di mana posisi sumber cahaya disimpan. Ada barang bagusbagaimana menerapkan cahaya terarah dalam shader. Kami akan fokus padanya. Tetap bagi kita untuk menentukan arah cahaya dan penerangan model kita.



Warna bayangan dan warna sumber cahaya akan ditentukan oleh parameter:



Parameter warna diinterpolasi sesuai dengan pencahayaan yang dihitung di atas.



Ini akan menjadi seperti ini:



Menggunakan parameter ini, Anda dapat menyesuaikan warna bayangan dan warna sumber cahaya melalui antarmuka Pelukis Substance.



Buat dan konfigurasikan preset


Ketika shader sudah siap, Anda perlu mengimpor tekstur Matcap dan shader dengan pengaturan rak.



Kami menghapus semua saluran yang tidak digunakan dan menambahkan saluran pengguna:



Prasetel untuk mengekspor tekstur akan terlihat seperti yang lain, kecuali bahwa itu akan menggunakan saluran khusus kami.



Kami akan membuat templat untuk semua pengaturan sehingga saat Anda membuat proyek, shader yang diinginkan segera ditetapkan dan semua saluran tekstur dikonfigurasikan. Untuk melakukan ini, buka File / SaveAsTemplate dan simpan template.



Sekarang saat membuat proyek baru, Anda tidak perlu mengonfigurasi apa pun - cukup pilih templat yang diinginkan.



Apa yang kamu dapatkan


Seniman teknis dapat membuat efek khusus, menyesuaikan adegan, dan mengoptimalkan proses rendering. Saya juga ingin model baju besi dan senjata di Stormfall: Saga of Survival menjadi apa yang dimaksudkan oleh seniman 3D. Hasilnya, model 3D di Substance Painter terlihat sama seperti di mesin gim.


Model 3D dalam Substance Painter dengan custom shading.


Model 3D dalam Persatuan dengan naungan khusus.

Saya harap artikel ini bermanfaat dan menginspirasi Anda untuk pencapaian baru!

All Articles