
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 .