Як віртуальна текстура може бути фактично ефективною?


27

Для довідки, що я маю в виду це «загальна назва» для техніки першої (я вважаю) ввів з idTech 5'по MegaTexture технології. Подивіться тут відео для швидкого огляду того, як це працює.

Останнім часом я скупив деякі статті та публікації, пов'язані з цим, і те, що я не розумію, це те, наскільки це може бути ефективним. Чи не вимагає постійного перерахунку координат УФ із простору "глобальної сторінки текстур" у координати віртуальної текстури? І як це не обмежує більшість спроб створення геометрії взагалі? Як можна дозволити довільне збільшення масштабу? Невже це в якийсь момент не вимагатиме підрозділення полігонів?

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

Відповіді:


20

Огляд

Основна причина віртуальної текстуризації (VT) або розріджених віртуальних текстур , як її іноді називають, - оптимізація пам'яті. Суть справи полягає лише в тому, щоб перемістити у відеопам'ять фактичні текселі (узагальнені як сторінки / плитки), які можуть знадобитися для візуалізованого кадру. Таким чином, це дозволить вам мати набагато більше текстурних даних в автономному режимі або повільному зберіганні (HDD, оптичний диск, хмара), ніж це було б інакше для відеопам'яті або навіть основної пам'яті. Якщо ви розумієте поняття віртуальної пам’яті, яке використовується сучасними операційними системами, то це те саме за своєю суттю (назва дана не випадково).

VT не вимагає повторного обчислення УФ-виду в тому сенсі, що ви робите це кожен кадр перед тим, як надати сітку, після чого повторно надсилайте дані вершин, але для виконання непрямого пошуку з вхідних УФ потрібні певні суттєві роботи в шейдерах вершин та фрагментів. Однак у гарній реалізації програма повинна бути повністю прозорою для програми, якщо вона використовує віртуальну текстуру або традиційну. Насправді більшу частину часу програма змішуватиме обидва типи текстуризації, віртуальну та традиційну.

Теоретична робота може теоретично працювати дуже добре, хоча я ніколи не розглядав деталі цього. Оскільки звичайними критеріями групування геометрії є текстури, а за допомогою VT кожен полігон у сцені може поділяти однакову "нескінченно велику" текстуру, теоретично ви могли б досягти повного малювання сцени за допомогою 1 виклику малювання. Але насправді інші фактори грають, що робить це непрактичним.

Проблеми з VT

Масштабування / зменшення і різкий рух камери - найскладніші речі, з якими можна впоратися в налаштуваннях VT. Це може виглядати дуже привабливо для статичної сцени, але як тільки речі почнуть рухатися, буде запропоновано більше текстурних сторінок / плиток, ніж ви можете передавати для зовнішнього зберігання. Асинхронізація файлів асинхронізації та нарізка ниток можуть допомогти, але якщо це система в режимі реального часу, як в грі, вам доведеться просто відтворювати кілька кадрів із плитками нижчої роздільної здатності, поки не надійдуть привітання, раз у раз , що призводить до розмитості текстури. Тут немає срібної кулі, і це найбільша проблема з технікою, ІМО.

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

Загалом, VT цікавий, але я б не рекомендував його для всіх. Це може добре працювати, але це важко реалізувати та оптимізувати, плюс там є занадто багато кутових кейсів та виправлень, що стосуються конкретного випадку, необхідних на мій смак. Але для великих ігор із відкритим світом чи програм візуалізації даних це може бути єдино можливий підхід, щоб вмістити весь вміст у доступне обладнання. Маючи багато роботи, можна зробити досить ефективний запуск навіть на обмеженому апаратному забезпеченні, як ми бачимо у версіях PS3 та XBOX360 для Rage id .

Впровадження

Мені вдалося певною мірою змусити VT працювати над iOS з OpenGL-ES. Моя реалізація не "піддається виконанню", але я міг би зробити так, якби хотів і мав ресурси. Ви можете переглянути тут вихідний код , це може допомогти отримати краще уявлення про те, як шматки поєднуються між собою. Ось відео демонстрації, що працює на iOS Sim. Це виглядає дуже мляво, тому що тренажер жахливий для емуляції шейдерів, але він працює безперебійно на пристрої.

Наступна діаграма окреслює основні компоненти системи в моїй реалізації. Він дещо відрізняється від демонстрації SVT Шона (посилання внизу), але архітектурніше наближений до тієї, що представлена ​​у статті Прискорення віртуального текстурування за допомогою CUDA , знайденому в першій книзі GPU Pro (посилання нижче).

