Ефективний метод надання масивного рельєфу в XNA


10

Я створюю гру XNA, яка потребує величезного місця для гравців. В даний час тестова карта висоти, яку я використовую, становить 4096x4096, і зберігається як 4-бітний BMP.

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

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

Зважаючи на це, я натрапив на ряд рішень, які я перерахував нижче:

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

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

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

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

Оновлення 1: Після дослідження методу геокліпмапування я почав кодувати це. У мене все математика зроблена, і гра працює. Однак це вкрай неефективно - що, мабуть, погано кодує з мого боку. Він працює на 2FPS і використовує ціле ядро ​​мого процесора. Я спробую вдосконалити код, але, думаю, мені знадобиться додаткова допомога, тож ось вставте код для класу менеджера Terrain. Пізніше я відправлю ще більше результатів, якщо коли-небудь я стану більш ефективним.


1
Цікаво, що техніка, про яку ви говорите, схожа на ту, яку використовує програмне забезпечення ID у своїй майбутній грі Rage. Вони використовують 'мегатекст', а потім передають необхідні його частини в GPU. Він говорив про це, але ось стаття з Вікіпедії, це може бути натхненним: en.wikipedia.org/wiki/MegaTexture

Відповіді:


5

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

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

Більш просунуті рендери рельєфу використовують алгоритм для налаштування не тільки видимої геометрії, але й деталей цієї геометрії. Geomipmapping (і його відносне геокліпмапування) на сьогоднішній день є відносно популярним для цього, але це не банальна річ.

редагувати: Ось гідний опис як геокліпмапингу, так і винищення фрустуму.

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


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

3

Будь-який підхід, який вимагає виконання роботи за кадром для завантаження даних на GPU, буде помилковим.

Ось приблизний контур одного підходу, який повинен бути успішним:

Ви повинні ділити свою місцевість на (досить великі) шматки, завантажуючи ці шматки у фіксовані вершинні буфери (бітова глибина карти висоти не має значення!). Ці вершинні буфери просто сидітимуть у пам’яті графічного процесора, чекаючи, коли їх буде зроблено. Вам доведеться поекспериментувати з тим, що є відповідним розміром, але 128x128 - це, мабуть, хороше місце для початку.

Для місцевості розміром 4096x4096 ви трохи за межі того, що мені було б зручно завантажувати відразу на GPU - це, мабуть, кілька сотень МБ даних вершин (хоча ви можете звести його до ~ 64 МБ, якщо ви розумний). Таким чином, можливо, вам доведеться завантажувати та вивантажувати вершинні буфери з GPU у фоновому режимі.

(Якщо ви реалізуєте фонове завантаження фрагментів, це має бути надзвичайно масштабованим!)

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

Ви майже ніколи не повинні робити вимикання на трикутник на процесорі!

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

Для отримання додаткової інформації про продуктивність, перегляньте цю відповідь на сайті Game Dev.


0

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


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