我正在关注Joe Ward的Pixel Bender basics for Flex and AIR教程,并为Flex 4.5 Flashplayer 11更新它。 在处理grainBlend部分时工作很棒,如果我弹出“警报”消息。否则,在更改HSlider时,着色器不会刷新/更新。
换句话说:如果我有一条活动的Alert消息,脚本就会运行。如果我删除了Alert Message,则blendShader只能运行一次,之后不再更新。
ScriptFlow:
初始化()确定
创建着色器确定
检测HSlider改变确定
updateFilter()确定
更新Shader的turbulace值OK
更新图像“噪音”着色器并重绘不工作
我相信教程中的以下摘录可能就是问题所在。 “...因为在设置显示对象的blendShader属性时克隆了着色器对象,所以不能简单地更改原始Shader对象的参数。还必须将更新的Shade对象重新分配给blendShader属性....”
shader.data.turbulence.value = [turbulence.value];
noise.blendMode = BlendMode.SHADER;
noise.blendShader = shader;
Flex代码
<?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>
Pixel Bender Kernel
<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());
}
}
}
答案 0 :(得分:0)
我放弃了blendShader。我使用过滤器重新创建它。它现在有效。另外,我动态创建了棕色背景和perlin噪音。 见下文!
<?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>`