[recovery mode] Оживляем картинку шейдерами или программирование абстрактного текста

Пару лет назад я наткнулся на одну картинку с простой геометрией:

cdf3e7e818352fd4fdc14d812f574a28.jpg

Её легко получилось нарисовать в ascii-арт, а теперь я запрограммировал видеокарту для того чтобы получить сотни таких же картинок на матрице, плавно перетекающих друг в друга. Что касается геометрии, то тут вроде вопросов нет, а вот солнечный узор и текст получилось сделать не сразу.Что-то напоминающее оригинальную текстуру узора у меня получилось с помощью такой операции:

c=(vec4(ceil(sin(r))+mod(y,2.0))+vec4(ceil(cos(r))+mod(x,2.0)))*(vec4(ceil(sin(r2))+mod(y,2.0))+vec4(ceil(cos(r2))+mod(x,2.0)));

где r и r2 это квадрат радиуса и радиус. Но с текстом наверное поинтереснее: абстрактный текст я научился получать таким обраом https://www.shadertoy.com/view/sdKXW1, а вот еще пример https://www.shadertoy.com/view/fdySWD теперь осталось только натянуть текст на геометрию. Для этого надо подобрать перпендикулы. Для диагонали вместо х и у используем их сумму и разность в операции деления по модулю. А для того чтобы натянуть абстрактный текст на круг нам придется заменить эти переменные на радиус и градусы. Если вы хотите пустить текст по заданной кривой, например, y=sin (x/32.0)*8.0 подойдет этот код:

void mainImage(out vec4 c,in vec2 o){
    float y=floor(o.y/2.0)-iResolution.y/4.0;
    float x=floor(o.x/2.0); float r=floor(pow(x,2.0)+pow(y,2.));
    c=vec4(ceil(ceil(sin(r)*4.0)+ceil(abs(y+(sin(x/32.0))*8.0))));
    if(cos(x)>0.0)c=vec4(1);
}

Перпендикуляром в данном случае будет косинус.

Ну, а в конце можно добавить зависимость этих формул от времени чтобы оживить картинку и дать понять что текст не настоящий.

image-loader.svg

Если интересно посмотреть как текст оживает или посмотреть на весь код целиком: то вот ссылка на шейдертой.

© Habrahabr.ru