Що для рендерингу вокселів, що ефективніше: попередньо виготовлений VBO або шейдер для геометрії?


26

Враховуючи досить статичний масив вокселів, що є більш ефективним: використання процесора для попереднього генерування VBO для візуалізації облич вокселя (ігнорування на сьогодні більш досконалих форм візуалізації, як маршируючих кубів) або використання шейдера геометрії на графічному процесорі для створення обличчя на льоту?

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

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

Відповіді:


9

Я думаю про сцену типу Minecraft, де під вокселем ви маєте на увазі світ блоків, які насправді відображаються за допомогою полігонів:

Якщо ви використовуєте шейдер для геометрії, буде важко уникнути наявності рівно трьох граней (або будь-яких) на воксель.

Якщо у вас є багато сусідніх блоків, що мають однакову текстуру, тоді ви можете використовувати плитку текстур, щоб у вашій (виродженій) смужці було набагато менше трикутників у підході VBO. Я маю на увазі, якщо є хороша велика плоска 6x6 трав'яних вокселів, ви можете намалювати всю вершину всього в 2 трикутники, а не в 64.

Із підходом GS ви не можете здійснити тривіальне відсікання облич, заткнутих суміжними вокселями, що дуже прямо і при підході VBO.

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

Я використав окремі VBO для кожної з 6 граней - вам потрібно коли-небудь намалювати максимум 3 з них, очевидно. Це добре поєднується з різними текстурами, які зазвичай використовуються у верхній частині вокселів у стилі minecraft. Тому що для кожного набору нормальне і таке тоді є рівномірним.

Використовуючи вертикально викладені пікселі в атласі з GL_REPEATгоризонтальною віссю та маючи повернені на 90 градусів версії пікселів у тому ж атласі, я виявив, що я можу намалювати величезну кількість очевидно різних блоків, використовуючи один і той же VBO в одному дзвінку. У прикладі трави 6х6 я розділив би її на 12 трикутників, оскільки я повторюю лише один вимір у своєму атласі.

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


3
Вам потрібно намалювати максимум 3 обличчя на воксель, але вам може знадобитися намалювати різні обличчя для кожного вокселя залежно від точки зору, щоб оптимізація була не такою простою? Попередньо виготовлений VBO міститиме більше одного вокселя. Якщо ваша точка зору знаходиться між вокселями, ви побачите східну сторону однієї та західну сторону другої. Єдиний спосіб, який це допоможе, - це те, що ви можете тривіально викреслити фактичні обличчя назад, але найгірший випадок, все-таки ви представляєте 5 з 6 сторін у групі вокселів. Якщо ваша точка зору виходить за осьові межі VBO, то вам потрібно зробити лише 3 сторони.
Bjorn Wesen

Пляма на Бьорні, її виконана. (Але я створюю РВО для блоків по мірі необхідності і переглянути те , що я побудував , коли камера рухається, а не маючи весь світ в РВО в усі часи, так що у мене є природне час , щоб зробити цей вибір)
Will

10

Що з третім варіантом, використовуючи вбудовані масиви? В основному ви малюєте безліч полів (виготовлених з простого 8-вершинного куба) за допомогою одного виклику малювання, пошуку позицій (та інших даних) як атрибутів на примірник з VBO-даних Voxel (використовуючи glVertexAttribDivisorOpenGL, я впевнений У DX теж є). Це може бути швидше, ніж підхід до геодезичного шейдера, хоча код програми (не шейдер) повинен бути досить схожим, оскільки я пам’ятаю, що шейдери з геометрії мають репутацію повільності, хоча я не маю досвіду роботи з ними (або з інстанцією), оскільки я все ще сиджу на обладнання 2.1.

Але в будь-якому випадку, або шейдери геометрії, або вбудовані масиви повинні більше підходити, ніж вбудована процесором геометрія вокселів, особливо коли дані вокселів можуть змінюватися. У поєднанні з зворотним зв'язком трансформації (вихідний потік у DX?) Ви можете встановити добру техніку відсікання на основі GPU.


Так, це найкраще рішення цієї проблеми. Чому мені не сталося? :)
Нотабене

Після деяких експериментів я мушу сказати вам, що запечена геометрія б’є будь-які наміри з великим запасом. Я ще не пробував шейдери з геометрії.
Jari Komppa

@JariKomppa чи можете ви детальніше розібратися, що ви маєте на увазі під запеченою геометрією?
Стівен Лу

Примірники попередньо перекладені та скопійовані в одну сітку. Наче мати одну сітку, яка представляє сто кубів чи що завгодно.
Jari Komppa

@JariKomppa Я бачив ті самі результати, де створення сітки набагато швидше. Однак на gtx 680 варіант видачі, як видається, працює набагато швидше, дивно.
Леві Н

1

Версія шейдера з геометрії для мене звучить набагато краще. Ви можете мати лише точку vbo та сконструювати поле на льоту (точка введення, вихідний трикутник потоку). Це буде швидко (навіть швидше, якщо ви будете використовувати блок tessellation в шейдері моделі 5 екв. DX11) і зменшите пропускну здатність надзвичайно, це буде приємним і чистим рішенням.

Про ГС. Він розміщується між вершинним шейдером та піксельним шейдером та модифікує потік вершини (примітивів). Хоча вершина шейдера працює лише на вершинах, шейдер геометрії працює на цілих примітивах. Вихід цього потоку спрямовується лише на піксельний шейдер (і він растеризується до цього поза курсом :)), і немає можливості його зберегти. (Можливо, за допомогою божевільного відтворення текстури, а потім її розбору ... але реальної простої можливості немає)

Примітка щодо продуктивності: Ви повинні мати можливість у всьому шадері геометрії та пропускати (просто передавати дані) вершинні шейдери. Але це не найкращий спосіб. Краще (швидше) - зробити більшість можливих перетворень на вершинній шейдері та спробувати мінімізувати програму шейдерів геометрії. Не бійтеся використовувати для циклу, якщо він вам знадобиться (наприклад, для створення коробки). Компілятор розкрутить його за вас.


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

Bandwith не буде великою проблемою (з мого досвіду), але, звичайно, це правда. І ви не можете шукати інших примітивів у GS (це я знаю :)).
Нотабене

@Tamschi: так, ця проблема виникла у мене відразу після написання цього питання. Для CPU-версії вокселі посеред твердих тіл придушуються, але це може бути неможливо для GPU без попереднього проходу з тим, що було б рівним розрізнення ..
Бьорн Весен

1
Ви можете прив’язати вершинний буфер до рівномірного формату isamplerBuffer або usamplerBuffer у шейдері, а потім зробити пошук з текстурою (name_of_uniform, index). Іншим варіантом буде прив’язання буфера до рівномірного масиву, що дає більше свободи у тому, який формат вершин ви хочете використовувати.
Тамщі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.