Предотвращение дублирования данных в буферах OpenGL

#opengl #attributes #glsl #shader

#opengl #атрибуты #glsl #шейдер

Вопрос:

Я пытаюсь нарисовать карту, созданную из плиток в OpenGL (версия 3.3 как минимум). Способ, которым я в настоящее время это делаю, заключается в компиляции всех данных вершин из каждого тайла на карте в единый массив и привязке этих данных к буферу внутри массива вершин. Это также относится к нормалям и координатам текстуры; у каждого есть свой собственный буфер. Затем на эти данные появляется указатель атрибута вершины, так что вершинный шейдер получает доступ к ним.

При этом, когда дело доходит до того, что каждая плитка имеет свой собственный цвет, это единый сплошной цвет (не текстура или градиент), я по сути передаю массив того же размера, что и массив вершин, в шейдер, даже если цвет постоянен для всех 6 вершин плитки! Это кажется ужасно расточительным, поскольку это, по сути, те же данные x6. Есть ли способ эффективно повторно использовать одни и те же данные через каждые 6 вершин при рендеринге карты?

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

Текущий метод действительно работает, и он довольно быстрый (2000 кадров в секунду для плиток 256×256 на GT 750m), но я не могу избавиться от чувства вины за то, что просто копирую данные по всему массиву, чтобы они соответствовали каждой вершине, хотя данные постоянны для каждого примитива (фактически 2 примитива: два треугольника, которые составляют квадратную плитку). Конечно, их должен быть лучший способ?

Ответ №1:

У вас есть различные способы решения вашей проблемы.

  1. Палитры: Используйте атрибут вершины (всего один байт), чтобы выбрать для каждого тайла значение из массива из 256 однородных цветов (цвет равен 3/4 байта, поэтому вы просто сэкономили 2/3 байта). Конечно, я предполагаю, что у вас не более 256 разных цветов (вероятно, вы могли бы использовать короткий и до 65536 цветов, если 256 недостаточно)

  2. Геометрия / тесселяционные шейдеры: Если плитки представляют собой просто квадраты или другие простые формы, тогда вам нужно взять в качестве входных данных одну вершину и, учитывая некоторую базовую информацию (например, размер плитки), вы создаете полные примитивы (это просто позволяет вам уменьшить размер данных в 5 или более раз, но вам нужно изучить множество дополнительных функций GL, что в любом случае неплохо)