Как заменить единый массив GLSL на одномерную текстуру

Я пытаюсь заставить систему ландшафта Ardor3D работать на оборудовании SM3.0.

Текущий шейдер фрагмента GLSL использует однородный массив vec2 для передачи массива координат xy в шейдер фрагмента.

Поскольку динамические индексированные однородные массивы работают только на оборудовании SM4.0 +, чтобы заставить его работать на SM3.0, мне нужно заменить его 1D текстурой с плавающей запятой.

Текущий массив выглядит так: uniform vec2 sliceOffset[8];

и к нему обращаются так: vec2 offset = sliceOffset[int(unit)];

У меня большой опыт работы с OpenGL и GLSL, поэтому у меня возникли проблемы с преобразованием.

Пока что я сделал это: создал 1D текстуру - ширина = 8 - формат = RGBA32F

Создайте одномерный буфер для текстуры

  • width = 8 * 4 = 32 floats, or 32 * 4 = 32 bytes large
  • fill the float buffer like this:

[x0,y0,0,0,x1,y1,0,0,x2,y2,0,0,x3,y3,0,0,x4,y4,0,0,x5,y5,0,0,x6,y6,0,0,x7,y7,0,0]

Создайте одномерный сэмплер для текстуры

  • min filter = nearest, no mip maps
  • mag filter = nearest
  • wrap mode = clamp to edge

В GLSL я определяю сэмплер как: uniform sampler1D sliceOffset;

И получает к нему доступ:

vec2 getSliceOffset(float unit)
{
 float texCoord = (unit * 2.0f + 1.0f) / (2.0f * 8.0f);
 vec2 offset = texture1D(sliceOffset, texCoord);
 return offset;
}

Но он сломан.

Что я делаю неправильно?


person ljbade    schedule 04.12.2010    source источник


Ответы (2)


Все, что вы показываете, выглядит правильно. «Он сломан» не очень наглядно. Какие симптомы?

Некоторые вещи, которые вы не показываете, могут быть неправильными:

  • 2 сэмплера, использующих один и тот же текстурный блок.
  • проблемы с типом в данных текстуры (хотя, если у вас есть опыт, я сомневаюсь)

Еще одна вещь, которую вы можете попробовать: вместо этого используйте texture2d, только с height = 1. DX не требует поддержки одномерных текстур, поэтому, в зависимости от оборудования, поддержка opengl может быть эмулирована. Вы можете попытаться держаться подальше от подобной эмуляции.

person Bahbar    schedule 04.12.2010
comment
Я попытался вывести цвет, возвращаемый из текстуры, в gl_FragColor, чтобы я мог выполнить дополнительную отладку. Текстура реагирует на изменения, поэтому сэмплер использует правильную текстуру. - person ljbade; 04.12.2010
comment
Я записал это в буфер [1.0, 0, 0, 0, ... 1.0, 0, 0, 0]. Теперь я ожидал, что результат будет красным, но я стал синим !, если я установил формат данных на GL_BGRA, я стал красным. Также, если я использую unit = 0, 2, 4, ... я получаю синий, но для unit = 1, 3, 5, ... я получаю черный. Это помогает? - person ljbade; 04.12.2010
comment
Также может кто-нибудь проверить правильность расчета texCoord? - person ljbade; 04.12.2010
comment
@Leith. Обновите свой вопрос, указав вызов glTexImage1D и его данные. - person Bahbar; 06.12.2010

Расчет texCoord верен. Сначала это сбивало с толку, так как я бы сделал (unit + .5) / 8.0, но это то же самое.

Однако меня все еще беспокоит одно. Разве вам не нужно писать .rg в конце оператора сэмплера, поскольку texFetch будет vec4? Я удивлен, что ваш компилятор не жалуется на это.

Пытаться:

texture1D(sliceOffset, texCoord).rg;
person Hannesh    schedule 04.12.2010
comment
Извините, что я это пропустил, но я использовал это. Он пропустил это, когда я создавал тот пример. Есть идеи о том, почему я получаю странные цвета при отладке? - person ljbade; 04.12.2010
comment
Я не могу этого понять. Единственная проблема - это неправильный формат, но он тоже выглядит нормально. - person Hannesh; 06.12.2010