Передача массива изображений для вычисления шейдера - PullRequest
0 голосов
/ 07 октября 2019

В настоящее время я работаю над проектом, использующим черновик для шейдеров Compute в WebGL 2.0. [проект] . Тем не менее, я не думаю, что мой вопрос относится к WebGL, а скорее к проблеме OpenGL. Цель построить пирамиду изображений, которые будут использоваться в вычислительном шейдере. Каждый уровень должен быть квадратом из 2 ^ (n-level) значений (до 1x1) и содержать простые целочисленные значения / значения с плавающей запятой ...

У меня уже есть значения, необходимые для этой пирамиды, хранящиеся в разных OpenGLИзображения все со своими размерами. Мой вопрос: как бы вы передали мой массив изображений в вычислительный шейдер. У меня нет проблем с ограничением количества передаваемых изображений, скажем, 14 или 16 ... но оно должно быть не менее 12. Если есть механизм для сохранения изображений в текстуре, а затем использовать textureLod, это будетрешить проблему, но я не мог разобраться, как это сделать с помощью картинок.

Спасибо за вашу помощь, и я почти уверен, что должен быть очевидный способ сделать это, но яотносительно новый для OpenGL в целом.

1 Ответ

1 голос
/ 07 октября 2019

Передача "пирамиды изображений" - обычная вещь в WebGL. Они называются mipmap.

gl.texImage2D(gl.TEXUTRE_2D, 0, gl.R32F, 128, 128, 0, gl.RED, gl.FLOAT, some128x128FloatData);
gl.texImage2D(gl.TEXUTRE_2D, 1, gl.R32F, 64, 64, 0, gl.RED, gl.FLOAT, some64x64FloatData);
gl.texImage2D(gl.TEXUTRE_2D, 2, gl.R32F, 32, 32, 0, gl.RED, gl.FLOAT, some32x32FloatData);
gl.texImage2D(gl.TEXUTRE_2D, 3, gl.R32F, 16, 16, 0, gl.RED, gl.FLOAT, some16x16FloatData);
gl.texImage2D(gl.TEXUTRE_2D, 4, gl.R32F, 8, 8, 0, gl.RED, gl.FLOAT, some8x8FloatData);
gl.texImage2D(gl.TEXUTRE_2D, 5, gl.R32F, 4, 4, 0, gl.RED, gl.FLOAT, some4x4FloatData);
gl.texImage2D(gl.TEXUTRE_2D, 6, gl.R32F, 2, 2, 0, gl.RED, gl.FLOAT, some2x2FloatData);
gl.texImage2D(gl.TEXUTRE_2D, 7, gl.R32F, 1, 1, 0, gl.RED, gl.FLOAT, some1x1FloatData);

Число во 2-м столбце - это уровень mip, за которым следует внутренний формат, за которым следуют ширина и высота уровня mip.

Youможно получить доступ к любому отдельному текселю из шейдера с помощью texelFetch(someSampler, integerTexelCoord, mipLevel), как в

uniform sampler2D someSampler;

...

   ivec2 texelCoord = ivec2(17, 12);  
   int mipLevel = 2;
   float r = texelFetch(someSampler, texelCoord, mipLevel).r;

Но вы сказали, что вам нужно 12, 14 или 16 уровней. 16 уровней - это 2 (16-1) или 32768x32768. Это 1,3 гигабайта памяти, поэтому вам понадобится графический процессор с достаточным пространством, и вы должны молиться, чтобы браузер позволил вам использовать 1,3 гигабайта памяти.

Вы можете сэкономить память, выделив текстуру с помощью texStorage2D, а затем загружать данные с помощью texSubImage2D.

Вы упомянули использование изображений. Если под этим вы подразумеваете <img> теги или Image, то вы не можете получить данные Float или Integer из них. Как правило, они имеют значения 8 бит на канал.

Или, конечно, вместо использования уровней mip, вы также можете разместить свои данные в атласе текстуры

...