Я пишу коды шейдеров в фреймворке GPUImage в Android. Затем я сталкиваюсь с проблемой индексации массива во фрагментном шейдере.
Согласно Приложению к языку затенения OpenGL ES, в вершинном шейдере юниформ-массивы могут быть проиндексированы. любым целым числом, а переменные массивы могут быть проиндексированы выражением постоянного индекса. Во фрагментном шейдере оба массива (однородный/переменный) могут быть проиндексированы только выражением постоянного индекса. В соответствии с определением выражения постоянного индекса индекс цикла for должен использоваться как индекс массива.
Однако что-то идет не так, когда я использую индекс цикла в качестве индекса массива во фрагментном шейдере. Ошибки компиляции нет, и коды шейдеров можно запускать, но кажется, что программа обрабатывает все значения индекса равными 0 в каждом раунде цикла.
Вот мои коды фрагментных шейдеров:
uniform sampler2D inputImageTexture;
uniform highp float sample_weights[9]; // passed by glUniform1fv
varying highp vec2 texture_coordinate;
varying highp vec2 sample_coordinates[9]; // computed in the vertex shader
...
void main()
{
lowp vec3 sum = vec3(0.0);
lowp vec4 fragment_color = texture2D(inputImageTexture, texture_coordinate);
for (int i = 0; i < 9; i++)
{
sum += texture2D(inputImageTexture, sample_coordinates[i]).rgb * sample_weights[i];
}
gl_FragColor = vec4(sum, fragment_color.a);
}
Результат будет правильным, если я разверну цикл и получу доступ от [0] до [8] для массивов. Однако при использовании индекса цикла результат неверен и становится таким же, как при запуске
sum += texture2D(inputImageTexture, sample_coordinates[0]).rgb * sample_weights[0];
в 9 раз, и во время процесса не сообщается об ошибке компиляции.
Я протестировал только одно устройство — Nexus 7 с Android версии 4.3. Фреймворк GPUImage использует android.opengl.GLES20, но не GLES30.
Является ли это дополнительным ограничением на коды шейдеров в устройствах Android или в OpenGL ES 2.0, или это проблема, зависящая от устройства?
Обновлено: после тестирования большего количества устройств Android (4.1–4.4) оказалось, что эта проблема возникает только на устройстве Nexus 7. Результаты на других устройствах правильные. Это странно. Является ли это проблемой реализации на отдельных устройствах?