Гауссовский шейдер для OpenGL ES, не работающий на графическом процессоре Mali, но исправно работающий на Adreno и PowerVR

#opengl-es #glsl #opengl-es-2.0

#opengl-es #glsl #opengl-es-2.0

Вопрос:

Я создал фильтр размытия по Гауссу в OpenGL ES. Я обнаружил, что он не работает на графических процессорах Mali. Кто-нибудь может сказать мне, что я делаю не так. Я уже пытался разбить длинные вычисления на небольшие шаги, но безрезультатно. Затем я передаю 1 / resoution в качестве разрешения вместо вычисления его во время циклов, чтобы избежать операций деления. Изображение стало немного тусклее, однако оно по-прежнему не размыло изображение.

РЕДАКТИРОВАТЬ: я уже пытался преобразовать lowp в mediump, но это не помогло. Сбой означает, что я получаю немного более тусклую версию исходного изображения. Графический процессор — Mali-G52 MC2. Наконец, я сгенерировал весь шейдер без циклов и предварительно вычисленных значений Гаусса. Но безрезультатно.

Это работает так, как задумано на других платформах GPU.

 varying highp vec2 textureCoordinate;
uniform sampler2D inputImageTexture;
uniform lowp vec2 resolution;
void main()
{
    lowp vec2 uv = vec2(textureCoordinate.x, textureCoordinate.y);
    lowp vec3 sum = vec3(0.0);
    lowp float intensity = 15.0;
    lowp float width_hal = float(int(intensity/2.0));
    lowp vec3 color = vec3(0.0);
    lowp float red = 0.0;
    lowp float green = 0.0;
    lowp float blue = 0.0;

for (lowp float i = 0.0; i < intensity; i=i 1.0){
    for (lowp float j = 0.0; j < intensity; j = j 1.0){
        lowp float guas_value = 1.0 / (2.0 * 3.14159 * (4.0 * 4.0)) * pow(2.718, -((i-intensity / 2.0)*(i-intensity / 2.0) (j-intensity / 2.0)*(j-intensity / 2.0))/(2.0 * (4.0 * 4.0)));
        lowp float x_axis = uv.x   ((-width_hal   i) * resolution.x * 1.5);
        lowp float y_axis = uv.y   ((-width_hal   j) * resolution.y * 1.5);
        color = texture2D(
                        inputImageTexture, vec2(
                        x_axis,
                        y_axis
                    )
                ).rgb;
        red  = color.r * guas_value;
        green  = color.g * guas_value;
        blue  = color.b * guas_value;
    }
}

gl_FragColor = vec4(red, green, blue, 1.0);
};
 

Комментарии:

1. Если вы измените все свои низкие значения на средние, улучшит ли это ситуацию? Диапазон низких частот может составлять от -2 до 2 в зависимости от графического процессора.

2. Какие графические процессоры Mali? Что значит «не работает»? На Mali lowp и mediump оба являются fp16, поэтому приведенное выше предложение не поможет. Попробуйте сделать все на высоком уровне (медленнее, но подтвердит, что проблема в точности).

3. Рекомендации по производительности — предварительно вычислите коэффициенты Гаусса и сохраните их в виде литерального массива. Разделите это на отдельные горизонтальные и вертикальные проходы. Это 2N выборок (N за проход), а не N ^ 2 выборки, поэтому будет НАМНОГО быстрее.

4. Я вижу, вы пробовали другие рекомендации solidpixel, но выполнили ли вы highp? это важная проверка.

5. Также значение с плавающей запятой для разрешения — значение с плавающей запятой может составлять от -2 до 2 — предназначено ли это? Вы специально вводите в переменные значения, превышающие это (см. Спецификацию GLSL )