Любителям машграфа посвящается - часть 2

edmsk

Доброго времени суток!
Напомню, в прошлый раз мы экспериметировали с меташарами под Android. Получилось неплохо - за 2 месяца около 50 000+ скачек бесплатной версии и ~1500 платной (стоимостью $2).
На этот раз хочу поделиться нашими изысканиями в области обработки изображений. На прошлой неделе мы завершили разработку приложения Раскраска Экрана. Основная идея заключалась в том, чтобы дать пользователю возможность легко и быстро изменить задний фон, применив к нему разные цветовые эффекты и добавив анимации (за деньги!)
Как эталон возможностей был взят фотошоп. Промучались мы долго. Основная сложность была в том, чтобы научиться быстрым преобразованиям цветов между разными цветовыми моделями, такими как HSL, HSV, LCH.
Так как все видеокарты работают с RGB, то, например, для изменения оттенка цвета (Hue) необходимо сначала выполнить преобразование RGB в одну из цветовых моделей, основанную на Hue. Любое такое преобразоване содержит достаточно большое кол-во условных переходов (if-ов которые очень плохо сказываются на производительности пиксельного шейдера.
Например, общеизвестная конвертация RGB->HSV выглядит так:

if ( S == 0 ) //HSV from 0 to 1
{
R = V * 255
G = V * 255
B = V * 255
}
else
{
var_h = H * 6
if ( var_h == 6 ) var_h = 0 //H must be < 1
var_i = int( var_h ) //Or ... var_i = floor( var_h )
var_1 = V * ( 1 - S )
var_2 = V * ( 1 - S * ( var_h - var_i ) )
var_3 = V * ( 1 - S * ( 1 - ( var_h - var_i ) ) )

if ( var_i == 0 ) { var_r = V ; var_g = var_3 ; var_b = var_1 }
else if ( var_i == 1 ) { var_r = var_2 ; var_g = V ; var_b = var_1 }
else if ( var_i == 2 ) { var_r = var_1 ; var_g = V ; var_b = var_3 }
else if ( var_i == 3 ) { var_r = var_1 ; var_g = var_2 ; var_b = V }
else if ( var_i == 4 ) { var_r = var_3 ; var_g = var_1 ; var_b = V }
else { var_r = V ; var_g = var_1 ; var_b = var_2 }

R = var_r * 255 //RGB results from 0 to 255
G = var_g * 255
B = var_b * 255
}

Немного подумав, мы пришли к выводу, что от всех условных переходов можно избавиться. В результате, получился следующий код:
  
vec3 hue2rgb(float h)
{
float h6 = h * 6.0;
float r = abs(h6 - 3.0) - 1.0;
float g = 2.0 - abs(h6 - 2.0);
float b = 2.0 - abs(h6 - 4.0);
return clamp(vec3(r, g, b 0.0, 1.0);
}

vec3 hsv2rgb(vec3 hsv)
{
return hue2rgb(hsv.x) - 1.0) * hsv.y + 1.0) * hsv.z;
}

Производительность выросла примерно на 500%, при условии, что на видеокарту телефона/планшета уже приходится большая нагрузка по fill-операциям.
Следующая трудность возникла при попытке имплементировать различные режимы смешивания цветов из фотошопа (Blend Modes).
Например, режим смешивания по цвету (Color Blend Mode) отличается тем, что сохраняет первоначальную относительную яркость каждого пикселя (Preserves Luminocity).
В результате долгих изысканий и попыток самим написать соотв. алгоритм мы наткнулись на документацию от самого фотошопа! И наконец-то получили то, что хотели.
К этому моменту прошло уже более месяца с начала разработки. Начали преобладать угрюмые настроения :( А еще необходимо было придумать динамические анимации для любой картинки, и приложение выглядело уже как-то не очень радужно в свете пред. сложностей.
Но мы все же собрались с силами и доделали. Добавили анимации времени суток, времен года, погоды и несколько цветовых динамических эффектов. Выглядит это на андроиде примерно вот так: http://www.youtube.com/watch?v=JKZJoyScLSs
Результат превзошел наши ожидания. Кол-во скачек и позитивных отзывов больше примерно в 10 раз, чем у меташариков.
Если кто-то из читающих интересуется данной темой или смежными вопросами - пишите в личку, буду рад помочь и даже поделиться различными исходниками :p

Barbie29

ну, чтож, молодцы!

edmsk

ну, чтож, молодцы!
Ну-с, спасибо что ли!)

apl13

Немного подумав, мы пришли к выводу, что от всех условных переходов можно избавиться.
ВНЕЗАПНО.

edmsk

ВНЕЗАПНО.
Ага, типа того! :D

agaaaa

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

spitfire

