(OpenGL 3.1 - 4.2) Динамические однородные массивы? - PullRequest
7 голосов
/ 29 марта 2012

Допустим, у меня есть 2 вида, такие как люди и пони.У них разные скелетные системы, поэтому однородный костный массив должен быть разным для каждого вида.Нужно ли реализовывать две отдельные программы шейдеров, способные правильно отображать каждый массив костей, или вместо этого есть способ динамически объявлять однородные массивы и выполнять итерацию по этому динамическому массиву?

Принимая во внимание производительность (есть все шейдерысосать при принятии решения ветвится).

Ответы [ 2 ]

15 голосов
/ 29 марта 2012

До OpenGL 4.3 массивы в GLSL должны были иметь фиксированный размер во время компиляции.4.3 позволяет использовать буферные объекты шейдерного хранилища, которые позволяют их конечной длине быть «неограниченной».По сути, вы можете сделать это:

buffer BlockName
{
  mat4 manyManyMatrices[];
};

OpenGL выяснит, сколько матриц в этом массиве во время выполнения, основываясь на том, как вы используете glBindBufferRange.Таким образом, вы все равно можете использовать manyManyMatrices.length() для получения длины, но это не будет константа времени компиляции.

Однако эта функция (на момент этого редактирования) очень новая и реализована только вбета.Это также требует аппаратного обеспечения класса GL 4.x (иначе: аппаратное обеспечение класса Direct3D 11).Наконец, поскольку он использует блоки шейдерного хранилища, доступ к данным может быть медленнее, чем можно было бы надеяться.

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

10 голосов
/ 12 апреля 2013

Вы можете использовать n-by-1-Textures в качестве замены для массивов.Размер текстуры можно указать во время выполнения.Я использую этот подход для передачи произвольного количества источников света моим шейдерам.Я удивлен, как быстро он работает, несмотря на множество петель и веток.Для примера смотрите файл шейдера polygon.f в jogl3.glsl.nontransp в источниках jReality.

uniform sampler2D sys_globalLights;
uniform int sys_numGlobalDirLights;
uniform int sys_numGlobalPointLights;
uniform int sys_numGlobalSpotLights;

...

int lightTexSize = sys_numGlobalDirLights*3+sys_numGlobalPointLights*3+sys_numGlobalSpotLights*5;

    for(int i = 0; i < numDir; i++){
        vec4 dir = texture(sys_globalLights, vec2((3*i+1+0.5)/lightTexSize, 0));

...

...