셰이더를 드로잉 채우기로 사용

Flash Player 10 이상, Adobe AIR 1.5 이상

셰이더를 사용하여 드로잉 채우기를 만드는 경우 드로잉 API 메서드를 사용하여 벡터 모양을 만듭니다. 드로잉 API를 사용하여 비트맵 이미지를 비트맵 채우기로 사용할 때와 동일하게 셰이더의 출력은 모양을 채우는 데 사용합니다. 셰이더 채우기를 만들려면 모양 그리기를 시작할 코드 지점에서 Graphics 객체의 beginShaderFill() 메서드를 호출합니다. 이 샘플에서와 같이 beginShaderFill() 메서드에 Shader 객체를 첫 번째 인수로 전달합니다.

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

셰이더를 드로잉 채우기로 사용할 때는 셰이더에 필요한 입력 이미지 값과 매개 변수 값을 설정합니다.

다음 예제에서는 셰이더를 드로잉 채우기로 사용하는 방법을 보여 줍니다. 이 예제에서 셰이더는 3점 그래디언트를 만듭니다. 이 그래디언트는 삼각형의 각 점에 세 개의 색상을 표시하며 세 점 사이에서 그래디언트가 블렌드됩니다. 또한 색상이 회전하여 애니메이션이 적용된 회전하는 색상 효과를 만듭니다.

참고: 이 예제의 코드는 Petri Leskinen에 의해 작성되었습니다. 이 예제를 공유해 주신 Petri 씨께 감사드립니다. Petri의 예제와 자습서는 http://pixelero.wordpress.com/에서 보다 자세히 볼 수 있습니다.

ActionScript 코드는 다음 세 가지 메서드를 중심으로 합니다.

  • init(): init() 메서드는 응용 프로그램이 로드될 때 호출됩니다. 이 메서드의 코드에서는 삼각형의 점을 나타내는 Point 객체의 초기 값을 설정합니다. 또한 canvas라는 Sprite 인스턴스를 만듭니다. 나중에 updateShaderFill()의 코드에서는 프레임마다 한 번씩 셰이더 결과를 canvas로 그립니다. 마지막으로 코드에서는 셰이더 바이트코드 파일을 로드합니다.

  • onLoadComplete(): onLoadComplete() 메서드의 코드에서는 shader라는 Shader 객체를 만듭니다. 또한 초기 매개 변수 값을 설정합니다. 마지막으로 코드에서는 enterFrame 이벤트에 대한 리스너로 updateShaderFill() 메서드를 추가합니다. 따라서 이 메서드는 프레임마다 한 번씩 호출되어 애니메이션 효과를 만듭니다.

  • updateShaderFill(): updateShaderFill() 메서드는 프레임마다 한 번씩 호출되어 애니메이션 효과를 만듭니다. 이 메서드의 코드에서는 셰이더 매개 변수의 값을 계산하고 설정합니다. 그런 다음 beginShaderFill() 메서드를 호출하여 셰이더 채우기를 만들고 다른 드로잉 API 메서드를 호출하여 셰이더 결과를 삼각형에 그립니다.

다음은 이 예제에 대한 ActionScript 코드입니다. 이 클래스는 Flash Builder에서 ActionScript 전용 프로젝트의 기본 응용 프로그램 클래스로 사용하거나 Flash Professional에서 FLA 파일의 문서 클래스로 사용합니다.

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 셰이더 커널에 대한 소스 코드이며, "ThreePointGradient.pbj" Pixel Bender 바이트코드 파일을 만드는 데 사용됩니다.

<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); 
    } 
}
참고: GPU(Graphics Processing Unit)에서 렌더링할 때 셰이더 채우기를 사용하는 경우 채워진 영역은 녹청 색상이 됩니다.

드로잉 API를 사용하여 모양을 그리는 방법에 대한 자세한 내용은 드로잉 API 사용을 참조하십시오.