Когда шейдер используется для создания заливки рисунка, необходимо создать векторную фигуру с помощью API-методов рисования. Вывод шейдера используется для заливки фигуры так же, как растровое изображение используется в качестве растровой заливки с помощью API-интерфейса рисования. Чтобы создать заливку шейдером, в том месте кода, где начинается отрисовка фигуры, вызовите метод
beginShaderFill()
объекта Graphics. Передайте объект Shader в качестве первого аргумента методу
beginShaderFill()
, как показано ниже.
var canvas:Sprite = new Sprite();
canvas.graphics.beginShaderFill(myShader);
canvas.graphics.drawRect(10, 10, 150, 150);
canvas.graphics.endFill();
// add canvas to the display list to see the result
Когда шейдер используется в качестве заливки рисунка, необходимо задать значения входного изображения и значения параметров, необходимых шейдеру.
В следующем примере демонстрируется использование шейдера в качестве заливки рисунка. В данном примере шейдер создает градиент с тремя вершинами. Этот градиент имеет три цвета, каждый из них находится у вершины треугольника, между которыми образуется заливка градиентом. В дополнение, цвета меняются местами, создавая эффект анимированного вращения цветов.
Примечание.
Код для этого примера написан Пeтри Лескиненом (Petri Leskinen). Мы благодарим Петри за предоставление этого кода. Примеры и учебные материалы, предоставленные Петри, можно найти по адресу
http://pixelero.wordpress.com
.
Код ActionScript строится на трех методах.
-
init()
: метод
init()
вызывается при загрузке приложения. В этом методе код задает начальные значения для объектов Point, представляющих вершины треугольника. Также код создает экземпляр Sprite с именем
canvas
. Позднее, в методе
updateShaderFill()
, код рисует результат шейдера в объекте
canvas
по одному разу в каждом кадре. В завершение, код загружает файл байт-кода шейдера.
-
onLoadComplete()
: в методе
onLoadComplete()
код создает объект Shader с именем
shader
. Также задаются начальные значения параметров. В завершение код добавляет метод
updateShaderFill()
в качестве прослушивателя события
enterFrame
, то есть он вызывается в каждом кадре один раз для создания эффекта анимации.
-
updateShaderFill()
: метод
updateShaderFill()
вызывается один раз для каждого кадра для создания эффекта анимации. В этом методе код вычисляет и задает значения параметров шейдера. После этого код вызывает метод
beginShaderFill()
, чтобы создать заливку шейдером, а затем вызываются другие API-методы для отрисовки результата шейдера в треугольнике.
Ниже приводится код ActionScript для этого примера. Используйте этот класс в качестве основного класса приложения для проекта, созданного только на базе ActionScript в Flash Builder, или в качестве класса документа для FLA-файла в инструменте Flash Professional.
package
{
import flash.display.Shader;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Point;
import flash.net.URLLoader;
import flash.net.URLLoaderDataFormat;
import flash.net.URLRequest;
public class ThreePointGradient extends Sprite
{
private var canvas:Sprite;
private var shader:Shader;
private var loader:URLLoader;
private var topMiddle:Point;
private var bottomLeft:Point;
private var bottomRight:Point;
private var colorAngle:Number = 0.0;
private const d120:Number = 120 / 180 * Math.PI; // 120 degrees in radians
public function ThreePointGradient()
{
init();
}
private function init():void
{
canvas = new Sprite();
addChild(canvas);
var size:int = 400;
topMiddle = new Point(size / 2, 10);
bottomLeft = new Point(0, size - 10);
bottomRight = new Point(size, size - 10);
loader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.BINARY;
loader.addEventListener(Event.COMPLETE, onLoadComplete);
loader.load(new URLRequest("ThreePointGradient.pbj"));
}
private function onLoadComplete(event:Event):void
{
shader = new Shader(loader.data);
shader.data.point1.value = [topMiddle.x, topMiddle.y];
shader.data.point2.value = [bottomLeft.x, bottomLeft.y];
shader.data.point3.value = [bottomRight.x, bottomRight.y];
addEventListener(Event.ENTER_FRAME, updateShaderFill);
}
private function updateShaderFill(event:Event):void
{
colorAngle += .06;
var c1:Number = 1 / 3 + 2 / 3 * Math.cos(colorAngle);
var c2:Number = 1 / 3 + 2 / 3 * Math.cos(colorAngle + d120);
var c3:Number = 1 / 3 + 2 / 3 * Math.cos(colorAngle - d120);
shader.data.color1.value = [c1, c2, c3, 1.0];
shader.data.color2.value = [c3, c1, c2, 1.0];
shader.data.color3.value = [c2, c3, c1, 1.0];
canvas.graphics.clear();
canvas.graphics.beginShaderFill(shader);
canvas.graphics.moveTo(topMiddle.x, topMiddle.y);
canvas.graphics.lineTo(bottomLeft.x, bottomLeft.y);
canvas.graphics.lineTo(bottomRight.x, bottomLeft.y);
canvas.graphics.endFill();
}
}
}
Ниже представлен исходный код для ядра шейдера ThreePointGradient, который используется для создания файла байт-кода Pixel Bender с именем «ThreePointGradient.pbj».
<languageVersion : 1.0;>
kernel ThreePointGradient
<
namespace : "Petri Leskinen::Example";
vendor : "Petri Leskinen";
version : 1;
description : "Creates a gradient fill using three specified points and colors.";
>
{
parameter float2 point1 // coordinates of the first point
<
minValue:float2(0, 0);
maxValue:float2(4000, 4000);
defaultValue:float2(0, 0);
>;
parameter float4 color1 // color at the first point, opaque red by default
<
defaultValue:float4(1.0, 0.0, 0.0, 1.0);
>;
parameter float2 point2 // coordinates of the second point
<
minValue:float2(0, 0);
maxValue:float2(4000, 4000);
defaultValue:float2(0, 500);
>;
parameter float4 color2 // color at the second point, opaque green by default
<
defaultValue:float4(0.0, 1.0, 0.0, 1.0);
>;
parameter float2 point3 // coordinates of the third point
<
minValue:float2(0, 0);
maxValue:float2(4000, 4000);
defaultValue:float2(0, 500);
>;
parameter float4 color3 // color at the third point, opaque blue by default
<
defaultValue:float4(0.0, 0.0, 1.0, 1.0);
>;
output pixel4 dst;
void evaluatePixel()
{
float2 d2 = point2 - point1;
float2 d3 = point3 - point1;
// transformation to a new coordinate system
// transforms point 1 to origin, point2 to (1, 0), and point3 to (0, 1)
float2x2 mtrx = float2x2(d3.y, -d2.y, -d3.x, d2.x) / (d2.x * d3.y - d3.x * d2.y);
float2 pNew = mtrx * (outCoord() - point1);
// repeat the edge colors on the outside
pNew.xy = clamp(pNew.xy, 0.0, 1.0); // set the range to 0.0 ... 1.0
// interpolating the output color or alpha value
dst = mix(mix(color1, color2, pNew.x), color3, pNew.y);
}
}
Примечание.
Если заливка шейдером применяется в режиме визуализации с использованием графического процессора, цвет области заполнения будет голубым.
Дополнительные сведения о рисовании фигур с помощью API-интерфейса рисования см. в разделе
Использование API рисования
.