Подтвердить что ты не робот

OpenGL: одиночный атрибут вершины для нескольких вершин?

У меня есть вершинный шейдер, который принимает следующие атрибуты:

  • a_posCoord: позиция вершин
  • a_texCoord: координата текстуры (передается в шейдер фрагмента)
  • a_alpha: коэффициент прозрачности (передается в шейдер фрагмента)

Объектами, которые я представляю, являются все "рекламные щиты" (пара прямоугольных треугольников для создания прямоугольника).

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

vertexAttributes = [

  px1,py1,pz1, // vertex 1: a_posCoord
  tx1,ty1,     // vertex 1: a_texCoord
  alpha,       // vertex 1: a_alpha

  px2,py2,pz2, // vertex 2: a_posCoord
  tx2,ty2,     // vertex 2: a_texCoord
  alpha,       // vertex 2: a_alpha

  px3,py3,pz3, // vertex 3: a_posCoord
  tx3,ty3,     // vertex 3: a_texCoord
  alpha,       // vertex 3: a_alpha

  px4,py4,pz4, // vertex 4: a_posCoord
  tx4,ty4,     // vertex 4: a_texCoord
  alpha,       // vertex 4: a_alpha

  px5,py5,pz5, // vertex 5: a_posCoord
  tx5,ty5,     // vertex 5: a_texCoord
  alpha,       // vertex 5: a_alpha

  px6,py6,pz6, // vertex 6: a_posCoord
  tx6,ty6,     // vertex 6: a_texCoord
  alpha        // vertex 6: a_alpha

  // ... Many more billboards not shown ...
];

Обратите внимание, что одно и то же значение alpha повторяется 6 раз, один раз для каждой вершины.

Можно ли указать атрибут для всех 6 вершин, не повторяя его для каждой отдельной вершины?

Здесь я хочу, чтобы мой буфер атрибутов вершин выглядел, в интересах уменьшения размера буфера:

vertexAttributes = [
  px1,py1,pz1, // vertex 1: a_posCoord
  tx1,ty1,     // vertex 1: a_texCoord

  px2,py2,pz2, // vertex 2: a_posCoord
  tx2,ty2,     // vertex 2: a_texCoord

  px3,py3,pz3, // vertex 3: a_posCoord
  tx3,ty3,     // vertex 3: a_texCoord

  px4,py4,pz4, // vertex 4: a_posCoord
  tx4,ty4,     // vertex 4: a_texCoord

  px5,py5,pz5, // vertex 5: a_posCoord
  tx5,ty5,     // vertex 5: a_texCoord

  px6,py6,pz6, // vertex 6: a_posCoord
  tx6,ty6,     // vertex 6: a_texCoord

  alpha        // vertex 1-6: a_alpha

  // ... Many more billboards not shown ...
];

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


Это более конкретный вопрос WebGL, но мне интересен OpenGL в общем смысле.

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

4b9b3361

Ответ 1

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

Однако то, что возможно с более новыми версиями OpenGL, устанавливает скорость, с которой продвигается смещение буфера определенного вершины. Эффективно это означает, что данные для заданного массива вершин дублируются до n вершин до смещения буфера для атрибута. Функция для установки этого делителя glVertexBindingDivisor. В вашем случае вы установите разделитель привязки 6 для альфа-массива. Но важно, чтобы это не использовало один атрибут для нескольких вершин, но это делает OpenGL таким дублированием, которое вы делали для вас.

Ответ 2

Если какой-либо атрибут вершины является постоянным для каждой вершины, почему бы вам не использовать единую переменную? Если он постоянный, он является однородным! Таким образом вы устанавливаете равномерное значение только один раз, и ваш набор данных уменьшается.

Ответ 3

Я получаю этот эффект при инстанционном рендеринге. glVertexAttribDivisor(1); делает атрибут openGL read vertex один раз для каждого экземпляра. Если ваши сметы имеют разную геометрию, вы можете рассмотреть возможность передачи вам модельной матрицы в качестве атрибута так же, как и альфа.

Ответ 4

Несколько идей:

1.) Укусите пулю и обновите буфер вершин, но только при изменении альфа.

2.) Разбить список квадов в партии и только перестроить партии, которые меняются.

3.) Контролируйте количество рекламных щитов и привяжите массив альфа-значений к равномерному... В альфах данных вершин или в некотором неиспользуемом канале/дополнительном канале индекс альфы для этого рекламного щита в вашем однородном массиве. по крайней мере, таким образом вы потенциально загружаете только n-альфа-значения.

4.) объединить 2 и 3...

Я только принимаю дикое предположение... Я бы хотел, чтобы у кого-нибудь были хорошие решения!

Ответ 5

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

http://sol.gfxile.net/instancing.html