Unreal Engine4 - Efek pemindaian PostProcess



Akhir pekan ini saya memiliki waktu luang antar kelas (perhatikan penulis menerima gelar Master of Science pada saat artikel) , dan saya memutuskan untuk kembali membuat shader dengan menciptakan efek pemindaian pasca-proses ini. Saya membayangkan bahwa itu digunakan dalam permainan sebagai semacam efek pemindaian jarak. Kami juga menggunakan beberapa distorsi kebisingan sederhana untuk membuat efeknya terlihat sedikit lebih menarik.

Pada artikel ini saya akan memberi tahu Anda bagaimana menerapkan efek ini pada UE4. Ada beberapa cara di mana Anda dapat membuat efek ini. Salah satu metode ini dipilih oleh saya.

Anda dapat membuka gambar di tab baru untuk melihatnya dalam resolusi yang lebih tinggi.

Komponen utama


Gagasan utama dari efek ini adalah untuk membuat versi render adegan menggunakan operator Sobel , dan kemudian mencampurnya dengan render adegan berbasis SphereMask yang biasa, yang kami akan buat untuk membuat efek pemindaian.

Efek ini terdiri dari 3 komponen utama:

  • Bidang scalable SphereMask
  • Fungsi Sobel-Edge (saya tidak akan menjelaskan bagaimana fungsi ini bekerja, karena ini adalah topik yang terpisah, tetapi saya akan merujuk pada kode yang saya gunakan)
  • Overlay tekstur yang diproyeksikan di kisi dunia

Bidang scalable SphereMask


Bagian ini adalah tentang bagaimana kita membuat SphereMask yang dapat diskalakan. Untuk melakukan ini, kami mentransfer posisi cetak biru ke set parameter material, setelah itu kami menggunakannya sebagai berikut



Hubungkan hasil node Clamp ke output memancarkan materi Anda dan Anda akan melihat sesuatu seperti ini



"TexLoc" adalah vektor3 yang menentukan lokasi sumber bola, dalam kasus saya ini dibaca dari serangkaian parameter material, sehingga dapat dibaca dari permainan itu sendiri, misalnya, untuk menentukan posisi pemain.

Seperangkat parameter simpul yang ditentukan di atas menciptakan bidang dengan radius bola 1024 unit. Saya hanya menggunakannya untuk menampilkan hasilnya di jendela pratinjau. Jika Anda ingin mempelajari lebih lanjut tentang bekerja dengan fungsi jarak jauh dan memahami cara menggunakannya, saya sangat merekomendasikan untuk memeriksa situs web Inigo Quilez .

Sekarang kita akan menggunakan Waktu untuk skala bola dengan interval waktu yang telah ditentukan.



Ini akan memberi kita hasil berikut



Frac (waktu) pada dasarnya memberi kita periode konstan yang terus berjalan 0-1.0-1.0-1. Kami mengalikan waktu dengan 0,25 untuk mengontrol kecepatan penskalaan, dan kemudian mengalikan hasilnya dengan jari-jari bola, yang mengarah ke perubahan jari-jari dari 0 hingga 1024, dan memberi kami topeng animasi.

Ini adalah hasil yang baik, tetapi ini bukan yang kita inginkan dari efeknya. Kami membutuhkan cincin penskalaan. Ini dapat dengan mudah dilakukan dengan menggunakan perhitungan sederhana.



Ini akan memberi kita apa yang kita inginkan, cincin yang sedang tumbuh, dengan gradasi gradien yang baik yang dapat dikendalikan.



Operasi matematika di blok Edge_Mask pada dasarnya memilih posisi dalam mask gradien, dalam hal ini nilainya 0,5, dan menentukan tepi mask dari posisi saat ini dengan lebar yang diberikan, yang memungkinkan kita untuk mendapatkan cincin. Saya tidak akan masuk ke detail teknis untuk mendapatkan tepi topeng, kemungkinan besar saya akan membicarakan hal ini di salah satu posting berikut.

Seperti yang Anda lihat, Anda memiliki kontrol penuh atas lebar cincin tanpa parameter skalar, dan jika kami ingin, kami bahkan dapat mengontrol pelemahan tepi, tetapi kami tidak memerlukan ini dalam efek ini.

Langkah selanjutnya adalah menggunakan noise untuk membuat versi cincin yang menarik secara visual.

Untuk ini, kita akan menggunakan simpul Vector Noise , yang merupakan bagian dari UE4. Anda dapat membacanya di sini , atau Anda dapat menggunakan tekstur noise yang berisi koordinat UV World Aligned.

Di shader saya, saya menetapkan parameter Function di Cellnoise di simpul Noise Vector , silakan bereksperimen dengan tipe parameter ini untuk mendapatkan efek unik Anda sendiri.



Hasilnya akan terlihat sebagai berikut



Ini adalah tahap pertama shader kami selesai, maka kami akan mempertimbangkan implementasi fungsi Sobel-Edge.

Fungsi Sobel-Edge


