Как эффективно визуализировать большую сетку ландшафта?

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 и отбраковки, чтобы пропустить рендеринг скрытых фрагментов.

  • Расстояние просмотра - это то, с чего вы начинаете. Вы будете рендерить куски только на заданном расстоянии, например, на расстоянии обзора вашей камеры. Чем меньше расстояние обзора, тем выше производительность, поскольку нужно рисовать меньше кусков местности.

  • Отбор Frustum - это обычная техника для визуализации только тех сеток, которые пересекаются с усечением камеры. Это, скорее всего, даст вам наибольший прирост производительности.

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

  • Отбор окклюзии может быть выполнен путем рендеринга мешей на процессоре с очень низким разрешением. Это позволяет раннее обнаружение мешей, скрытых за другими. Их не нужно отправлять в графический процессор, поэтому вы сохраняете много исполнений вершинных шейдеров, которые в противном случае выполнялись бы до отклонения треугольников.

  • Уровень детализации означает, что вы вычисляете ячейки с более низким разрешением. Исходя из расстояния до камеры, вы выбираете одну из сеток для рисования. Это позволяет уменьшить количество вершин, так как куски далеко не нуждаются в такой большой детализации. Этот подход хорошо подходит для октодеревьев, поскольку вы можете объединить несколько кубов в одну сетку низкого разрешения для областей, удаленных от камеры. Однако нетривиально объединить края между двумя фрагментами с разным разрешением.

Данияр
источник