Не удается инициализировать векторный массив с целочисленным индексом в WebGL / GLSL? - PullRequest
0 голосов
/ 10 июня 2019

Мне интересно, почему я не могу инициализировать массив с целочисленным индексом.В шадертой, похоже, работает, но не работает, когда я использую этот пиксельный шейдер через three.js:

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 glsl doesn't run

    gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}

Есть идеи?

1 Ответ

2 голосов
/ 11 июня 2019

Проблема в том, что 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

...