GL ES: оптимизация фрагментного шейдера

Вывод: я получаю замедление FPS, как только пытаюсь подкрасить спрайты (т. е. умножить текстуру на цвет во фрагментном шейдере).

Подробности:

Аппаратное обеспечение: iPod touch 4

Использование текстуры png 64x64, содержащей альфа-канал, рендеринг с помощью glEnable(GL_BLEND). (смайлик с тенью)

Я рисую 700 спрайтов на экране с помощью glDrawArrays. И да, я объединяю все это в один вызов отрисовки. Ниже показана структура данных Vertex:

struct Vertex {
    float Position[2];
    float Color[4];
    float Texture[2];
};

Да, я отправляю цвет с каждой вершиной, потому что мне нужно выборочно подкрашивать одни спрайты, но не другие. Ниже приведен фрагментный шейдер, который я использую:

varying lowp vec2 TexCoord;
uniform sampler2D TextureSampler;

void main(void)
{
    gl_FragColor = texture2D( TextureSampler, TexCoord );
}

До сих пор он работает ОТЛИЧНО, давая мне полные 60 кадров в секунду !!!

НО

Как только я изменю фрагментный шейдер на следующий (чтобы разрешить тонировку):

varying lowp vec4 DestinationColor;
varying lowp vec2 TexCoord;
uniform sampler2D TextureSampler;

void main(void)
{
    gl_FragColor = texture2D( TextureSampler, TexCoord ) * DestinationColor;
}

Производительность падает до 47 FPS только из-за этого единственного изменения {просто путем умножения на ОДИН вектор} (FPS измеряется с помощью инструментов xcode и детектора OpenGL). Любые идеи, что происходит?

Спасибо.

Изменить:

Я также попытался отключить атрибут цвета вершины:

struct Vertex {
    float Position[2];
    float Texture[2];
};

И модифицируем фрагментный шейдер следующим образом:

precision lowp float;
varying lowp vec2 TexCoord;
uniform sampler2D TextureSampler;

void main(void)
{
    gl_FragColor = texture2D( TextureSampler, TexCoord ) * vec4(1.0,0.0,0.0,1.0);
}

Он работает со скоростью 52 FPS для 700 спрайтов (прирост всего 5 FPS). Так что это не интерполяция, кажется, что умножение чрезвычайно дорого. Только это ОДНО умножение?


person fakhir    schedule 24.05.2013    source источник


Ответы (1)


По моему опыту, альфа-смешивание имеет тенденцию довольно быстро снижать частоту кадров, особенно на старых устройствах. Я предполагаю, что умножение этого цвета на самом деле требует много дополнительных вычислений для графического процессора (чтобы учесть и умножить цвет, уже находящийся в буфере кадра). Честно говоря, если у вас все еще 47 кадров в секунду на iPod touch 4-го поколения, похоже, у вас все хорошо. Вы, вероятно, вернетесь к 60 на более новом устройстве. Если вы группируете вызовы отрисовки, такой простой шейдер практически не нуждается в дополнительной оптимизации.

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

ИЗМЕНИТЬ

Есть еще один ответ SO здесь, который может быть больше того, что вы ищете. По сути, это говорит о том, что более точное умножение с плавающей запятой во фрагментном шейдере может снизить производительность. Возможно, вы сможете вручную установить более низкую точность сэмплера и таким образом повысить производительность.

person LOP_Luke    schedule 24.05.2013
comment
Как я уже упоминал в вопросе, я уже получаю 60 кадров в секунду на iPod 4 при рендеринге 700 спрайтов. НО как только я применяю оттенок во фрагментном шейдере (т.е. умножаю цвет на текстуру), FPS внезапно падает до 47 FPS. Выборочный рендеринг кажется хорошей идеей, спасибо :). Но можете ли вы указать причину замедления? Это просто умножение 2 векторов!! - person fakhir; 24.05.2013
comment
Итак, что я обычно вижу на своем iPhone 4, так это то, что чем сложнее я делаю свои фрагментные шейдеры, тем быстрее падает мой fps. Особенно, когда у меня есть поиск текстур и/или альфа-смешивание. Даже очень простые вычисления могут очень быстро снизить частоту кадров на старых устройствах. Честно говоря, я недостаточно знаю внутреннюю работу OpenGL, чтобы объяснить, почему это так, но я предполагаю, что дополнительное умножение просто подталкивает ваше оборудование чуть выше максимального порога частоты кадров. - person LOP_Luke; 24.05.2013
comment
Я отредактировал вопрос выше, чтобы добавить новую информацию. В основном я уже использую lowp :). Я также пытался умножить на вектор постоянного цвета (см. редактирование выше). Теперь я получаю 52 FPS. Падение 8 FPS из-за только ОДНОГО умножения? Похоже, умножение векторов очень дорого. - person fakhir; 24.05.2013
comment
Из любопытства, какой у вас будет fps, если вы отключите смешивание, но оставите все остальное без изменений? - person LOP_Luke; 24.05.2013
comment
С отключенным GL_BLEND и отсутствием тонировки я получаю стабильные 60 кадров в секунду при рендеринге 3100 спрайтов !!! - person fakhir; 24.05.2013
comment
Да, этого я и ожидал. Я не могу сказать вам точно, почему дополнительное умножение vec4 имеет такой удар по производительности, но это определенно смешивание, которое является реальным источником замедления. Комбинация «смешивание + умножение» просто увеличивает производительность вашего iPod. Apple предлагает использовать текстуры PVRTC, чтобы ускорить работу, и, возможно, это поможет ускорить умножение. Я все еще думаю, что у вас все в порядке с таким количеством спрайтов на старом устройстве. - person LOP_Luke; 25.05.2013