Bagaimana saya bisa membuat efek glitter?

9

Saya mencoba membuat efek berkilauan untuk shader waktu nyata saya, tetapi saya tidak tahu caranya.

Ini satu contoh , dan satu lagi contoh .

masukkan deskripsi gambar di sini

Teknik apa yang bisa saya gunakan untuk mengimplementasikan ini?

Tikar
sumber
Ini dapat dicapai melalui efek Pasca-proses, mirip dengan mekar, tetapi menerapkan pola (tekstur bintang) ke fase sampel bawah. Ini semua hanya spekulasi yang sulit.
akaltar
1
Bukankah peta yang normal dan specular memungkinkan Anda melakukan ini melalui tekstur?
JohnB
Saya membuat beberapa tes menggunakan peta normal. Tapi yang sulit adalah membuatnya berkilau sesuai dengan orientasi tampilan dan orientasi cahaya.
MaT

Jawaban:

10

Nah, ketika diminta untuk merancang shader apa pun, kita harus mulai dengan memecah masalah menjadi masalah yang lebih kecil. Dan seperti halnya efek kilau tidak benar-benar membuat shader terlihat bagus, tetapi keseluruhan pencahayaan dan efek, hanya menggunakan salah satu dari mereka tidak akan terlihat baik.

Pertama-tama, mari kita nyatakan apa yang bukan bagian langsung dari shader:

  1. Bayangan itu bukan bagian dari shader, dan itu dilakukan melalui pas bayangan terpisah.
  2. Saya berasumsi ada oklusi ambien (terutama bahwa gambar ini ditampilkan dalam pertanyaan terutama tidak menggunakan renderer waktu nyata tapi itu asumsi).

Kedua, mari pisahkan shader yang sebenarnya menjadi efek terpisah:

  1. Ada pencahayaan seperti anisotropik, ini sangat penting untuk keseluruhan tampilan shader. Alasan di balik ini, adalah bahwa bahan aktual mengandung kain, kain mengkilap ini membuat pantulan cahaya memiliki bias arah, membuat sebagian besar cahaya yang dipantulkan ke arah tertentu.

masukkan deskripsi gambar di sini

masukkan deskripsi gambar di sini Perhatikan bahwa kain seperti itu memiliki banyak normalnya yang tak terhingga, tetapi teknik yang dijelaskan di sini mendekati normal yang paling signifikan

Dalam rangka untuk mendekati yang paling signifikan normal, salah satu cara yang harus dilakukan, adalah dengan menggunakan tekstur koordinat dan garis singgung menghitung mesh, dan bukannya menghitung N . L Anda menghitung 1- (NT).

Penjelasan lengkap di sini . Dan Anda mungkin perlu menerapkannya dalam fragmen shader daripada teknik vertex yang mereka bicarakan. Model anisotropik lainnya juga dapat diterapkan.

Sekarang untuk efek kilau:

Ini dapat dilakukan di ruang dunia / ruang tekstur lokal, atau ruang layar sebagai operan terpisah.

Algoritma yang dapat saya pikirkan, menggunakan teknik pemrosesan gambar (dengan asumsi mesh memiliki coords tekstur).

  • Menghasilkan noise 2D frekuensi tinggi pada permukaan mesh menggunakan koordinat teksturnya, noise perlin tampaknya merupakan kandidat yang baik.
  • Terapkan filter maks menggunakan 3x3 kernel pada noise. Ini akan menghasilkan efek yang mirip dengan gambar di bawah ini, dan filter maks dijelaskan di sini .

masukkan deskripsi gambar di sini

Perhatikan gambar di atas hanyalah contoh dari filter maks, dan menerapkannya pada noise akan memberikan sth mirip dengan bidang bintang.

  • Setelah Anda melakukan ini, terapkan filter Gaussian dengan penyimpangan tertentu pada noise untuk mendapatkan bentuk seperti bintang.

masukkan deskripsi gambar di sini

Contoh filter Gausian diterapkan pada noise maks.

  • Langkah terakhir adalah menggabungkan ini dengan tekstur dan cahaya mesh asli. Ini paling baik dilakukan dengan menggunakan operasi biner (|) atau-ing dengan tekstur / warna mesh asli, ini hanya akan mengambil putih dari kebisingan dan menghilangkan piksel hitam. Mengenai cahaya (dan mungkin peta specular lainnya), hal terbaik yang harus dilakukan adalah menambahkan atau memodulasinya dengan piksel gabungan sebelumnya. Anda juga mungkin memerlukan efek post-glow untuk mendapatkan cahaya yang lebih baik.

Catatan, teknik ini mungkin perlu optimisasi yang signifikan untuk shader waktu nyata.

concept3d
sumber
3

Ada artikel yang menarik AMD - Getting Procedural .

Sepertinya kilau lebih sulit dari yang kupikirkan.
Solusi yang layak: Gunakan posisi 3D untuk mengindeks fungsi noise 3D, tambahkan vektor tampilan, gunakan fungsi frac untuk mengacak lebih jauh hal-hal.

Sparkle:
float specBase = saturate(dot(reflect(-normalize(viewVec), normal),
lightDir));
// Perturb a grid pattern with some noise and with the view-vector
// to let the glittering change with view.
float3 fp = frac(0.7 * pos + 9 * Noise3D( pos * 0.04).r + 0.1 * viewVec);
fp *= (1 - fp);
float glitter = saturate(1 - 7 * (fp.x + fp.y + fp.z));
float sparkle = glitter * pow(specBase, 1.5);
Tikar
sumber