система віртуального текстурування

  • Page Filesце віртуальні текстури, вже вирізані плитками (сторінки AKA) як крок попередньої обробки, тому вони готові переміщуватися з диска у відеопам'ять, коли це потрібно. Файл сторінки також містить весь набір mipmap-файлів, які також називаються віртуальними .

  • Page Cache Managerзберігає подання на тексту із застосуванням Page Tableта Page Indirectionтекстур. Оскільки переміщення сторінки з офлайн-пам’яті в пам'ять коштує дорого, нам потрібен кеш, щоб не перезавантажувати вже доступне. Цей кеш дуже простий кеш найменш нещодавно використаних (LRU). Кеш також є компонентом, відповідальним за постійне оновлення фізичних текстур із власним локальним поданням даних.

  • Page ProviderЄ чергою завдань асинхронним , що буде отримувати сторінки , необхідні для даного подання сцени і відправити їх в кеш.

  • Page IndirectionТекстура текстури з одного пікселя для кожної сторінки / плитки в віртуальної текстури, яка буде картировать входять UVs до Page Tableтекстурі кешу , який має фактичні дані текселя. Ця текстура може бути досить великою, тому вона повинна використовувати якийсь компактний формат, наприклад, RGBA 8: 8: 8: 8 або RGB 5: 6: 5.

Але ми все ще не вистачаємо тут ключового фрагмента, і ось як визначити, які сторінки потрібно завантажувати зі сховища в кеш і, отже, в Page Table. Ось тут проходять зворотній зв'язок і Page Resolverвхід.

Пропуск зворотного зв’язку - це попередньо відображення перегляду, із спеціальним шейдером та значно нижчою роздільною здатністю, який запише ідентифікатори потрібних сторінок у кольоровий кадрбуфер. Цей різнокольоровий печворк з куба та кулі вгорі - це фактичні індекси сторінок, кодовані як RGBA-колір. Це виведення заздалегідь пропускається зачитується в основну пам'ять і обробляється з допомогою Page Resolverдля декодування індексів сторінки та запуску нових запитів за допомогою Page Provider.

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

Інші ресурси, які варто перевірити

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


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

1
@Llamageddon, просто так трапляється, що у мене все-таки була діаграма під рукою;) Боюся, псевдо-код буде трохи важко надати, оскільки в ньому є зовсім небагато реального коду. Але я сподіваюся, що розгорнута відповідь допомагає дати загальне уявлення про техніку.
гламперт

3
Варто зазначити, що більшість сучасних апаратних засобів тепер відкриває програмовані таблиці сторінок, виключаючи необхідність текстури перенаправлення. Це піддається, наприклад, зарезервованим ресурсам directx12 , який базується на ресурсах з плиткою directx11 , або рідкісними текстурами opengl .
MooseBoys

1
@Llamageddon, попередній пропуск зворотного зв'язку може бути зроблений за нижчим значенням, щоб зберегти якомога більше обчислень та пам'яті, оскільки пікселі для сторінки зазвичай повторюються (ви можете помітити великі кольорові квадрати в моїй демонстрації). Ви вірно вважаєте, що з часом вона може пропустити видиму сторінку, але це, як правило, не матиме великого візуального впливу, оскільки система завжди повинна зберігати в кеші щонайменше найнижчу карту всього VT. У другому документі, з яким я пов’язаний, є всі приклади шейдерів у додатку, ви також можете посилатися на репо для мого власного проекту, вони схожі.
гламперт

1
@glampert Ahh, бачу; що має сенс. І все-таки я думаю, що існує маса варіантів обробки транспарантів; у переході на ідентифікатор сторінки ви можете затуманити (так що гістограмування побачило б усі сторінки, якщо б не було величезної кількості прозорих шарів), або використовувати k-буферний підхід , або навіть просто базувати прозору резидентну текстуру, на якій об'єкти знаходяться біля камера (на відміну від надання їх у пропуск зворотного зв'язку).
Натан Рід

11

Віртуальне текстурування - це логічний крайнощ текстурних атласів.


Атлас текстури - це одна гігантська текстура, яка містить текстури для окремих сіток всередині неї:

Приклад текстурного атласу

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

Як згадується в коментарях @ nathan-reed, одним з головних недоліків текстурних атласів є втрата режимів обгортання, таких як повтор, затискання, облямування тощо. Крім того, якщо текстури не мають достатньої межі навколо них, ви можете випадково зразок із сусідньої текстури при фільтруванні. Це може призвести до кровотечі артефактів.

Атласи текстур мають одне основне обмеження: розмір. Графічні API встановлюють чітку межу щодо того, наскільки великою може бути текстура. Однак, графічна пам’ять лише така велика. Отже, існує також жорсткий ліміт щодо розміру текстури, що визначається розміром вашого v-ram. Віртуальні текстури вирішують цю проблему, запозичивши поняття з віртуальної пам'яті .

Віртуальні текстури використовують той факт, що в більшості сцен ви бачите лише невелику частину всіх текстур. Отже, лише той підмножина текстур має бути в vram. Решта може бути в основній оперативній пам'яті або на диску.

Є декілька способів його реалізації, але я поясню реалізацію, описану Шоном Барреттом у своїй розмові про GDC . (яку я дуже рекомендую переглянути)

У нас є три основні елементи: віртуальна текстура, фізична текстура та таблиця пошуку.

Віртуальна текстура

Віртуальна текстура являє собою теоретичний мега атлас, який у нас був би, якби у нас було достатньо vram, щоб усе вмістити. Він насправді ніде не існує в пам'яті. Фізична текстура представляє, які дані пікселів у нас фактично є. Таблиця пошуку - це відображення між ними. Для зручності ми розбиваємо всі три елементи на однакові за розміром плитки або сторінки.

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

