Какой лучший способ нарисовать много деревьев

8

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

Образец острова

Проблема, с которой я сталкиваюсь, состоит в том, что, поскольку текстуры прозрачны, я должен нарисовать их сзади вперед. План-б состоит в том, чтобы вызвать использование discard в фрагментном шейдере, но z-порядок дает лучшие результаты:

uniform float uTreeAlpha;
uniform sampler2D uTexture;

varying vec2 vTexCoordOut;

void main (void)
{
  vec4 colour = texture2D(uTexture, vTexCoordOut);
  if (colour.a < 0.1) {
    discard;
  }
  gl_FragColor = vec4(colour.rgb, colour.a * uTreeAlpha);   
}

Вторая проблема заключается в том, что порядок меняется в зависимости от камеры и вида. Я не знаю эффективного способа нарисовать их в OpenGL за один вызов.

В настоящее время мой код рендеринга выглядит следующим образом:

if cameraChangedFromLastTime() then
  sortTreesBackToFront();
end
for i = 0 to trees.size() -1
  drawTree()
end

Где каждый drawTree () устанавливает некоторые формы, устанавливает текстуру, а затем вызывает glDrawArrays (). У меня есть некоторые оптимизации, чтобы пропустить установку текстуры или обновление текстурных координат, если последнее дерево и текущий совпадают, и установить некоторые общие формы вне цикла, и пропустить деревья, которые слишком далеко, но в основном, если у меня есть 3000 деревьев, я иди 3000 раз по кругу.

Рисование каждого дерева в отдельности является убийцей производительности. Если бы я мог нарисовать их одним вызовом или партиями (при сохранении Z-порядка), я бы, вероятно, сделал это в 1/10 времени.

Так как бы я это сделал. Имейте в виду, что мои деревья являются местозаполнителями, и в конечном итоге я получу:

  • Разные сетки для разных деревьев
  • Различные масштабы и углы для деревьев, чтобы дать больше разнообразия
  • Различные текстуры для разных деревьев, потенциально несколько текстур, примененных к сетке (например, оставляет одну текстуру, ствол другой)
  • Деревья все смешаны вместе, поэтому нет простого способа нарисовать один вид, а затем другой
  • Некоторая форма простой циклической анимации (ветки качаются на ветру)
  • Все текстуры будут находиться в одном атласе

Итак, что лучше подходит здесь? Возможно ли сделать рендеринг за один проход? Если бы я использовал glDrawElements, перестраивая индексы, но не вершины, могу ли я достичь этого?

Locka
источник
vterrain.org , см. правый столбец под разделом «Растения» для рендеринга завода, соответствующий левый столбец, «Рендеринг раздела» для уровня детализации / общего ускорения рендеринга. Но будьте осторожны: источник - это больше список научных работ, чем учебник.
Exilyth
Я не знаю много об этом материале. Но проверьте программное обеспечение VUE. Он используется для создания пейзажей с деревьями, горами, атмосферой и многим другим, в 3D. Но я не уверен, поможет ли это в вашей ситуации
user1981248

Ответы:

3

То, что вы хотите, это аппаратное копирование . Примечание: я сделал это в XNA (то есть DirectX), но я не очень разбираюсь в OpenGL. Я уверен, что есть сопоставимая особенность, хотя. По сути, это то, что он связывает вместе вершины вашей модели дерева с другим потоком вершин, который несет мировые координаты для каждого экземпляра.

DrHeinous
источник
1
Эквивалентом OpenGL будет расширение opengl.org/registry/specs/EXT/draw_instanced.txt . Но, для начала, отображение списков в устаревших объектах OpenGL и Vertex Array / Vertex Buffer Objects в современном OpenGL может подойти. В обоих случаях объект / сетка сохраняется в Списке / VAO / VBO, затем каждый экземпляр рисуется с различным преобразованием. Используя статические сетки, данные могут быть загружены один раз, а затем использованы повторно. sol.gfxile.net/instancing.html дает краткий обзор различных методов.
Exilyth
Спасибо, инстансинг - интересная идея. Однако я не смог использовать расширение draw_instanced, так как я использую OpenGL ES 2.0 и работаю над somethign, который работает на всем. Я думаю, возможно, что я могу загрузить различные древовидные сетки в VBO (возможно, с более простыми моделями подальше), z-сортировать, а затем рисовать их в пакетах из буфера индекса, который я собираю для каждого пакета. Я мог бы нарисовать 30 или 40 одновременно.
Лока
2

Прозрачность нужно заказывать только в том случае, если используется неаддитивное смешивание. Для тонны отдаленных рекламных щитов смешивание не нужно (вы действительно не можете видеть это). Рендеринг по крайней мере следующих с прозрачностью выреза (альфа только 1 или 0), и вам не нужно сортировать их.

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

Шон Миддледич
источник
Я экспериментировал с использованием отбрасывания и без сортировки, но результаты выглядят немного блекло - деревья имеют тенденцию сильно перекрываться, поэтому, если нет последовательного порядка, я получаю много попсов, когда одно дерево идет перед другим и " выигрывает "пиксель. Я оставил сброс, потому что все еще случаются столкновения (например, 2 дерева с одинаковым расстоянием от камеры), но это запасной вариант. Я также экспериментировал с рекламными щитами, и эффект слишком ненастоящий, особенно для эстакад.
Лока
Используйте лучшие рекламные щиты. В идеале иметь модель дерева. Создайте спрайт рекламного щита для угла обзора и используйте этот спрайт там, где угол приблизительно совпадает. Для вырезов они лучше всего работают на расстоянии, где вы не видите разницы. Когда вы приближаетесь, вам нужно использовать больше смешанных моделей (может быть, несколько квадов на дерево), или вы можете переключиться на прозрачность экрана.
Шон Миддледич
В какой-то момент вам нужно выяснить приемлемый баланс между качеством и скоростью. Вы не станете «невероятно быстрым» и «идеальным» для большинства сложных сцен на обычном оборудовании.
Шон Мидлдич