Рисование изометрической карты кусками? - PullRequest
0 голосов
/ 07 сентября 2018

Я хочу уменьшить количество вызовов отрисовки в моей реализации изометрической карты, поэтому я подумал о том, чтобы объединить несколько сеток и нарисовать их за один раз. В настоящее время я создаю сетку из всех плиток размером 8x8. Это означает сетку, содержащую полы, стены и предметы. Эти полы, стены и объекты - это просто квадраты, расположенные вдоль правильной оси, где Y вверх. Вращающаяся ортографическая камера обеспечивает матрицу изометрической проекции. Большинство полов и стен заполняют весь квадрат непрозрачной текстурой, но некоторые, и большинство объектов имеют альфа-прозрачность, например окно, разбитый пол или стул. Я строю «чанковую» сетку, добавляя к ней отдельные сетки, я делаю это для того, чтобы рисовать спереди назад и снизу вверх, иначе комбинированная чанковая сетка вообще не отображается должным образом. Я отрисовываю все необходимые куски также в том же порядке, и это прекрасно работает.

Однако проблемы с рисованием начинаются, когда мне нужно добавить дополнительные объекты «внутри» этих частей сетки. Например, движущийся игрок, который также является просто квадом с прозрачной текстурой. Я должен быть в состоянии поместить его внутрь этой сетки, возможно, на плитку, где он находится перед стеной и за окном. Если бы я рендерил плеер до чанка, его прозрачные пиксели не показывали бы чанк. Если бы я рендерил игрока после чанка, он не был бы виден через прозрачный квад в чанке. Если бы это можно было решить легко и не дорого на CPU / GPU, это было бы решением моего вопроса. Однако я считаю себя новичком в OpenGL, поэтому не очень хорошо знаю, что это за магия.

Я могу придумать решения для решения этой проблемы, не связанные с OpenGL:

  • Дамп метод чанка сетки и просто отодвинуться вперед. Мне либо нужен более эффективный способ рисования, либо я не позволяю уменьшить масштаб, чтобы уменьшить количество вызовов на рисование, поскольку это узкое место.
  • Избавьтесь от четырехугольников с прозрачностью и сделайте их полностью трехмерными. Я чувствую, что это должен быть выбор дизайна, а не обязательная вещь, кроме того, это добавило бы много дополнительной работы для создания всех этих активов. Теперь у меня есть только текстуры, спроецированные на квад, вместо полностью UV моделей с отдельными текстурами.
  • Нарисуйте все прозрачные объекты после кусков в правильном порядке. Это кажется хакерским и подверженным ошибкам, так как некоторые объекты должны входить в эту чанковую сетку, а некоторые нет.
  • Комбинируйте полы только в пакетной сетке. Этажи являются самым большим узким местом, в нижней части карты заполнены все плитки для полов, что составляет около 4000 вызовов для розыгрыша в индивидуальном порядке, большое здание также использует много этажей для каждого уровня Z. Стены и объекты нарисованы значительно меньше, вероятно, всего пара сотен максимум, полностью уменьшенных. Таким образом, для каждого чанка рисуем все этажи одним вызовом, а затем для каждого отдельного объекта, я бы сильно сократил количество вызовов, просто комбинируя этажи. При рисовании стен и объектов я должен проверить, существует ли потенциальный динамический объект для визуализации, или просто проверить, есть ли динамические объекты в блоке, и отсортировать их по всем стенам и объектам перед их рисованием.

Вот как я сейчас рендеринг.

    Gdx.gl.glEnable(GL20.GL_DEPTH_TEST);
    Gdx.gl.glEnable(GL20.GL_BLEND);
    Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);

    shader.begin();
    shader.setUniformMatrix("u_worldView", cam.combined);

    // If I draw the player before the chunk the transparency of the player would not render the chunk.
    player.getMesh().render(shader, GL20.GL_TRIANGLES);

    // Drawing the mesh chunk combines of floors, walls and objects of each tile within the chunk.
    chunk.getCombinedMesh().render(shader, GL20.GL_TRIANGLES);


    // If I draw the player after the chunk the player would not be drawn if it is behind a transparent mesh like a window or a tree.
    player.getMesh().render(shader, GL20.GL_TRIANGLES);     
    shader.end();

Так, каковы мои варианты здесь? Можно ли это исправить, используя некоторые магические приемы из шапки OpenGL? Или у вас есть другое предложение, чтобы положить в список выше? Я использую LibGDX для своего проекта.

...