셰이더 입력 및 매개 변수 값 지정

Flash Player 10 이상, Adobe AIR 1.5 이상

많은 Pixel Bender 셰이더는 셰이더 처리에 사용되는 입력 이미지를 한 개 이상 사용하도록 정의되어 있습니다. 예를 들어 셰이더가 소스 이미지를 받아들인 다음 특정 효과를 적용하여 해당 이미지를 출력하는 것이 일반적입니다. 셰이더의 사용 방법에 따라 입력 값이 자동으로 지정되거나 명시적으로 값을 제공해야 할 수 있습니다. 마찬가지로, 많은 셰이더는 셰이더의 출력을 사용자 정의하는 데 사용되는 매개 변수를 지정합니다. 또한 셰이더를 사용하기 전에 각 매개 변수에 대해 명시적으로 값을 설정해야 합니다.

Shader 객체의 data 속성을 사용하여 셰이더 입력과 매개 변수를 설정하고 특정 셰이더에 입력 또는 매개 변수가 필요한지 확인합니다. data 속성은 ShaderData 인스턴스입니다.

셰이더 입력 및 매개 변수 식별

셰이더 입력 및 매개 변수 값을 지정하는 경우 첫 번째 단계로 사용 중인 특정 셰이더에 입력 이미지 또는 매개 변수가 필요한지 확인합니다. 각 Shader 인스턴스에는 ShaderData 객체가 포함된 data 속성이 있습니다. 셰이더가 입력이나 매개 변수를 정의하면 해당 ShaderData 객체의 속성으로 액세스됩니다. 속성 이름은 셰이더 소스 코드에서 입력 및 매개 변수에 대해 지정된 이름과 일치합니다. 예를 들어 셰이더에서 src라는 입력을 정의하면 ShaderData 객체에 해당 입력을 나타내는 src 속성이 있습니다. 입력을 나타내는 각 속성은 ShaderInput 인스턴스이며, 매개 변수를 나타내는 각 속성은 ShaderParameter 인스턴스입니다.

셰이더의 작성자가 셰이더에 필요한 입력 이미지 값 및 매개 변수, 입력 이미지 값 및 매개 변수가 나타내는 대상, 적합한 값 등을 나타내는 셰이더 설명서를 제공하는 것이 좋습니다.

그러나 셰이더가 문서화되어 있지 않으며 해당 소스 코드가 없는 경우 셰이더 데이터를 검사하여 입력과 매개 변수를 확인할 수 있습니다. 입력과 매개 변수를 나타내는 속성은 동적으로 ShaderData 객체에 추가됩니다. 따라서 for..in 루프를 사용하여 ShaderData 객체를 검사하고 연관된 셰이더에서 입력 또는 매개 변수를 정의하는지 확인할 수 있습니다. 셰이더 메타데이터에 액세스에 설명된 것처럼 셰이더에 대해 정의된 모든 메타데이터 값은 Shader.data 속성에 추가된 동적 속성으로도 액세스됩니다. 이 기술을 사용하여 셰이더 입력과 매개 변수를 확인하는 경우 동적 속성의 데이터 유형을 검사합니다. 속성이 ShaderInput 인스턴스이면 입력을 나타내고, ShaderParameter 인스턴스이면 매개 변수를 나타냅니다. 그렇지 않으면 메타데이터 값입니다. 다음 예제에서는 for..in 루프를 사용하여 셰이더 data 속성의 동적 속성을 검사하는 방법을 보여 줍니다. 각 입력(ShaderInput 객체)은 inputs이라는 Vector 인스턴스에 추가됩니다. 각 매개 변수(ShaderParameter 객체)는 parameters라는 Vector 인스턴스에 추가됩니다. 마지막으로, 모든 메타데이터 속성은 metadata라는 Vector 인스턴스에 추가됩니다. 이 예제에서는 myShader라는 Shader 인스턴스가 이미 작성되었다고 가정합니다.

var shaderData:ShaderData = myShader.data; 
var inputs:Vector.<ShaderInput> = new Vector.<ShaderInput>(); 
var parameters:Vector.<ShaderParameter> = new Vector.<ShaderParameter>(); 
var metadata:Vector.<String> = new Vector.<String>(); 
 