Спочатку нам потрібно знайти розташування сторінки в межах фізичної текстури. Тоді нам потрібно обчислити розташування УФ всередині сторінки. Нарешті, ми можемо додати ці два компенсації разом, щоб отримати розташування УФ у межах фізичної текстури

float2 pageLocInPhysicalTex = ...
float2 inPageLocation = ...
float2 physicalTexUV = pageLocationInPhysicalTex + inPageLocation;


Розрахунок сторінкиLocInPhysicalTex

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

float2 pageLocInPhysicalTex = lookupTable.Sample(virtTexUV, nearestNeighborSampler);


Обчислення inPageLocation

inPageLocation - це УФ-координата, яка відносно верхнього лівого краю сторінки, а не верхнього лівого усього текстури.

Один із способів обчислити це - віднімаючи УФ у верхньому лівому куті сторінки, а потім масштабування до розміру сторінки. Однак це зовсім небагато математики. Натомість ми можемо використовувати, як представлена ​​плаваюча точка IEEE. IEEE з плаваючою точкою зберігає дробову частину числа серією базових дробів.

введіть тут опис зображення

У цьому прикладі число:

number = 0 + (1/2) + (1/8) + (1/16) = 0.6875

Тепер давайте розглянемо спрощену версію віртуальної текстури:

Проста віртуальна текстура

1/2 біта говорить нам, чи ми знаходимося в лівій половині текстури або в правій. 1/4 біт говорить нам про те, в якій чверті половини ми знаходимося. У цьому прикладі, оскільки текстура розділена на 16, або 4 в бік, ці перші два біти вказують нам, на якій сторінці ми знаходимося. біти повідомляють нам про розташування всередині сторінки.

Решта бітів ми можемо отримати, перемістивши float на exp2 () і викресливши їх fract ()

float2 inPageLocation = virtTexUV * exp2(sqrt(numTiles));
inPageLocation = fract(inPageLocation);

Де numTiles - це int2, що дає кількість плиток на стороні текстури. У нашому прикладі це було б (4, 4)

Тож давайте обчислимо inPageLocation для зеленої точки, (x, y) = (0.6875, 0.375)

inPageLocation = float2(0.6875, 0.375) * exp2(sqrt(int2(4, 4));
               = float2(0.6875, 0.375) * int2(2, 2);
               = float2(1.375, 0.75);

inPageLocation = fract(float2(1.375, 0.75));
               = float2(0.375, 0.75);

Останнє, що потрібно зробити, перш ніж ми закінчимо. В даний час inPageLocation - це УФ-координата у віртуальній текстурі 'простір'. Однак ми хочемо, щоб ультрафіолетова координата у фізичному текстурі "простору". Для цього нам просто потрібно масштабувати inPageLocation за відношенням розміру віртуальної текстури до фізичного розміру текстури

inPageLocation *= physicalTextureSize / virtualTextureSize;



Отже, закінчена функція:

float2 CalculatePhysicalTexUV(float2 virtTexUV, Texture2D<float2> lookupTable, uint2 physicalTexSize, uint2 virtualTexSize, uint2 numTiles) {
    float2 pageLocInPhysicalTex = lookupTable.Sample(virtTexUV, nearestNeighborSampler);

    float2 inPageLocation = virtTexUV * exp2(sqrt(numTiles));
    inPageLocation = fract(inPageLocation);
    inPageLocation *= physicalTexSize / virtualTexSize;

    return pageLocInPhysicalTex + inPageLocation;
}

Я не маю на увазі віртуальне текстурування, найбільш відоме як MegaTexture технологія idTech 5 . Також дивіться це і це . Я бачив це, як згадувалося в огляді багатьох трубопроводів, що надають сучасні двигуни, і в кількох статтях, які використовують аналогічний підхід для тіньових карт. Це має багато спільного з текстурними атласами, так, він певним чином використовує їх, але я не плутаю його з атласами текстур.
Llamageddon

А-а-а. Дякуємо за посилання. Чи можете ви додати їх до питання. Я відповідно
оновлю

3
IMO, головний недолік простих атласів текстур (а не віртуальних текстур) полягає в тому, що ви втрачаєте режими обгортання, такі як повтор і затискання, а кровотеча виникає через фільтрацію / міпмапування - не точність з плаваючою комою. Я був би здивований, побачивши, що точність поплавця стає проблемою для звичайних (невіртуальних) текстур; навіть 16K текстура (максимум, дозволений поточними API) не є достатньо великою, щоб дійсно напружувати плавучу точність.
Натан Рід

@RichieSams Btw, я думаю, що ваша відповідь хороша, навіть якщо на інше питання. Ви повинні зробити запитання з питань запитання.
Llamageddon

Гм, це пояснює це досить добре, хоча я не дуже розумію, як це працює з рівнями мип. Я б хотів, щоб я міг записати свою конкретну проблему з її розумінням, але це
якось ухиляється
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.