Установка цвета соседнего фрагмента через GLSL - PullRequest
1 голос
/ 24 февраля 2011

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

В проекте используется проход рендеринга, посредством которого данная модель рисуется в FBO с уникальными цветами, которые соответствуют UV-координатам на карте текстуры. Затем эти цвета отбираются и преобразуются в координаты изображения, так что карта текстуры для модели может обновляться в зависимости от того, что видно камере. По существу:

Render model to FBO
For each FBO pixel
   1. sample secondary texture based on FBO pixel position
   2. convert color at current pixel to image coordinate for the model's texture map
   3. update model's texture with sampled secondary texture at calculated coordinate
End loop

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

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

Любая помощь / совет с благодарностью. Спасибо!

Ответы [ 2 ]

5 голосов
/ 24 февраля 2011

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

В вашем коде у вас будет три текстуры, соответствующие перечисленным задачам:

  1. вторичная текстура
  2. карта текстуры исходной модели
  3. карта текстуры модели назначения

При первом запуске вы будете использовать (1) и (2) в качестве исходных текстур для рисования в (3). В следующий раз через цикл вы будете использовать (1) и (3) для записи в (2). Затем вы вернетесь к использованию (1) и (2) для записи в (3). И так далее.

Таким образом, (2) и (3) связаны с объектами кадрового буфера с текстурами, поставляемыми в качестве цветового буфера вместо буфера рендеринга.

NVidia создала расширение GL_NV_texture_barrier в 2009 году, которое позволяет вам сжимать (2) и (3) в одну текстуру, если вы четко указали на разделительную линию между тем, где вы читаете, и тем, где вы пишешь. У меня нет опыта, чтобы сказать, насколько широко он доступен.

Попытка чтения и записи в одну и ту же текстуру (как это возможно для FBO) в противном случае приводит к неопределенным результатам в OpenGL. Проблемы с вызовами на аппаратном уровне связаны с кэшированием и мультисэмплингом.

2 голосов
/ 24 февраля 2011

Насколько я понимаю, в OpenGL необходимо выполнить операцию разброса (равномерное пространство в пикселях FBO -> назначение текстуры UV со случайной сеткой).Есть способ сделать это, не такой простой, как вы ожидаете, и даже не такой быстрый, но я не могу найти лучшего:

  • Выполнить вызов отрисовки типа GL_POINTSи размер равен ширине * высоте исходного FBO.
  • Выберите текстуру модели в качестве целевого цветового слоя FBO без прикрепленного слоя глубины
  • В вершинном шейдере вычислите исходную координату экранаиспользуя gl_VertexID.
  • Образец из исходной текстуры FBO, чтобы получить цвет и целевую позицию (при условии, что ваша исходная поверхность FBO была текстурой).Назначьте правильный gl_Position и передайте целевой цвет фрагментному шейдеру.
  • В фрагментном шейдере просто скопируйте цвет на выход.

Это заставит GPU работатьчерез каждый из ваших оригинальных пикселей FBO и разбросайте вычисленные цвета по текстуре назначения.

...