for (var prop:String in shaderData) 
{ 
    if (shaderData[prop] is ShaderInput) 
    { 
        inputs[inputs.length] = shaderData[prop]; 
    } 
    else if (shaderData[prop] is ShaderParameter) 
    { 
        parameters[parameters.length] = shaderData[prop]; 
    } 
    else 
    { 
        metadata[metadata.length] = shaderData[prop]; 
    } 
} 
 
// do something with the inputs or properties

셰이더 입력 값 지정

셰이더 처리에 사용되는 입력 이미지가 한 개 이상 필요한 셰이더가 많습니다. 그러나 대부분의 경우 입력은 Shader 객체를 사용할 때 자동으로 지정됩니다. 예를 들어 셰이더에 한 개의 입력이 필요하며 해당 셰이더가 필터로 사용된다고 가정합니다. 표시 객체나 BitmapData 객체에 필터를 적용하면 해당 객체가 입력으로 자동 설정됩니다. 이 경우 명시적으로 입력 값을 설정하지 않습니다.

그러나 경우에 따라, 특히 셰이더에서 여러 입력을 정의하는 경우 입력 값을 명시적으로 설정합니다. 셰이더에 정의된 각 입력은 ActionScript에서 ShaderInput 객체로 나타납니다. 셰이더 입력 및 매개 변수 식별에 설명된 것처럼 ShaderInput 객체는 Shader 객체의 data 속성에 있는 ShaderData 인스턴스의 속성입니다. 예를 들어 셰이더에서 src라는 입력을 정의하며 해당 셰이더가 myShader라는 Shader 객체에 연결되어 있다고 가정합니다. 이 경우 다음 식별자를 사용하여 src 입력에 해당하는 ShaderInput 객체에 액세스합니다.

myShader.data.src

각 ShaderInput 객체에는 입력 값을 설정하는 데 사용되는 input 속성이 있습니다. input 속성을 BitmapData 인스턴스로 설정하여 이미지 데이터를 지정합니다. input 속성을 BitmapData 또는 Vector.<Number> 인스턴스로 설정하여 이진 또는 숫자 데이터를 지정할 수도 있습니다. BitmapData 또는 Vector.<Number> 인스턴스를 입력으로 사용하는 방법에 대한 자세한 내용은 Adobe Flash 플랫폼용 Adobe ActionScript 3.0 참조 설명서ShaderInput.input 목록을 참조하십시오.

input 속성 외에도 ShaderInput 객체에는 입력에 필요한 이미지 유형을 확인하는 데 사용할 수 있는 속성이 있습니다. 이러한 속성에는 width, heightchannels 속성이 포함됩니다. 각 ShaderInput 객체에는 입력에 대해 명시적 값을 제공해야 하는지 여부를 확인하는 데 유용한 index 속성도 있습니다. 셰이더에 자동으로 설정되는 개수보다 많은 입력이 필요한 경우 해당 입력의 값을 설정합니다. 셰이더를 사용하는 다양한 방법 및 입력 값이 자동으로 설정되는지 여부에 대한 자세한 내용은 셰이더 사용을 참조하십시오.

셰이더 매개 변수 값 지정

일부 셰이더는 셰이더가 결과를 만들 때 사용하는 매개 변수 값을 정의합니다. 예를 들어 이미지의 밝기를 변경하는 셰이더는 작업이 밝기에 미치는 영향을 결정하는 밝기 매개 변수를 지정할 수 있습니다. 셰이더의 매개 변수 정의에 따라 셰이더에 정의된 단일 매개 변수에 하나 또는 여러 개의 값이 필요할 수 있습니다. 셰이더에 정의된 각 매개 변수는 ActionScript에서 ShaderParameter 객체로 나타납니다. 셰이더 입력 및 매개 변수 식별에 설명된 것처럼 ShaderParameter 객체는 Shader 객체의 data 속성에 있는 ShaderData 인스턴스의 속성입니다. 예를 들어 셰이더에서 brightness라는 매개 변수를 정의하며 myShader라는 Shader 객체로 해당 셰이더를 나타낸다고 가정합니다. 이 경우 다음 식별자를 사용하여 brightness 매개 변수에 해당하는 ShaderParameter에 액세스합니다.

