Bagaimana cara menerapkan alpha blending dalam adegan 3D yang kompleks?

11

Saya tahu pertanyaan ini mungkin terdengar agak mudah dijawab tetapi itu membuat saya gila. Ada terlalu banyak kemungkinan situasi yang harus ditangani oleh mekanisme pencampuran alfa yang baik, dan untuk setiap Algoritma saya dapat memikirkan ada sesuatu yang hilang.

Ini adalah metode yang saya kira sejauh ini:

  • Pertama-tama saya berpikir tentang penyortiran objek berdasarkan kedalaman, yang satu ini hanya gagal karena Objek bukan bentuk yang sederhana, mereka mungkin memiliki kurva dan mungkin loop di dalam satu sama lain. Jadi saya tidak bisa selalu tahu mana yang lebih dekat dengan kamera.

  • Kemudian saya berpikir tentang menyortir segitiga tetapi yang ini juga mungkin gagal, saya pikir saya tidak yakin bagaimana menerapkannya, ada kasus langka yang lagi-lagi menyebabkan masalah, di mana dua segitiga saling melewati. Sekali lagi tidak ada yang tahu yang mana yang lebih dekat.

  • Hal berikutnya adalah menggunakan buffer kedalaman, setidaknya alasan utama kita memiliki buffer kedalaman adalah karena masalah dengan penyortiran yang saya sebutkan tetapi sekarang kita mendapatkan masalah lain. Karena objek mungkin transparan, dalam satu piksel mungkin ada lebih dari satu objek yang terlihat. Jadi untuk objek mana saya harus menyimpan kedalaman piksel?

  • Saya kemudian berpikir mungkin saya hanya bisa menyimpan kedalaman objek paling depan, dan menggunakan itu menentukan bagaimana saya harus memadukan panggilan menggambar berikutnya pada piksel itu. Tapi sekali lagi ada masalah, pikirkan tentang dua pesawat semi transparan dengan pesawat padat di tengahnya. Saya akan membuat pesawat solid pada akhirnya, orang bisa melihat pesawat yang paling jauh. Perhatikan bahwa saya akan menggabungkan setiap dua pesawat sampai hanya ada satu warna yang tersisa untuk piksel itu. Jelas saya dapat menggunakan metode penyortiran juga karena alasan yang sama saya jelaskan di atas.

  • Akhirnya satu-satunya hal yang saya bayangkan dapat bekerja adalah untuk membuat semua objek menjadi target render yang berbeda dan kemudian mengurutkan lapisan-lapisan itu dan menampilkan hasil akhirnya. Tapi kali ini saya tidak tahu bagaimana saya bisa mengimplementasikan algoritma ini.

Ali1S232
sumber

Jawaban:

11

Jawaban singkat

Lihatlah ke dalam peeling yang dalam . Dari penelitian saya ini tampaknya menjadi alternatif terbaik, walaupun mahal secara komputasi karena memerlukan beberapa rendering pass. Berikut ini adalah implementasi yang lebih baru dan lebih cepat , juga oleh NVIDIA.

Jawaban panjang

Itu pertanyaan yang sulit . Sebagian besar buku yang saya baca membaca subjek dan meninggalkannya di:

Mulailah dengan merender semua objek buram dan kemudian membaurkan objek transparan di atasnya dalam urutan back-to-front.

Lebih mudah diucapkan daripada dilakukan, karena pendekatan yang jelas dari pemilahan objek oleh centroid mereka tidak menjamin urutan pengurutan yang benar.

Ini persis masalah yang sama mengapa algoritma pelukis tidak bekerja untuk kasus umum dan penyangga kedalaman diperlukan.

Dengan itu, salah satu buku yang saya miliki menyebutkan beberapa solusi:

  • Mengupas kedalaman - solusi multi-pass yang mengatasi keterbatasan buffer kedalaman dengan memberikan kami fragmen ke-n terdekat, bukan hanya yang terdekat. Keuntungan terbesar adalah Anda dapat membuat objek transparan dalam urutan apa pun, dan tidak perlu disortir. Ini bisa mahal karena beberapa lintasan tetapi tautan yang saya berikan di atas tampaknya meningkatkan kinerja.

  • Stencil Routed K-Buffer - Gunakan perutean stensil untuk menangkap banyak lapisan fragmen per piksel per lintasan geometri. Kerugian utama adalah bahwa fragmen perlu disortir dalam pass pasca-pemrosesan.

