Я выполняю некоторую обработку GPGPU на большом входном массиве 4D в WebGL2.Первоначально я просто сгладил входной массив и передал его как единый массив целых чисел с пользовательской функцией доступа в GLSL для преобразования 4D-координат в индекс массива следующим образом:
const int SIZE = 5; // The largest dimension that works; if I can switch to textures, this will be passed in as a uniform value.
const int SIZE2 = SIZE*SIZE;
const int SIZE3 = SIZE*SIZE2;
const int SIZE4 = SIZE*SIZE3;
uniform int u_map[SIZE4];
int get_cell(vec4 m){
ivec4 i = ivec4(mod(m,float(SIZE)));
return u_map[i.x*SIZE3+i.y*SIZE2+i.z*SIZE+i.w];
}
В JavaScriptКроме того, сглаженные данные передаются следующим образом:
const map_loc = gl.getUniformLocation(program, "u_map");
gl.uniform1iv(map_loc, data);
Где data
- это Int32Array
(потому что это то, что требуется для отображения на целочисленные значения GLSL), содержащее 8-битные значения.
Это работает, но сильно ограничивает размер входов, с которыми я могу работать.Увеличение размера до 6 приводит к использованию 1296 одинаковых слотов, когда для этих данных и других управляющих входов доступно только 1024.
Итак, я хочу перейти к использованию текстуры для хранения больших количествданные.Итак, я обновил код JS следующим образом:
const tex = gl.createTexture();
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.R8, data.length, 1, 0, gl.RED, gl.UNSIGNED_BYTE, data);
, где data
был переупакован как Uint8Array
, который должен использоваться для предоставления одноканальных значений r
в текстуреобъект сэмплера в GLSL.Код GLSL обновляется следующим образом:
uniform sampler2D u_map;
int get_cell(vec4 m){
ivec4 i = ivec4(mod(m,float(SIZE)));
float r = texelFetch(u_map, ivec2(i.x*SIZE3+i.y*SIZE2+i.z*SIZE+i.w, 0), 0).r;
return int(r);
}
, который должен извлекать единственное допустимое значение канала из основного буфера, так же, как когда мы использовали массив.
Однако после выполненияэта замена, я просто получаю мусор.Значения, возвращаемые из get_cell
, кажутся равными 1 или 0, и ни одно из них даже надежно не соответствует наличию фактических значений 1 или 0 в исходном буфере данных.
Что я делаю неправильно