Ada banyak opsi berbeda untuk fitur ini, beberapa di antaranya lebih dioptimalkan daripada yang lain, saya tidak akan menjelaskan esensinya, karena ini adalah topik yang terpisah, tetapi pencarian Google secara teratur dengan kata kunci "Sobel Edge" atau "Sobel Operator" akan memberi Anda banyak pilihan . Atau gunakan artikel di hub dari Gepard_vvk - Algoritma untuk memilih kontur gambar .

Gagasan utama dari operator Sobel adalah ini: kami mengambil RenderTarget adegan (bayangkan bahwa itu adalah tekstur yang berisi apa yang saat ini Anda lihat di viewport Anda) dan membandingkan setiap piksel dengan semua piksel tetangga di sekitarnya. Selanjutnya, kami membandingkan perbedaan kecerahan, dan jika perbedaannya di atas ambang tertentu, kami menandainya sebagai tepi, dan dalam proses ini kami mendapatkan topeng tekstur Target RenderTarget hitam dan putih, di mana topeng disesuaikan di tepi.

Kode di bawah ini adalah contoh sederhana dari fungsi operator Sobel yang dibuat RebelMoogle di situs web Shadertoy (kemungkinan besar opsi ini tidak sepenuhnya dioptimalkan, sehingga Anda dapat mencoba implementasi lain), kami akan membuatnya kembali di UE4 dalam materi kami.

void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 uv = fragCoord.xy / iResolution.xy; vec3 TL = texture(iChannel0, uv + vec2(-1, 1)/ iResolution.xy).rgb; vec3 TM = texture(iChannel0, uv + vec2(0, 1)/ iResolution.xy).rgb; vec3 TR = texture(iChannel0, uv + vec2(1, 1)/ iResolution.xy).rgb; vec3 ML = texture(iChannel0, uv + vec2(-1, 0)/ iResolution.xy).rgb; vec3 MR = texture(iChannel0, uv + vec2(1, 0)/ iResolution.xy).rgb; vec3 BL = texture(iChannel0, uv + vec2(-1, -1)/ iResolution.xy).rgb; vec3 BM = texture(iChannel0, uv + vec2(0, -1)/ iResolution.xy).rgb; vec3 BR = texture(iChannel0, uv + vec2(1, -1)/ iResolution.xy).rgb; vec3 GradX = -TL + TR - 2.0 * ML + 2.0 * MR - BL + BR; vec3 GradY = TL + 2.0 * TM + TR - BL - 2.0 * BM - BR; fragColor.r = length(vec2(GradX.r, GradY.r)); fragColor.g = length(vec2(GradX.g, GradY.g)); fragColor.b = length(vec2(GradX.b, GradY.b)); } 


Di UE4, terlihat seperti ini



Catatan singkat tentang implementasi fungsi - pastikan node SceneTexture Anda dikonfigurasi untuk menggunakan PostProcessInput0



Dua Custom node GradX dan GradY , konfigurasikan dengan cara yang sama



GradX :

 return -TL + TR - 2.0 * ML + 2.0 * MR - BL + BR; 

Grady :

 return TL + 2.0 * TM + TR - BL - 2.0 * BM - BR; 

Ini tidak harus dilakukan di Custom , saya menggunakannya hanya untuk kenyamanan, karena kalau tidak akan ada terlalu banyak node dan spaghetti akan terbentuk.

Jika Anda menyambungkan hasil fungsi ke keluaran material yang memancarkan , Anda akan melihat yang berikut ini



Kami juga mengalikan hasilnya dengan vektor3 biasa untuk membuat tepi warna apa pun yang kita inginkan.



Hasilnya, warna tepi berubah.



Dunia overlay tekstur kotak


Bagian paling sederhana: kami hanya menggunakan tekstur mesh dan memproyeksikannya ke seluruh dunia, dan kemudian menggabungkannya dengan fungsi Sobel-Edge untuk mendapatkan efek keren.



Jika Anda menghubungkan hasil fungsi ke output emissive , Anda akan melihat



Menyatukan semuanya


Sekarang kita akan menyatukan ketiga bagian untuk efek posting kita!

Pertama, kami menggabungkan fitur Sobel-Edge dan World-Aligned-Grid, menyatukannya



Kemudian kita membuat simpul SceneTexture dan menambahkan hasilnya dari Sobel-Edge dan World-Aligned-Grid ke sana.

Lalu kami menyisipkan antara adegan normal dan yang ditambahkan, menggunakan hasil dari topeng cincin yang kami buat di bagian pertama



Dan voila, kami berhasil. Hasil akhirnya akan terlihat seperti ini. Anda tentu saja dapat menyesuaikan parameter dan mencoba mengubah nilainya untuk mendapatkan opsi yang lebih menarik.



Saya harap Anda menemukan informasi ini berguna, semua yang terbaik :)

Contoh proyek dengan shader ini dapat ditemukan di github .

Source: https://habr.com/ru/post/id435240/


All Articles