Создание 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)