Чи можна побудувати куб з меншою кількістю 24 вершин


14

У мене є світ на основі кубів, як Minecraft, і мені цікаво, чи є спосіб побудувати куб з меншою кількістю 24 вершин, щоб я міг зменшити використання пам'яті.

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

Це так чи я помиляюся? Можливо, є якісь нові модні технології DX11, які можуть допомогти?

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


1
Ви хочете зменшити використання пам'яті графічної картки або використання оперативної пам'яті ?
doppelgreener

1
Дані вершин зберігаються в оперативній пам’яті та на графічному процесорі прямо зараз, тож їх зменшення зменшило б обоє.
Теланор

Відповіді:


9

Якщо вам потрібні лише норми на обличчя, і якщо ваші текстові тексти для обличчя суворо 0/0, 0/1, 1/0, 1/1 (або подібні до вашого макета), ви можете побудувати куб з 8 вертами і або 30 (смуга з перезапуском), або 36 (список). Отримайте нормалі та текстові слова, використовуючи постійний пошук масиву на основі SV_VertexID у вашій вершинній шейдері.

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

У подальшому, ви все ще можете пройти до 24 вертів за куб, але також використовувати інстанціювання. Кожен куб був би фіксованого розміру у вашому вершинному буфері (1x1x1), і ви мали б коефіцієнт масштабування та положення (якщо припустимо, що ваші куби не обертаються, матриця, якщо вони є) як дані per-instance. У випадку, що не обертається, у вас є разова вартість 24 верти, але тоді для кожного куба просто потрібно 6 поплавків, щоб повністю вказати. У обертовому випадку ви дивитесь на 16 поплавців, але навіть це суттєва економія (у цьому випадку ви більше шансів на вузьку сторону процесора на матричних перетвореннях - для не обертового корпусу, що створює матрицю на льоту ваш вершинний шейдер - навіть якщо це робиться за вершиною, настільки нерозумно швидкий, що вам навіть про це не потрібно хвилюватися).

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

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

У моєму двигуні є базовий код, який просто малює купу кубів за допомогою цього методу, і я можу легко пережовувати понад 300 000 кубів, зберігаючи 60 кадрів в секунду, на графічному процесорі порівняно низького рівня, і не роблячи нічого іншого для оптимізації процесу. . Справді, я ні освітлюю, ні текстурую їх, але у мене ввімкнено альфа-змішування, вимкнення фонового режиму вимкнено, і в цілому це врівноважує мою частину "не робити нічого іншого для оптимізації", тому це повинно дати вам розумне уявлення про тип Ballpark ви можете вдарити цим методом.


1
Раніше я використовував екземпляр, і він чудово підходить для кубиків менше 40 кб. Але у мене є щонайменше 256 тис. Кубів, і примірники теж не впоралися з цим. Використання SV_VertexID з пошуком здається дуже перспективним.
Теланор

Наскільки великим був ваш буфер за примірник? Спроба вкласти їх у величезний буфер може в результаті задихнутися у вашому графічному процесорі; Я, як правило, зберігаю буфери для екземплярів на достатньому просторі для об'єктів 64k (при необхідності розділяючи виклики малювання), використовую шаблон відкидання / без перезапису та записую безпосередньо на відображений вказівник замість копіювання з проміжного масиву, що працює дуже добре .
Максим Мінімус

Також важливим є збереження низької кількості карт. Карта / записувати один куб / знімати карту 40 к разів буде набагато повільніше, ніж карта / написати 40 к кубів / зняти карту лише один раз. Якщо ви робили перший, спробуйте перейти на другий.
Максим Мінімус

15

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

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

Зображення нижче демонструє цю концепцію, але в 2D для легшого розуміння. На зображенні є 11 зайнятих блоків (представлених заповненими сірими кругами), для яких зазвичай потрібно 4 х 11 = 44 ребра для зображення (4, оскільки це квадрат, а не куб). Але, як бачите, малювати краї потрібно лише тоді, коли вони стикаються з порожнім квадратом, який у цьому випадку становить лише 8 країв.

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

Якщо таким простим прикладом у 2D вдалося зменшити 44 краю до 8 країв, уявіть собі виграші у великому 3D-світі ...

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

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


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

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

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

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