Что для более эффективного рендеринга вокселов: готовый VBO или геометрический шейдер?

26

Учитывая довольно статичный массив вокселей, что более эффективно: использование ЦП для предварительной генерации VBO для рендеринга граней вокселей (без учета более продвинутых форм рендеринга, например, марширующих кубов) или использование геометрического шейдера в графическом процессоре для генерации лица на лету?

Я не беспокоюсь об обновлении смены вокселей, но, конечно, это преимущество GPU-версии, поскольку вам не нужно перестраивать VBO. Кроме того, подход GS чувствует себя немного более современным :)

С другой стороны, я не рассматривал детали того, как GS на самом деле работает с конвейером растеризации в современных графических процессорах. Выводит ли он вершины в своего рода потоковый кеш или вершины записываются в обычную память графического процессора между ними? Если это последнее, то генерация на лету может уменьшить доступную полосу пропускания и вычислительную мощность по сравнению с остальными задачами с графическим процессором, и тогда было бы выгоднее делать это на процессоре.

Бьорн Везен
источник

Ответы:

9

Я имею в виду сцену типа Minecraft, где под вокселем вы подразумеваете мир блоков, которые на самом деле визуализируются с использованием полигонов:

Если вы используете геометрический шейдер, вам будет трудно избежать ровно трех граней (или чего-то еще) на воксель.

Если у вас есть много смежных блоков, которые имеют одинаковую текстуру, вы можете использовать мозаику текстур, чтобы иметь гораздо меньше треугольников в вашей (вырожденной) полосе в подходе VBO. Я имею в виду, что если есть хороший большой плоский участок 6x6 вокселей травы, вы можете нарисовать всю вершину всего за 2 треугольника, а не за 64.

При подходе GS вы не можете выполнять тривиальный отбор граней, перекрытых соседними вокселями, что также очень просто при подходе VBO.

Я не пробовал подход GS, но могу сказать, что подход VBO с объединением повторяющихся соседних плиток работает очень хорошо. Я обнаружил, что возиться с индексами элементов гораздо медленнее, чем просто повторять вершины. Если вы разделите свой мир на маленькие кубики, вы обычно можете использовать только один байт на компонент для каждой вершины и даже упаковать информацию о текстуре и нормали (у грани на выровненном по оси кубе есть только 3 возможных нормали) и т. Д. В четвертый байт, чтобы сделать 4 байта на вершину, что приятно и быстро.

Я использовал отдельные VBO для каждой из 6 граней - вам, очевидно, нужно всего лишь нарисовать не более 3 из них. Это прекрасно согласуется с различными текстурами, обычно используемыми в верхних частях вокселей в стиле Minecraft. Потому что для каждого набора нормальное и таковое тогда одинаково.

С использованием вертикально-мозаичных растровых изображений в атласе с GL_REPEATгоризонтальной осью и с поворотными на 90 градусов версиями растровых изображений в одном и том же атласе я обнаружил, что могу рисовать огромное количество явно разных блоков, используя один и тот же VBO в одном вызове. В примере с площадью травы 6х6 я бы разбил это на 12 треугольников, поскольку я повторял только одно измерение в моем атласе.

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

Будет
источник
3
Вам нужно нарисовать не более 3 граней на каждый воксел, но вам может потребоваться нарисовать разные грани для каждого вокселя в зависимости от точки обзора, так что оптимизация не так проста, верно? Готовый VBO будет содержать более одного вокселя. Если ваша точка зрения находится между вокселями, вы увидите восточную сторону одного и западную сторону другого. Единственный способ, которым это могло бы помочь, - это то, что вы можете тривиально отбирать фактические грани, обращенные назад, но в худшем случае вы по-прежнему визуализируете 5 из 6 сторон в группе вокселей. Если ваша точка обзора находится за пределами осевых границ VBO, то вам нужно только визуализировать 3 стороны.
Бьорн Везен
Пятно на Бьорне, это выполнимо. (Но я создаю VBO для блоков по мере необходимости и пересматриваю то, что я построил, когда камера движется, вместо того, чтобы постоянно иметь весь мир в VBO; так что у меня есть естественное время, чтобы сделать этот выбор)
Will
10

