1

我正在关注 Joe Ward 的Flex 和 AIR教程的 Pixel Bender 基础知识,并为 Flex 4.5 Flashplayer 11 更新它。在grainBlend 部分工作时,如果我弹出“警报”消息,它效果很好。否则,当 HSlider 更改时,着色器不会刷新/更新。

换句话说:如果我有一个活动的警报消息,脚本就会运行。如果我删除警报消息,blendShader 只能工作一次,之后就不会更新。

脚本流:

初始化()好的

创建着色器确定

检测 HSlider Change OK

updateFilter() 确定

更新 Shader 的湍流值 OK

更新图像“噪声”着色器并重绘不工作

我相信本教程的以下摘录可能是问题所在。“...因为在设置显示对象的 blendShader 属性时会克隆着色器对象,所以不能简单地更改原始 Shader 对象的参数。您还必须将更新后的 Shade 对象重新分配给 blendShader 属性...。”

    shader.data.turbulence.value = [turbulence.value];
noise.blendMode = BlendMode.SHADER;
noise.blendShader = shader;

弹性代码

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
           xmlns:s="library://ns.adobe.com/flex/spark"
           xmlns:mx="library://ns.adobe.com/flex/mx"
           contentCreationComplete="init()" 
           backgroundColor="0x666666">
<fx:Script>
    <![CDATA[
        import mx.controls.Alert;
        import mx.events.SliderEvent;

        //Embed the Pixel Bender kernel in the output SWF
        [Embed(source="kernels/grainblend.pbj", mimeType="application/octet-stream")]
        private var GrainBlendKernel:Class;

        //Create the Shader object
        [Bindable]
        private var shader:Shader = new Shader( new GrainBlendKernel() );

        private function init():void
        {   
            //Set the slider values based on the parameter metadata
            turbulence.minimum = shader.data.turbulence.minValue;
            turbulence.maximum = shader.data.turbulence.maxValue;
            turbulence.value   = shader.data.turbulence.defaultValue;
            turbulence.addEventListener( SliderEvent.CHANGE, updateFilter );
            //Apply the blend
            noise.blendShader = shader;
        }

        private function updateFilter( event:Event ):void
        {
            trace(turbulence.value);//print slider
            //Alert.show("Hit");
            shader.data.turbulence.value = [turbulence.value];
            trace("shader's value: "+shader.data.turbulence.value);
            noise.blendMode = BlendMode.SHADER;
            noise.blendShader = shader;

        }

    ]]>
</fx:Script>
<s:VGroup width="100%">
    <s:HGroup width="100%" height="100%" horizontalAlign="center" verticalAlign="top">
        <s:VGroup>
            <mx:Canvas width="195" height="194" backgroundColor="#663300"/>
            <s:Label text="Background" textAlign="center" width="196"/>
        </s:VGroup>
        <s:VGroup>
            <s:Image source="img/noise.jpg" width="195"  height="194"/>
            <s:Label text="Perlin noise" width="196" textAlign="center"/>
        </s:VGroup>
        <s:VGroup>
            <mx:Canvas width="195" height="194" backgroundColor="#663300">
                <s:Image source="img/noise.jpg" id="noise" width="195" height="194"/>
            </mx:Canvas>
            <s:Label text="Grain blend" width="196" textAlign="center"/>                
        </s:VGroup>
    </s:HGroup>
    <s:HGroup width="100%" horizontalAlign="center" verticalAlign="top">
        <s:Label text="{turbulence.value}"/>
        <s:HSlider id="turbulence" width="200"/>
    </s:HGroup>
</s:VGroup>

像素弯曲内核

<languageVersion: 1.0;>

