Создание Pixel Bender фильтра «Slide Wring». Введение
Если кто помнит, в качестве "разведки боем" я смастерил в Pixel Bender довольно симпотный эффект смены изображений "Slide Wring". Сегодня я выставляю на ваш суд исходный код этого фильтра. Так я начну небольшой цикл уроков по созданию в программе Pixel Bender некоторых особенно интересных на мой взгляд эффектов.
Начинать знакомство с новым эффектом мы будем с самого интересного — с финального кода:
Код:
<languageVersion : 1.0;>
kernel SlideWring
<
namespace : "Image Effects";
vendor : "Vadim BELLinSKY";
version : 3;
description : "Slide Wring for Flash is an easy and effective method for flipping imapges.";
>
{
parameter float2 size
<
minValue: float2(0.0, 0.0);
maxValue: float2(2880.0, 2880.0);
defaultValue: float2(0.0, 0.0);
description: "Image size";
>;
parameter float borderThickness
<
minValue: 0.0;
maxValue: 28.0;
defaultValue: 7.0;
description: "Border thickness";
>;
parameter pixel3 borderColor
<
parameterType: "colorRGB";
minValue: pixel3(0.00, 0.00, 0.00);
maxValue: pixel3(1.00, 1.00, 1.00);
defaultValue: pixel3(0.95, 0.95, 0.95);
description: "Border color";
>;
parameter float phase
<
minValue: 0.0;
maxValue: 1.0;
defaultValue: 0.0;
description: "Transition phase";
>;
input image4 src1;
input image4 src2;
output pixel4 dst;
const float PI = 3.1415926535;
const float PI2 = PI * 2.0;
const float PI_2 = PI * 0.5;
const float shrinking = 0.1;
const float shining = 0.75;
const float shading = 0.75;
#define width_2 float(size[0] * 0.5)
#define height_2 float(size[1] * 0.5)
#define period1 float(PI_2 / size[1])
#define period2 float(PI / size[0])
#define phase1 float((phase * 0.75 - 0.5) * PI2)
#define phase2 float(shrinking * sin(phase * PI))
void
evaluatePixel()
{
float2 here = outCoord();
bool borderFlag = false;
float angleH = clamp(here.y * period1 - phase1, 0.0, PI);
float cosH = cos(angleH);
float cosHdiv = 1.0 / cosH;
// calculating the value of the current pixel
float angleV = here.x * period2;
float sinV = sin(angleV);
float dx = (width_2 - here.x) * cosHdiv;
float dy = (height_2 - here.y) * (1.0 + phase2 * (1.0 + sinV));
float absdx = abs(dx);
float absdy = abs(dy);
float thickness = borderThickness * cos(dy * period1 * 2.0) * sinV;
thickness = thickness < 0.25 ? 0.0 : thickness;
float2 here1 = here - float2(thickness, 0.0);
float2 here2 = here + float2(thickness, 0.0);
// calculating the value of a pixel on the left of the current one
float dx1 = (width_2 - here1.x) * cosHdiv;
float absdx1 = abs(dx1);
// calculating the value of a pixel on the right of the current one
float dx2 = (width_2 - here2.x) * cosHdiv;
float absdx2 = abs(dx2);
// helper conditions
bool subcond1 = absdy < height_2;
bool subcond2 = absdx1 < width_2;
bool subcond3 = absdx2 < width_2;
bool subcond4 = dx1 < -width_2;
bool subcond5 = dx2 > -width_2;
bool subcond6 = cosH < 0.0;
// main conditions
bool condition1 = ( (( subcond6 && subcond3) || (!subcond6 && subcond2)) && subcond1 );
bool condition2 = ( ((!subcond6 && !subcond3) || ( subcond6 && !subcond2)) && subcond1 );
bool condition3 = ( (( subcond4 && subcond5) || (!subcond4 && !subcond5)) && subcond1 );
bool condition4 = absdx > width_2 || absdy > height_2;
if (condition4)
{
// the pixel is outside the slide
// but it still can be on the border
if (condition1 || condition3)
{
borderFlag = true;
}
else
{
dst.a = 0.0;
}
}
else
{
// the pixel is within the slide
if (subcond6)
{
dst = sampleLinear(src1, float2(width_2 + dx, height_2 - dy));
}
else
{
dst = sampleLinear(src2, float2(width_2 - dx, height_2 - dy));
}
// but it still can be on the border
if (condition2)
{
borderFlag = true;
}
}
// shading/shining parameters
float shadingValue = 1.0 - abs(cosH);
float shadingBorder = shadingValue * shadingValue;
float shiningImage = shadingBorder * shining;
float shadingImage = shadingBorder * shading;
pixel3 borderColorCorrect = borderColor * shadingBorder;
if (subcond6)
{
// shining of the slide below the center
dst.rgb += (1.0 - dst.rgb) * shiningImage;
}
else
{
// shading of the slide above the center
dst.rgb *= 1.0 - shadingImage;
}
if (borderFlag)
{
// the pixel is somewhere on the border
dst.a = 1.0;
if ((dx <= width_2) && (abs(width_2 + dx2) <= 0.5 || abs(width_2 + dx1) <= 0.5))
{
// the pixel is located on the inner edge of the border
dst.rgb = mix(borderColorCorrect, dst.rgb, 0.5);
} else {
// the pixel is somewhere inside the border
dst.rgb = borderColorCorrect;
}
if ( (dx <= - width_2) && ( (abs(width_2 + dx2) <= 0.5) || (abs(width_2 + dx1) <= 0.5) ) )
{
// the pixel is located on the outer edge of the border
dst *= 0.5;
}
}
else
{
// edges smoothing
float mh = clamp(height_2 + 0.5 - absdy, 0.0, 1.0);
float mw = clamp(width_2 + 0.5 - absdx, 0.0, 1.0);
float m = mh * mw;
dst *= m * m;
}
}
}
Надо отметить, что уроки не будут раскрывать основ работы с Pixel Bender. Предполагается, что вы уже запустили программу, открыли пару примеров, познакомились с интерфейсом, почитали документацию и полны решимости создавать красивые эффекты, но еще не знаете как…
Готовьтесь. Скоро начинаем.
Взято тут.
Всего комментариев 3
Комментарии
|
|
|
Спасибо за статьи, может и доберусь когда-нибудь до бендера.
|
|
|
|
Благодарю =)
|
Последние записи от Zebestov
- Pixel Bender фильтр «Flipping Hexagons» для Flash (17.06.2012)
- Создание Pixel Bender фильтра «Slide Wring». Введение (12.06.2012)
- Free Transform в два треугольника! (22.03.2011)
- drawTriangles(), старая ошибка в документации (24.01.2011)












