Подход для написания фрагментного шейдера GLSL со сплошным цветом на треугольник / грань - PullRequest
5 голосов
/ 30 июня 2011

У меня есть данные вершин и треугольников, которые содержат цвет для каждого треугольника (лица), а не для каждой вершины. то есть одна вершина совместно используется несколькими гранями, каждая грань потенциально имеет свой цвет.

Как мне подходить к этой проблеме в GLSL, чтобы получить однотонное назначение для каждого рендеринга face ? Вычисление и назначение буфера «цвета вершины» путем усреднения цветов соседних полисов вершины достаточно просты, но это, конечно, приводит к размытому результату, когда цвета интерполируются в фрагментном шейдере.

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

Ответы [ 3 ]

6 голосов
/ 30 июня 2011

Хотя вы, возможно, могли бы сделать это в высокопроизводительном GLSL, правильный способ сделать сплошную штриховку - создать уникальные вершины для каждого треугольника. Это тривиальная петля. Для каждой вершины посчитайте, сколько треугольников делят ее. Вот как часто вы должны повторить это. Убедитесь, что ваш цикл для этого O (n). Затем просто установите цвет каждой вершины или нормаль к цвету треугольника. Снова одна прямая петля. Не пытайтесь оптимизировать для общих цветов, оно того не стоит.

Отредактируйте намного позже, потому что это популярный ответ:

Чтобы сделать плоскость на грани Затенение Вы можете интерполировать положение вершины в мире или пространстве вида. Затем во фрагментном шейдере вычисляем ddx (dFdx) и ddy (dFdy) этой переменной. Возьмите перекрестное произведение этих двух векторов и нормализуйте его - вы получили плоскую норма! Никаких изменений сетки или данных вершин не требуется вообще.

4 голосов
/ 01 июля 2011

OpenGL не имеет атрибутов "per-face".См .:

Как мне указать индивидуальные цвета при использовании индексированных массивов вершин в OpenGL 3.x?

Вот несколько возможных вариантов, которые я вижу:

  1. Разделите индексные массивы и используйте отдельные вершины для каждой грани, как рекомендовано starmole
  2. Создайте индексный массив для каждого используемого цвета.Используйте материалы вместо цветов вершин и измените материал после рисования треугольников из массива индекса для каждого цвета.
  3. Если геометрия позволяет, вы можете убедиться, что последняя вершина, указанная в массиве индекса, имеет правильную вершинуцвет лица, а затем используйте заливку GL_FLAT или используйте фрагментный шейдер только с цветом последней вершины.
3 голосов
/ 02 июля 2011

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

...