myShader.data.brightness

매개 변수에 대해 값을 한 개 이상 설정하려면 값이 한 개 이상 포함된 ActionScript 배열을 만든 다음 ShaderParameter 객체의 value 속성에 해당 배열을 지정합니다. 단일 셰이더 매개 변수에 값이 여러 개 필요할 수 있으므로 value 속성은 Array 인스턴스로 정의됩니다. 셰이더 매개 변수에 단일 값이 필요한 경우에도 Array 객체에 값을 래핑하여 ShaderParameter.value 속성에 지정해야 합니다. 다음 샘플에서는 단일 값을 value 속성으로 설정하는 방법을 보여 줍니다.

myShader.data.brightness.value = [75];

셰이더에 대한 Pixel Bender 소스 코드에서 매개 변수의 기본값을 정의하는 경우 Shader 객체를 만들 때 기본값이 포함된 배열이 만들어져 ShaderParameter 객체의 value 속성에 지정됩니다. value 속성에 배열이 지정되고 나면(기본 배열인 경우 포함) 배열 요소의 값을 변경하여 매개 변수 값을 변경할 수 있습니다. 새 배열을 만들어 value 속성에 지정할 필요가 없습니다.

다음 예제에서는 ActionScript에서 셰이더의 매개 변수 값을 설정하는 방법을 보여 줍니다. 이 예제에서 셰이더는 color라는 매개 변수를 정의합니다. color 매개 변수는 Pixel Bender 소스 코드에 float4 변수로 선언되어 있으므로 4개의 부동 소수점 숫자 배열입니다. 이 예제에서 color 매개 변수 값은 계속 변경되며, 변경될 때마다 셰이더가 사용되어 화면에 색상이 설정된 사각형을 그립니다. 그 결과 애니메이션 색상 변경이 만들어집니다.

참고: 이 예제의 코드는 Ryan Taylor에 의해 작성되었습니다. 이 예제를 공유해 주신 Ryan 씨께 감사드립니다. Ryan의 포트폴리오와 그가 작성한 내용은 www.boostworthy.com/에서 보고 읽을 수 있습니다.

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

  • init(): init() 메서드의 코드에서는 셰이더가 들어 있는 Pixel Bender 바이트코드 파일을 로드합니다. 파일이 로드되면 onLoadComplete() 메서드가 호출됩니다.

  • onLoadComplete(): onLoadComplete() 메서드의 코드에서는 shader라는 Shader 객체를 만듭니다. 또한 texture라는 Sprite 인스턴스를 만듭니다. renderShader() 메서드의 코드에서는 프레임마다 한 번씩 셰이더 결과를 texture로 그립니다.

  • onEnterFrame(): onEnterFrame() 메서드는 프레임당 한 번 호출되어 애니메이션 효과를 만듭니다. 이 메서드의 코드에서는 셰이더 매개 변수 값을 새 색상으로 설정한 다음 renderShader() 메서드를 호출하여 셰이더 결과를 사각형으로 그립니다.

  • renderShader(): renderShader() 메서드의 코드에서는 Graphics.beginShaderFill() 메서드를 호출하여 셰이더 채우기를 지정합니다. 그런 다음 채우기가 셰이더 출력(생성된 색상)에 의해 정의되는 사각형을 그립니다. 이와 같은 방식으로 셰이더를 사용하는 방법에 대한 자세한 내용은 셰이더를 드로잉 채우기로 사용을 참조하십시오.

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