Itu juga menyebutkan solusi perangkat keras untuk masalah tersebut, tapi saya rasa itu tidak benar-benar tersedia:

  • Buffer-F - A Rasterization-Order Buffer FIFO untuk Multi-Pass Rendering. Meskipun demikian bacaan yang baik dan pendahuluan juga berbicara sedikit tentang masalah tata urutan dan solusi saat ini.

Penanganan lain yang tidak memberikan hasil sempurna tetapi lebih baik daripada tidak sama sekali:

  • Setelah merender semua objek buram, tetap gunakan pengujian Z-buffer untuk objek transparan tetapi nonaktifkan penulisan buffer-Z . Anda mungkin mendapatkan beberapa artefak dari pengurutan yang salah tetapi setidaknya semua objek transparan akan terlihat.

Dan mengutip whitepaper F-buffer di atas:

Solusi paling sederhana adalah membuat setiap poligon transparan sebagian sepenuhnya independen (yaitu membuat semua lintasannya sebelum melanjutkan ke poligon berikutnya). Solusi ini biasanya sangat mahal karena biaya perubahan-negara yang dikeluarkan. Atau, aplikasi atau pustaka naungan dapat mengelompokkan poligon untuk memastikan bahwa hanya poligon yang tidak tumpang tindih yang disatukan. Dalam kebanyakan kasus, solusi ini juga tidak menarik, karena membutuhkan perangkat lunak untuk melakukan analisis layar-ruang poligon.

David Gouveia
sumber
11

Jawaban yang benar adalah # 1: urutkan semua barang Anda secara mendalam dan renderkan (jelas matikan tulisan, tetapi jangan diuji). Apa itu "benda"?

Setiap "benda" harus berupa objek cembung; itu tidak bisa saling tumpang tindih. Jika Anda memiliki objek yang cekung, maka objek itu harus dipecah menjadi potongan-potongan cembung.

Ini adalah yang cara standar rendering adegan transparan. Apakah itu menyelesaikan kasus yang saling menembus? Tidak. Apakah itu memecahkan kasus di mana Anda memiliki 3 objek di mana tidak ada urutan kedalaman dapat ditentukan? Tidak. Apakah itu memecahkan kasus di mana Anda memiliki objek panjang yang tumpang tindih dengan yang kecil yang lebih dekat di kedalaman pusatnya? Tidak.

Tapi itu cukup berhasil . Game tidak menggunakan peeling dalam. Mereka tidak menggunakan k-buffer yang diarahkan stensil. Mereka tidak menggunakan buffer-F. Mengapa? Karena hal-hal ini sangat lambat.

Anda dapat memperoleh artefak dengan metode standar. Tapi setidaknya gim Anda berjalan cukup cepat.

Jika Anda ingin membatasi diri pada DX11 atau perangkat keras yang lebih baik, ada cara untuk menerapkan blending dengan penyortiran yang tepat. Mereka lebih lambat, tetapi tidak hampir lambat seperti teknik sebelumnya. Dan tidak seperti peeling dalam yang bisa menghasilkan artefak, yang ini akurat sampel. Plus, kinerja algoritma umumnya per-fragmen (dan sampai taraf tertentu per tumpang tindih dalam setiap fragmen). Jadi, jika Anda tidak menggambar banyak hal transparan, kinerjanya minimal.

Saya tidak tahu apakah teknik ini memiliki nama yang rumit , tetapi satu implementasi untuk pra-GL4.2 dapat ditemukan di sini. Versi D3D11 dapat ditemukan di sini (Powerpoint, PPSX, kompatibel dengan Libre).

Nicol Bolas
sumber
Poin bagus dalam jawaban ini. Saya pribadi juga puas dengan cukup baik (yang saya jelaskan pada jawaban saya, sebagai solusi) karena sebagian besar teknik yang saya daftarkan mungkin lebih banyak masalah daripada nilainya. Juga, teknik yang menarik pada akhirnya, saya tidak berpikir itu terdaftar pada Real-Time Rendering di mana saya meneliti jawaban saya. Saya noob yang lengkap ketika datang ke fitur level DX11.
David Gouveia
"satu implementasi untuk pra-GL4.2 dapat ditemukan di sini" 404
Jeroen van Langen