Нельзя использовать динамическое индексирование c с сэмплерами в GLSL ES 3.0. От spe c
12.29 Пробоотборники
Должны ли пробоотборники быть разрешены как l-значения? Спецификация уже допускает эквивалентное поведение:
Текущая спецификация:
uniform sampler2D sampler[8];
int index = f(...);
vec4 tex = texture(sampler[index], xy); // allowed
Использование назначения типов сэмплера:
uniform sampler2D s;
s = g(...);
vec4 tex = texture(s, xy); // not allowed
РАЗРЕШЕНИЕ: Dynami c индексирование сэмплера массивы теперь запрещены по спецификации. Ограничьте индексирование массивов сэмплеров постоянными интегральными выражениями.
и
12.30 Dynami c Индексирование
Для GLSL ES 1.00, поддержка динамических файлов c индексирование массивов, векторов и матриц не было обязательным, поскольку некоторые реализации не поддерживали его напрямую. Программные решения (посредством программных преобразований) существуют для подмножества случаев, но приводят к низкой производительности. Должна ли быть обязательной поддержка динамического индексирования c для GLSL ES 3.00?
РЕШЕНИЕ: поддержка мандатов динамического c индексирования массивов , за исключением массивов сэмплеров , выходных массивов фрагментов и унифицированного блока массивы.
Должна ли поддерживаться динамическая c индексация векторов и матриц в GLSL ES 3.00?
РАЗРЕШЕНИЕ: Да.
Индексирование массивов сэмплеров по константе -index-выражения поддерживаются в GLSL ES 1.00. Постоянное индексное выражение - это выражение, сформированное из константных выражений и определенных индексов l oop, определенных для подмножества конструкций l oop. Должна ли эта функциональность быть включена в GLSL ES 3.00?
РАЗРЕШЕНИЕ: Нет. Массивы сэмплеров могут быть проиндексированы только с помощью константно-интегральных выражений.
Можно ли использовать текстуру 2D_ARRAY для решения вашей проблемы? Поместите каждую из ваших текущих 2D текстур в слой текстуры 2D_ARRAY, тогда координата z - это просто целочисленный индекс слоя. Преимущество: вы можете использовать гораздо больше слоев с 2D_ARRAY, чем получать сэмплеры. Реализации WebGL2 обычно имеют только 32 сэмплера, но допускают сотни или тысячи слоев в текстуре 2D_ARRAY.
или используют GLSL 1.0
const vs1 = `
void main() { gl_Position = vec4(0); }
`;
const vs3 = `#version 300 es
void main() { gl_Position = vec4(0); }
`;
const fs1 = `
precision highp float;
#define MAX_SPLITS 4
uniform sampler2D samplers[MAX_SPLITS];
uniform int splitCount;
bool func(sampler2D s) {
return texture2D(s, vec2(0)).r > 0.5;
}
void main() {
float v = 0.0;
for (int i = 0; i < MAX_SPLITS; ++i) {
if (i >= splitCount) {
break;
}
if (func(samplers[i])) { // that's where the error happens
v += 1.0;
}
}
gl_FragColor = vec4(v);
}
`;
const fs3 = `#version 300 es
precision highp float;
#define MAX_SPLITS 4
uniform sampler2D samplers[MAX_SPLITS];
uniform int splitCount;
bool func(sampler2D s) {
return texture(s, vec2(0)).r > 0.5;
}
out vec4 color;
void main() {
float v = 0.0;
for (int i = 0; i < MAX_SPLITS; ++i) {
if (i >= splitCount) {
break;
}
if (func(samplers[i])) { // that's where the error happens
v += 1.0;
}
}
color = vec4(v);
}
`;
function main() {
const gl = document.createElement('canvas').getContext('webgl2');
if (!gl) {
return alert('need WebGL2');
}
test('glsl 1.0', vs1, fs1);
test('glsl 3.0', vs3, fs3);
function test(msg, vs, fs) {
const p = twgl.createProgram(gl, [vs, fs]);
log(msg, ':', p ? 'success' : 'fail');
}
}
main();
function log(...args) {
const elem = document.createElement('pre');
elem.textContent = [...args].join(' ');
document.body.appendChild(elem);
}
<script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>