package 
{ 
    import flash.display.Shader; 
    import flash.display.Sprite; 
    import flash.events.Event; 
    import flash.net.URLLoader; 
    import flash.net.URLLoaderDataFormat; 
    import flash.net.URLRequest; 
     
    public class ColorFilterExample extends Sprite 
    { 
        private const DELTA_OFFSET:Number = Math.PI * 0.5; 
        private var loader:URLLoader; 
        private var shader:Shader; 
        private var texture:Sprite; 
        private var delta:Number = 0; 
         
        public function ColorFilterExample() 
        { 
            init(); 
        } 
         
        private function init():void 
        { 
            loader = new URLLoader(); 
            loader.dataFormat = URLLoaderDataFormat.BINARY; 
            loader.addEventListener(Event.COMPLETE, onLoadComplete); 
            loader.load(new URLRequest("ColorFilter.pbj")); 
        } 
         
        private function onLoadComplete(event:Event):void 
        { 
            shader = new Shader(loader.data); 
             
            texture = new Sprite(); 
             
            addChild(texture); 
             
            addEventListener(Event.ENTER_FRAME, onEnterFrame); 
        } 
        private function onEnterFrame(event:Event):void 
        { 
            shader.data.color.value[0] = 0.5 + Math.cos(delta - DELTA_OFFSET) * 0.5; 
            shader.data.color.value[1] = 0.5 + Math.cos(delta) * 0.5; 
            shader.data.color.value[2] = 0.5 + Math.cos(delta + DELTA_OFFSET) * 0.5; 
            // The alpha channel value (index 3) is set to 1 by the kernel's default 
            // value. This value doesn't need to change. 
             
            delta += 0.1; 
             
            renderShader(); 
        } 
         
        private function renderShader():void 
        { 
            texture:graphics.clear(); 
            texture.graphics.beginShaderFill(shader); 
            texture.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight); 
            texture.graphics.endFill(); 
        } 
    } 
}

다음은 ColorFilter 셰이더 커널에 대한 소스 코드이며, "ColorFilter.pbj" Pixel Bender 바이트코드 파일을 만드는 데 사용됩니다.

<languageVersion : 1.0;> 
kernel ColorFilter 
< 
    namespace : "boostworthy::Example"; 
    vendor : "Ryan Taylor"; 
    version : 1; 
    description : "Creates an image where every pixel has the specified color value."; 
> 
{ 
    output pixel4 result; 
     
    parameter float4 color 
    < 
        minValue:float4(0, 0, 0, 0); 
        maxValue:float4(1, 1, 1, 1); 
        defaultValue:float4(0, 0, 0, 1); 
    >; 
     
    void evaluatePixel() 
    { 
        result = color; 
    } 
}

매개 변수가 문서화되어 있지 않은 셰이더를 사용하는 경우 ShaderParameter 객체의 type 속성을 검사하여 배열에 포함해야 하는 요소의 유형 및 개수를 확인할 수 있습니다. type 속성은 셰이더 자체에 정의된 매개 변수의 데이터 유형을 나타냅니다. 각 매개 변수 유형에 필요한 요소 수와 유형 목록은 ActionScript 3.0 참조 설명서의 ShaderParameter.value 속성 목록을 참조하십시오.

각 ShaderParameter 객체에는 셰이더의 매개 변수 순서에서 각 매개 변수의 위치를 나타내는 index 속성도 있습니다. 이러한 속성 외에도 ShaderParameter 객체는 셰이더의 작성자가 제공한 메타데이터 값이 포함된 추가 속성을 가질 수 있습니다. 예를 들어 작성자는 매개 변수에 대해 최소값, 최대값 및 기본값과 같은 메타데이터 값을 지정할 수 있습니다. 작성자가 지정한 모든 메타데이터 값은 ShaderParameter 객체에 동적 속성으로 추가됩니다. 이러한 속성을 검사하려면 for..in 루프를 사용하여 ShaderParameter 객체의 동적 속성을 반복함으로써 해당 메타데이터를 확인합니다. 다음 예제에서는 for..in 루프를 사용하여 ShaderParameter 객체의 메타데이터를 확인하는 방법을 보여 줍니다. 각 메타데이터 값은 metadata라는 Vector 인스턴스에 추가됩니다. 이 예제에서는 myShader라는 Shader 인스턴스가 이미 만들어졌으며 brightness라는 매개 변수가 있다고 가정합니다.

var brightness:ShaderParameter = myShader.data.brightness; 
var metadata:Vector.<String> = new Vector.<String>(); 
 
for (var prop:String in brightness) 
{ 
    if (brightness[prop] is String) 
    { 
        metadata[metadata.length] = brightness[prop]; 
    } 
} 
 
// do something with the metadata