Как насчет третьего варианта, использующего инстансированные массивы? По сути, вы рисуете множество блоков (сделанных из простого 8-вершинного куба) одним вызовом отрисовки, выбирая позиции (и другие данные) в качестве атрибутов для каждого экземпляра из VBO Voxel-data ( glVertexAttribDivisorя уверен, используя OpenGL) У DX это тоже есть). Это может быть быстрее, чем подход геометрического шейдера, хотя код приложения (не шейдер) должен быть довольно похожим, поскольку я помню, что геометрические шейдеры имеют репутацию медленных, хотя у меня нет опыта работы с ними (или создания экземпляров), так как я до сих пор сижу на 2.1 аппаратно.

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

Крис говорит восстановить Монику
источник
Да, это лучшее решение этой проблемы. Почему не произошло со мной? :)
Notabene
После некоторых экспериментов я должен сказать вам, что запеченная геометрия намного лучше любого экземпляра. Я еще не пробовал геометрические шейдеры.
Яри ​​Комппа
@JariKomppa Вы ​​можете уточнить, что вы подразумеваете под запеченной геометрией?
Стивен Лу
Экземпляры предварительно переведены и скопированы в одну сетку. Например, иметь одну сетку, которая представляет сто кубов или что-то еще.
Яри ​​Комппа
@JariKomppa Я видел те же результаты, где создание меша происходит намного быстрее. Однако на GTX 680 опция инстансинга работает намного быстрее, странно.
Леви Х
1

Геометрия шейдерной версии звучит для меня намного лучше. Вы можете иметь только точку VBO и поле построения на лету (точка входа, поток выходного треугольника). Он будет быстрым (даже быстрее, если вы будете использовать модуль тесселяции в шейдерной модели 5 экв. DX11) и значительно сократит полосу пропускания, это будет хорошим и чистым решением.

О ГС. Он помещается между вершинным шейдером и пиксельным шейдером и изменяет исходящий поток вершин (примитивов). В то время как вершинный шейдер работает только с вершинами, геометрический шейдер работает с целыми примитивами. Вывод этого потока идет только в пиксельный шейдер (и перед этим растеризуется, конечно же, :)), и сохранить его невозможно. (Может быть, с помощью какого-то сумасшедшего рендеринга в текстуру и последующего синтаксического анализа ... но реальной возможности нет)

Замечание по производительности: Вы должны быть способны ко всему в геометрическом шейдере и пропустить (просто передать данные) вершинный шейдер. Но это не лучший способ. Лучше (быстрее) выполнить большинство возможных преобразований в вершинном шейдере и попытаться свернуть программу геометрического шейдера. Не бойтесь использовать для цикла, если он вам понадобится (например, для создания коробки). Компилятор развернет его для вас.

NotaBene
источник
2
Это может быть хорошей идеей проверить наличие смежных вокселей в геометрии и / или вершинном шейдере и отбросить вершины или пропустить грани, если они закрыты. В противном случае решение GS увеличит используемую полосу пропускания.
Тамши
Bandwith не будет большой проблемой (из моего опыта), но, конечно, это правда. И вы не можете искать в других примитивах в GS (это я знаю :)).
Notabene
@Tamschi: да, эта проблема возникла у меня сразу после написания этого вопроса ... для версии с ЦП вокселы в середине тела подавляются, но это может быть невозможно на GPU без предварительного прохода, что может составить дифференцирование ..
Бьорн Везен
1
Вы можете привязать буфер вершин к униформе isamplerBuffer или usamplerBuffer в шейдере, а затем выполнить поиск с текстурой (name_of_uniform, index). Другой вариант - привязать буфер к единому массиву, что даст вам больше свободы в том формате вершин, который вы хотите использовать.
Тамши