Як ефективно візуалізувати велику рельєфну сітку?


10

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

Хтось сказав мені, щоб вручну розділити модель всередині такого програмного забезпечення, як Blender, але, на жаль, це також неможливо, оскільки ці місцевості створюються шматками в іншому програмному забезпеченні та завантажуються після гри (це ідея). Тому це було б великою роботою, щоб зобов’язати кожен раз їх вручну нарізати.

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

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

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

Відповіді:


12

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

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

// Load vertices from disk
struct point { double x, y, z; };    
vector<point> vertices;

// Create container for chunks
typedef pair<int, int> key;
unordered_map<key, vector<point>> chunks;
const int chunksize = 10;

// For each vertex
for (int i = 0; i < vertices.size(); ++i) {
    // Fetch global coordinates
    int x = vertices[i].x,
        y = vertices[i].y,
        z = vertices[i].z;

    // Find containing chunk
    key k;
    k.first  = x / chunksize;
    k.second = z / chunksize;

    // Calculate local coordinates
    point p;
    p.x = x % chunksize;
    p.y = y;
    p.z = z % chunksize;

    // Add to chunk
    chunks[k].push_back(p);
}

// Create separate buffers for each chunk
// ...

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

  • Відстань перегляду - це місце, де ви починаєте. Ви будете виводити шматки лише на певну відстань, наприклад, відстань перегляду камери. Чим менша відстань огляду, тим вища продуктивність, оскільки потрібно намалювати менше шматочків місцевості.

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

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

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

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

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