Ты так это говоришь, как будто в подобном треде не будет холиваров.

apl13

Но они будут в обсуждениях.
А внешне все будет выглядеть благопристойно и гладко.

Serpent555

Девелоперам респект. Безусловный RGB->HSV - круто. Хотя, если нужно решать задачу сдвига тона без упора на точность преобразования (т.е. без перехода в Lab, Luv или Munsell резве нельзя было ограничиться поворотом точки в RGB-кубе вокруг главной диагонали? Или с учётом выхода за границы это было бы сложнее?
С точки зрения пользователей - вот никогда не понимал, нахрена им такие приложения?.. Или как раз для большинства, для кого смартфон - просто красивая игрушка?

Amuren

ограничиться поворотом точки
Поворачивать - домножать на матрицу? А перед этим вычислить синусы\косинусы и матрицу заполнить? Думаю, это дороже, чем по if'ам пробежаться.

Amuren

Зашел на страничку шаров, мне написали:
Приложение совместимо с вашим устройством MTS Samsung GT-S5830.

Гугл определенно слишком много обо мне знает.

Temach

С точки зрения пользователей - вот никогда не понимал, нахрена им такие приложения?.. Или как раз для большинства, для кого смартфон - просто красивая игрушка
Тоже не понимаю. При этом ТС утверждает, что он еще и наварился на 90 000 руб практически на ровном месте за счет скачек платной версии.

bav46

а откуда у эпла 95 млрдов долларов кэшем? явно же не с продажи ифонов.
и откуда уверенность что на ровном месте? шарики писали два разработчика очень много ночей, потом затраты денежные и временные на продвижение и то они сейчас только бесплатные перевалили 50к+ за 5 месяцев чтоли.
ну если считаешь что ровное место попробуй что-нибудь создай на ровном месте :grin:

yroslavasako

и откуда уверенность что на ровном месте? шарики писали два разработчика очень много ночей,
Откуда эта советская привычка мерить востребованность товара работой? Не важно сколько вы работали, важно насколько это актуально для пользователей. В данном случае "на ровном месте" означает на и без того пресыщенным свистоперделками рынке. То есть, я, конечно, рад, что у вас получается что-то зарабатывать, но не перестаю удивляться критериям, по которым пользователи айфона выбирают приложения

edmsk

Поворачивать - домножать на матрицу? А перед этим вычислить синусы\косинусы и матрицу заполнить? Думаю, это дороже, чем по if'ам пробежаться.
Смещение цвета по оттенку мы так и делаем. Это бы просто одно умножения на матрицу. А вот блендинг по Hue так уже не сделаешь. Поэтому и требуется переход в HSV/HSL/LCH (luma chroma hue)

edmsk

Откуда эта советская привычка мерить востребованность товара работой? Не важно сколько вы работали, важно насколько это актуально для пользователей. В данном случае "на ровном месте" означает на и без того пресыщенным свистоперделками рынке. То есть, я, конечно, рад, что у вас получается что-то зарабатывать, но не перестаю удивляться критериям, по которым пользователи айфона выбирают приложения
Во-первых, речь про андроид, а не айфон. Народ под андроидом любит кустомизацию.
Во-вторых, что касается востребованности - на данный момент скачки приложения перевалили за 100 000, прошло чуть меньше месяца.
Ну а по поводу советских мерок - ты сам же ими и пользуешься в первую очередь, иначе бы тебе даже мысль такая в голову не пришла.

edmsk

Тоже не понимаю. При этом ТС утверждает, что он еще и наварился на 90 000 руб практически на ровном месте за счет скачек платной версии.
Красиво - телефон становится няшным. Надоели цвета - поменял.
Полезно - погода, время суток.
Уникально - аналогов на рынке нет, идея оригинальна, людям это нравится по определению
Креативно и интересно - за несколько минут создается любая 2.5д сцена, с молниями, снегом, дождем и любыми другими эффектами.

edmsk

Девелоперам респект. Безусловный RGB->HSV - круто. Хотя, если нужно решать задачу сдвига тона без упора на точность преобразования (т.е. без перехода в Lab, Luv или Munsell резве нельзя было ограничиться поворотом точки в RGB-кубе вокруг главной диагонали? Или с учётом выхода за границы это было бы сложнее?
Да, все так. Все смещения делаются матрицами в одно умножения в пиксельном шейдере. Матрица расчитывается снаружи, поэтому это самый быстрый способ.
Но у нас также есть блендинг по hue, там уже приходится делать переход. Я экспериментировал с разными моделями. На практике, самой быстрой в преобразованиях оказалась hsl. Т.к. нужно было изменить hue и оставить все остальное как есть, выбор на ней и остановился.
Оставить комментарий
Имя или ник:
Комментарий: