Як правильно реалізувати альфа-змішування у складному 3D-сцені?


11

Я знаю, що це питання може здатися досить легко відповісти, але це зводить мене з розуму. Занадто багато можливих ситуацій, з якими має справлятися хороший механізм змішування альфа, і для кожного алгоритму я можу придумати, що щось не вистачає.

Це методи, про які я хотів поки що:

  • Перш за все, хоч щодо сортування об’єктів за глибиною, цей просто не вдається, оскільки об'єкти не є простими формами, вони можуть мати криві і можуть петляти всередині один одного. Тому я не завжди можу сказати, хто з них ближче до камери.

  • Тоді я подумав про сортування трикутників, але цей також може провалитись, думав, що я не впевнений, як його реалізувати. Є рідкісний випадок, який може знову викликати проблему, коли два трикутника проходять один через одного. Знову ніхто не може сказати, хто з них ближче.

  • Наступне, що було використати буфер глибини, принаймні, головна причина, що у нас буфер глибини - через проблеми з сортуванням, про які я згадував, але тепер ми отримуємо ще одну проблему. Оскільки об'єкти можуть бути прозорими, в одному пікселі може бути видно більше одного об’єкта. Тож для якого об’єкта я повинен зберігати глибину пікселів?

  • Тоді я подумав, що, можливо, я можу зберігати лише саму глибину переднього об'єкта, і за допомогою цього визначаю, як слід поєднувати наступні дзвінки з виведенням у цей піксель. Але знову виникла проблема, подумайте про дві напівпрозорі площини із суцільною площиною посередині. Я збирався вивести суцільну площину в кінці, видно найбільш віддалену площину. Зауважте, що я збирався об'єднати кожні дві площини, поки не залишиться лише один колір для цього пікселя. Очевидно, я можу використовувати й методи сортування через ті самі причини, які я пояснював вище.

  • Нарешті, єдине, що я думаю, що я можу працювати - це рендеринг усіх об'єктів у різні цілі візуалізації, а потім сортування цих шарів та показ кінцевого результату. Але цього разу я не знаю, як можна реалізувати цей алгоритм.

Відповіді:


11

Коротка відповідь

Загляньте в глибинний пілінг . З мого дослідження, здається, це найкраща альтернатива, хоча і обчислювально дорога, тому що вимагає декількох пропусків рендерінгу. Ось ще одна остання і швидша реалізація , також від NVIDIA.

Довга відповідь

Це складне питання. Більшість книг, які я читав, проглядають тему і залишають її за адресою:

Почніть з надання всіх непрозорих об'єктів, а потім змішайте прозорі об’єкти зверху в порядку "назад-вперед".

Простіше сказати, ніж зробити, хоча очевидний підхід до сортування об'єктів за їхніми центроїдами не гарантує правильного порядку сортування.

Це точно та сама проблема, чому алгоритм художника не працює для загального випадку і потрібен буфер глибини .

Зважаючи на це, в одній із книг я згадую кілька рішень:

  • Глибокий пілінг - багатопрохідне рішення, яке долає обмеження буфера глибини, даючи нам n-і найближчі фрагменти, а не лише найближчий. Найбільша перевага полягає в тому, що ви можете відображати прозорі об’єкти в будь-якому порядку, і немає необхідності в сортуванні. Це може бути дорогим через кілька пропусків, але посилання, яке я дав у верхній частині, здається, покращує продуктивність.

  • Трафарет K-Buffer Трафарет - Використовуйте трафарет трафарету для зйомки декількох шарів фрагментів на піксель за пропуск геометрії. Основним недоліком є ​​те, що фрагменти потрібно сортувати в проході після обробки.

Він також згадує апаратне рішення проблеми, але я не думаю, що він фактично доступний:

  • F-Buffer - буфер FIFO для замовлення на розсип для багатопрохідної візуалізації. Тим не менш, добре прочитане та вступ також трохи розповідає про проблему порядку замовлення прозорості та поточні рішення.

Інші способи вирішення, які не дають ідеальних результатів, але краще, ніж нічого:

  • Після надання всіх непрозорих об'єктів продовжуйте використовувати тестування Z-буфера для прозорих об'єктів, але вимкніть запис Z-буфера . Ви можете отримати артефакти від неправильного сортування, але принаймні всі прозорі об’єкти будуть видні.

І цитуючи довідку F-буфера вище:

Найпростіше рішення - зробити кожен частково прозорий багатокутник повністю самостійно (тобто зробити всі його проходи, перш ніж перейти до наступного багатокутника). Таке рішення, як правило, є надмірно дорогим через витрати, пов'язані зі зміною держави. Альтернативно, бібліотека додатків або затінення може групувати багатокутники, щоб забезпечити, що лише полігони, що не перекриваються, відображаються разом. У більшості випадків це рішення також не є привабливим, оскільки воно вимагає програмного забезпечення для аналізу екранного простору полігонів.


11

Правильна відповідь №1: сортуйте всі ваші речі за глибиною та відтворіть їх (очевидно, вимкніть написання глибини, але не тестуйте). Що таке "річ"?

Кожна «річ» повинна бути опуклим предметом; він не може самостійно перекриватися. Якщо у вас є увігнутий предмет, він повинен бути розбитий на опуклі шматочки.

Це стандартний спосіб візуалізації прозорою сцени. Чи вирішує це взаємопроникні випадки? Ні. Чи вирішує він випадки, коли у вас є 3 об'єкти, де не можна визначити порядок глибини? Ні. Чи вирішує він випадки, коли у вас довгий предмет, який перекривається маленьким, ближче по глибині до центру? Немає.

Але це працює досить добре . Ігри не використовують глибинний пілінг. Вони не використовують трафіковані k-буфери, спрямовані за трафаретом. Вони не використовують F-буфери. Чому? Тому що ці речі неймовірно повільні.

Ви можете отримати артефакти за допомогою стандартного методу. Але принаймні ваша гра працює досить швидко.

Якщо ви готові обмежитися DX11 або кращим обладнанням, існують способи впровадження сумішування за допомогою правильного сортування. Вони повільніші, але майже не такі повільні, як попередні методи. І на відміну від глибинного пілінгу, який може впроваджувати артефакти, цей приклад точний. Плюс, ефективність алгоритму, як правило, за фрагментом (і певною мірою на перекриття у кожному фрагменті). Тож якщо ви не намалювали багато прозорих речей, продуктивність мінімальна.

Я не знаю, чи має ця техніка пікантне ім'я, але одну реалізацію для pre-GL4.2 можна знайти тут. Тут можна знайти версію D3D11 (Powerpoint, PPSX, сумісна з Libre).


Хороші моменти у цій відповіді. Я особисто також погодився би з достатньо хорошим (що я описав у своїй відповіді як вирішення проблеми), оскільки більшість перерахованих нами методів, мабуть, більше проблем, ніж вони варті. Крім того, цікава техніка наприкінці, я не думаю, що вона була включена до рендерингу в реальному часі, на якому я досліджував свою відповідь. Я повна ноб, коли мова йде про функції рівня DX11.
Девід Гувейя

"одну реалізацію для pre-GL4.2 можна знайти тут" 404
Jeroen van Langen
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.