2012-10-18 4 views
1

Je suis le tutoriel Pixel Bender basics for Flex and AIR de Joe Ward et le mettre à jour pour Flex 4.5 Flashplayer 11. En travaillant sur la section de grainBlend Cela fonctionne très bien, si j'ai un message "Alerte" pop-up. Sinon, le shader ne rafraîchit pas/ne se met pas à jour lorsque HSlider est modifié. En d'autres termes: Le script s'exécute SI j'ai un message d'alerte actif. Si je supprime le message d'alerte, le blendShader ne fonctionne qu'une seule fois et ne sera jamais mis à jour par la suite.Flex 4.5 blendShader, Pixel Bender pas rafraîchissant

ScriptFlow:

Init() OK

créer shaders OK

détecter HSlider Change OK

updateFilter() OK

mise à jour valeur turbulace de Shader OK

tu pdate image "noise" shader et redraw NOT WORKING

Je crois que l'extrait suivant du tutoriel pourrait être le problème. "... Du fait qu'un objet shader est cloné lorsque vous définissez la propriété blendShader d'un objet d'affichage, vous ne pouvez pas simplement modifier le paramètre de l'objet Shader d'origine.Vous devez également réaffecter l'objet Shade mis à jour à la propriété blendShader ...."

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

Code 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 noyau

<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()); 
    } 

} 
} 

Répondre

0

J'ai abandonné le blendShader. Je l'ai recréé en utilisant des filtres. Ça fonctionne maintenant. En outre, j'ai créé dynamiquement le fond marron et le bruit perlin. Voir ci-dessous!

<?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>`