2015-09-01 6 views
1

Я обрабатываю спрайты в 3d-пространстве, где каждый квадрат формируется с двумя треугольниками. Я рисую GL_TRIANGLES (см. Ниже). Поскольку в этой формации повторяются 2 вершины, вершинный шейдер выполняет в два раза один и тот же расчет.GLSL/OpenGL Повторное использование вывода из вершинного шейдера

5 3, 4 
    *---* 
    | /| 
    |/ | 
    *---* 
    1, 6 2 

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

Теперь, на мой вопрос, есть ли лучший способ сделать это, что на самом деле будет быстрее, чем выполнение всех дополнительных операций вершинного шейдера.

+2

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

ответ

5

Геометрический шейдер для этого не нужен.

Что вам нужно, это индексированный рендеринг: каждая вершина хранится только в VBO после. Затем вы создаете дополнительный буферный объект (связанный с GL_ELEMENT_ARRAY_BUFFER), который хранит индексы вершин, хранящихся в реальном VBO.

Визуализация: (источник: in2gpu.com)

enter image description here

Обратите внимание, что в вашем случае это не что плохо. Например, рассмотрим рисование круга: допустим, вы рисуете его с помощью 360 треугольников (кажется разумным). В этом случае центр вершина будет дублироваться для каждого треугольника - это приведет к 359 * 4 (количество компонентов + выравнивание) * 4 (обычная стоимость sizeof(float)) = 5744 байт ненужных данных:

enter image description here

Далее чтение:


UPDATE

С 2 вершины повторяется в этой формации, вершинные шейдеры делают два раза один и тот же расчет.

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

Так что не оптимизируйте это.Если вы знаете об индексированном рендеринге, но вы либо не можете его использовать, либо не улучшаете, пусть GPU hasle будет наилучшим образом.

+0

Я знаю об индексированном рендеринге. Моя проблема заключается в том, что я не нашел никакой документации о том, будет ли кэшированный результат вершинного шейдера в индексированном рендеринге. Я должен был указать это на мой вопрос, извините. Иногда или, может быть, это не очень хороший ответ. Было бы разумно, если кэширование не будет реализовано. – user1146657

+0

Это и всегда будет, потому что это очень распространенный сценарий. См. Обновление. –

1

Поскольку в этом формировании повторяются 2 вершины, вершинный шейдер выполняет в два раза одинаковые вычисления.

Нет, практически на всех существующих реализациях (например, на графических процессорах) это не так.

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

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

+0

Спасибо. Исследования привели меня к https://www.opengl.org/wiki/Post_Transform_Cache – user1146657

+0

Но кеш вершин применяется только при использовании индексированного чертежа, правильно? Я не знаю точно, но я сомневаюсь, что кеш-вершина закроет фактические значения атрибутов вершин. –

+0

@RetoKoradi: Для всех существующих реализаций: Да. Вот почему вы должны использовать индексированный чертеж, где это возможно. Теоретически вы можете выполнить поиск на основе значений атрибутов вершин, но это будет довольно дорогостоящая операция. Геометрические шейдеры OTOH также не дешевы, поэтому попытка решить эту проблему с использованием геометрического шейдера, скорее всего, не улучшит производительность. – datenwolf