Проблема в том, что GLSL 1.0 поддерживает только константу целочисленные выражения для оси массива или циклов на основе константы целочисленных выражений.
См. Спецификацию
void main(void) {
vec2 p[1];
p[0] = vec2(0.0, 0.0); // works
int i = 0;
p[i] = vec2(0.0, 0.0); // doesn't work. i is not constant
const int j = 0;
p[j] = vec2(0.0, 0.0); // works
vec2 q[2];
for (int k = 0; k < 2; ++k) { // 2 is a constant int so this works
p[k] = vec2(0); // works
}
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}
Обратите внимание, что правила сложны. Например, ваш код работает в вершинном шейдере, но не в фрагментном шейдере. За исключением массивов сэмплеров, даже в вершинных шейдерах индекс должен следовать тем же ограниченным правилам.
WebGL2 поддерживает GLSL ES 3.00, что позволяет использовать постоянный доступ к целочисленным массивам в большем количестве мест.
Shadertoy дополнительно использует WebGL2, хотя он пытается сделать это автоматически. Вам не нужно говорить, что ваш шейдер использует GLSL ES 3.0, он просто догадывается, как это сделать. Возможно, он компилирует шейдер в обоих направлениях, и тот, который работает, тот, который он использует. Я понятия не имею, я просто знаю, что это поддерживает оба.
THREE.js имеет версию WebGL2