Memesan transparansi independen dalam sistem partikel

9

Saya sedang menulis sistem partikel dan ingin menemukan trik untuk mencapai campuran alpha yang tepat tanpa menyortir partikel karena:

  • Setiap partikel adalah titik sprite dalam satu mesh dan saya tidak dapat menggunakan kemampuan grafik adegan untuk mengurutkan node transparan. Namun, simpul sistem harus disortir dengan benar.
  • Posisi partikel dihitung pada shader dari kecepatan awal, akselerasi dan waktu. Untuk mengurutkan sistem saya harus melakukan semua perhitungan ini pada CPU, yang merupakan sesuatu yang ingin saya hindari.
  • Menyortir ratusan partikel terhadap posisi kamera dan mengunggahnya pada GPU setiap frame menjadi operasi berat yang tenang.

Pengujian alpha tampaknya cukup cepat pada GLES 2.0 dan berfungsi dengan baik untuk tekstur yang tidak transparan tetapi "tertutup". Namun, itu tidak cukup untuk partikel semi-transparan.

Bagaimana kamu akan mengatasi ini?

Stepan Zastupov
sumber
Seberapa pentingkah mereka diurutkan dengan benar? Apakah Anda benar-benar melihat artefak (penting) yang menggunakan campuran vanila?
ChrisE
Sebuah partikel dapat berbaur dengan latar belakang, bukan partikel lain dan kemudian esensi "segi empat" dari point-sprite sangat terlihat. Pengujian alfa membantu di sini tetapi artefak masih terlihat ketika nilai alfa tenang rendah tetapi tidak cukup untuk membuang fragmen.
Stepan Zastupov
6
Sudahkah Anda mencoba menonaktifkan penulisan kedalaman (membiarkan tes kedalaman aktif) saat merender partikel? Itu seharusnya membuat pemesanan yang salah menjadi kurang jelas.
Adam
2
Setelah beberapa percobaan saya menemukan bahwa menonaktifkan penulisan dalam adalah solusi terbaik dalam banyak kasus.
Stepan Zastupov

Jawaban:

10

Inilah yang akan saya lakukan.

Langkah 1: Jangan urutkan. Lakukan saja. Lihat apakah itu masalah. Kemungkinan besar tidak.

Langkah 2: Batasi partikel menjadi sedemikian rupa sehingga tidak perlu disortir, seperti:

  • Hanya padatan (dengan ujung yang kemungkinan alpha-to-coverage)

    • biarkan zbuffer mengurus penyortiran.
  • Hanya bit tambahan

    • a + b = b + a, jadi pesanan tidak masalah

Langkah 3: jika lebih banyak dibutuhkan, pisahkan rendering partikel menjadi bit yang harus ada di depan dan sisanya, dan lakukan rendering dalam beberapa lintasan (misalnya, dapat memperbaiki asap kompleks)

Langkah 4: jika masih banyak yang dibutuhkan, atau jika Anda membutuhkan solusi umum, satu hal yang terlintas dalam pikiran adalah menggunakan MRT untuk menyelesaikan penyortiran N bucket yang sangat kasar; membuat partikel menjadi permukaan keluaran N dan menyusunnya dalam celah yang terpisah.

Apa pun lebih lanjut akan memerlukan informasi lebih lanjut tentang kasus penggunaan spesifik Anda. Tapi saya yakin Anda tidak benar-benar membutuhkan kemandirian pesanan. Cukup gunakan partikel yang cukup secara acak dan itu akan baik-baik saja =)

Jari Komppa
sumber
6

Hanya saja, jangan menulis ke buffer kedalaman ketika rendering partikel. Ini akan memungkinkan mereka untuk semua dirender dan dicampur satu sama lain. Anda masih harus melakukan pengujian mendalam sehingga mereka dapat tersumbat dengan baik oleh geometri di tempat kejadian.

KlashnikovKid
sumber
5

Menggunakan urutan campuran aditif tidak masalah:

glEnable(GL_BLEND)
glDepthMask(GL_FALSE)
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA)
DrawParticles();

// Now turn depth masking on and blending off, so state is unchanged.
glDepthMask(GL_TRUE)
glDisable(GL_BLEND)

Ini mengasumsikan bahwa tekstur sprite Anda memiliki latar belakang transparan.

teh_leecherer
sumber