kernel GrainBlend
<   namespace : "com.adobe.example";
vendor : "Adobe Systems Inc.";
version : 1;
description : "Creates a wood grain or marbleing effect"; >
{
input image4 background;    
input image4 noise;

output pixel4 dst;
parameter float turbulence
<
    maxValue : 500.0;
    minValue : 0.0;
    defaultValue : 150.0;
>;

void evaluatePixel()
{   
    pixel4 a = sampleNearest(background, outCoord());
    pixel4 b = sampleNearest(noise, outCoord());


    float alpha = a.a; //save the original alpha

    if( (b.a > 0.0) && (a.a > 0.0)){
        float seed = outCoord().x + (((b.r + b.g + b.b)/3.0)  * turbulence);

        float grain = (0.7 * sin(seed) + 0.3 * sin(2.0 * seed + 0.3) + 0.2 * sin(3.0 * seed + 0.2));
        dst = sampleNearest(background, outCoord()) * (grain + 0.5);
        dst.a = alpha; //restore the original alpha           
    }
    else {
        //Just copy the background pixel outside the area of the noise image
        dst = sampleNearest(background, outCoord());
    }

}
}
4

1 回答 1

0

我放弃了 blendShader。我使用过滤器重新创建了它。现在可以了。此外,我动态地创建了棕色背景和柏林噪声。见下文!

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
           xmlns:s="library://ns.adobe.com/flex/spark"
           xmlns:mx="library://ns.adobe.com/flex/mx"
           creationComplete="init()"
           backgroundColor="0x666666">
<fx:Script>
    <![CDATA[
        import mx.events.SliderEvent;

        import spark.filters.ShaderFilter;


        //Embed the Pixel Bender kernel in the output SWF
        [Embed(source="kernels/grainblend.pbj", mimeType="application/octet-stream")]
        private var GrainBlendKernel:Class;

        //Create the Shader object
        private var shader:Shader = new Shader( new GrainBlendKernel() );
        private var shaderFilter:ShaderFilter =  new ShaderFilter(shader);
        private var myBrown:BitmapData;
        private var myPerlin:BitmapData;

        private function init():void
        {   
            myPerlin = new BitmapData(200, 200, false, 0x00CCCCCC);
            myBrown = new BitmapData(200, 200, false, 0x00663300);
            //Set the slider values based on the parameter metadata
            turbulence.minimum = shader.data.turbulence.minValue;
            turbulence.maximum = shader.data.turbulence.maxValue;
            turbulence.value   = shader.data.turbulence.defaultValue;
            turbulence.addEventListener( SliderEvent.CHANGE, updateFilter );
            myPerlin.perlinNoise(100, 80, 6, Math.floor(Math.random() * 10), false, true, 7, true, null);
            //Set the displayed images to the perlinNoise
            perlinNoise.source = myGrain.source =myPerlin;
            //Set the background image to Brown
            backGround.source = myBrown;
            shader.data.background.input = myBrown;
            myGrain.filters = [shaderFilter];
        }


        private function updateFilter( event:Event ):void
        {
            shader.data.turbulence.value = [turbulence.value];
            myGrain.filters = [shaderFilter];
        }
    ]]>
</fx:Script>
<s:VGroup width="100%">
    <s:HGroup width="100%" height="100%" horizontalAlign="center" verticalAlign="top">
        <s:VGroup>
            <s:BitmapImage id="backGround" width="200" height="200"/>
            <s:Label text="Background" textAlign="center" width="200"/>
        </s:VGroup>
        <s:VGroup>              
            <s:BitmapImage id="perlinNoise" width="200" height="200"/>
            <s:Label text="Perlin noise" width="200" textAlign="center"/>
        </s:VGroup>
        <s:VGroup>
            <s:BitmapImage id="myGrain" width="200" height="200" />
            <s:Label text="Grain blend" width="200" textAlign="center"/>                
        </s:VGroup>
    </s:HGroup>
    <s:HGroup width="100%" horizontalAlign="center" verticalAlign="top">
        <s:Label text="{turbulence.value}"/>
        <s:HSlider id="turbulence" width="200"/>
    </s:HGroup>
</s:VGroup>
    </s:Application>`
于 2012-10-22T07:04:38.567 回答