1

我附上了一个可以在 CS 5.5 中运行的带有 FLA 的 zip。动画包含一个性能分析器和滑块来控制各种参数。

演示: http ://separdi.ehclients.com/alivetest/index.html 点击任意位置开始动画

文件: https ://www.dropbox.com/s/4rcpvzo1h7br8fh/alivesource.zip

我编写了一个程序,它逐个像素地绘制线条并以波浪状的方式对其进行动画处理,并使用置换贴图置换某些像素。

这是每个循环发生的情况:

  1. 前一个循环中的显示对象和变量被清除
  2. 位移图存储在位图数据对象中
  3. 通过读取存储在数组中的 y 坐标,逐像素绘制一条线。它的值也可以使用相应的位移图和正弦波数据进行更改。

我有设置滑块,您可以使用它来控制绘制的线数(linecount)、每条线的宽度(canvaswidth)和每条线的分辨率(res)。

性能很差,我希望您能帮助优化它。也许我无法优化我的代码,请告诉我。

我不认为缓存为位图数据是可能的,因为线条是永久运动的

请记住,我真的很想保留 35 行和每次迭代 1 像素的分辨率

非常感谢

更新:我现在使用 drawPath 来绘制线条,而不是逐个像素地绘制。

/*
Click anywhere on the stage to start anim
*/


import flash.display.BitmapData;
import com.greensock.*;
import flash.display.Shape;
import uk.co.soulwire.*;
import net.hires.debug.Stats;
import uk.co.soulwire.gui.SimpleGUI;
import flash.display.MovieClip;
import flash.display.Sprite;


/*
Performance analyser and variable sliders
*/
var stats:Stats;
var gui:SimpleGUI;
var guiholder:MovieClip;
stats=new Stats();
stats.x = 1200;
stats.y = 0;
addChild(stats);
gui = new SimpleGUI(this,"Parameters","h",1000,0);
gui.show();

/*
Stores the base coordinates
*/
var c:Coordinates;
c=new Coordinates();

/*
Holds the lines
*/
var holder:MovieClip = new MovieClip  ;
addChild(holder);


/*
Generic variables
*/
var i:uint;
var j:uint;
var line:Sprite;
var lines:Array = [];
var bmd:BitmapData;
var brightness = 0;
var sinus = 0;






/**
*
Parameters used to control the animaitons and extrusions
*
**/


/*
How many pixels do we draw in each loop?
*/
var scaleFactor:Number=2
var canvasWidth:Number = 999;
var lineCount:Number = 35;
var res = 1;//Skip res-1 pixels per loop to lower the resolution

/*
Displacement map properties
*/
var extrusion:Number = 1;
var extrusiontarget:Number = .1;
var tolerance:Number = 1;
var smoothness = 10;

//Sinewave 
var lasti = 0;
var sinedirection = -1;
var sineamplitude:Number = 3;
var sinespeed = 0.5;
var sinedensity = 100;

/*
Breathing animation
*/
var inhale:Number = 2;
var exhale:Number = 2;
var beforeInhale:Number = 0;
var beforeExhale:Number = 0;

/*
Add sliders to control the above variables
*/
gui.addGroup("Pixels being drawn");
gui.addSlider("lineCount", 5, 35);
gui.addSlider("canvasWidth",30,999);
gui.addSlider("res",1,10);

gui.addGroup("Displacement Map");
gui.addSlider("smoothness", 1, 100,{callback:setBlur});
gui.addSlider("tolerance", 1, 255);
gui.addSlider("extrusiontarget", 0.1, 3);

gui.addGroup("Sinwave");
gui.addSlider("sinedirection",-1,1);
gui.addSlider("sineamplitude",0,30);
gui.addSlider("sinespeed",0,10);

gui.addGroup("Breathing");
gui.addSlider("beforeInhale",0,5);
gui.addSlider("inhale",0,5);
gui.addSlider("beforeExhale",0,5);
gui.addSlider("exhale",0,5);




/**
Loop
**/
function myEnterFrame(event:Event):void {
    /*
    Start a new iteration of line drawing, triggered when you click anywhere ons tage
    */
    drawLines();
}





function drawLines():void {


    for (i=0; i<lines.length; i++) {
        holder.removeChild(lines[i]);
        lines[i] = null;
    }
    lines = [];
    for (i=0; i<lineCount; i++) {
        drawLine(i);
    }

}


function resetBitmapData(){
    bmd = null;
    bmd = new BitmapData(canvasWidth,1000);
    bmd.draw(mc);
    mc.visible = false;
}


/**
plot the cordinates of each point absed on sin data and bmp brihgtness
**/


var targety:Number;
var myPath:GraphicsPath;
var myStroke:GraphicsStroke;
var myDrawing:Vector.<IGraphicsData > ;
var myFill:GraphicsSolidFill;
myFill= new GraphicsSolidFill();
myFill.color = 0x000000;

function drawLine(linenumber):void {
    line=new Sprite();
    holder.addChild(line);
    myPath= new GraphicsPath(new Vector.<int>(), new Vector.<Number>());
    myStroke = new GraphicsStroke(res);
    myStroke.fill = new GraphicsSolidFill(0xff0000);// solid stroke
    for (j=0; j<canvasWidth; j+=res) {
        brightness = Math.ceil(getbrightness(getcolor(j,c.coords[linenumber][j]))/tolerance) ;
        sinus= Math.sin((j + (lasti * sinespeed)) / sinedensity) * sineamplitude;
        targety=c.coords[linenumber][j]-(sinus*0)-(brightness*extrusion)-(sinus*(linenumber-15)*1);
        myPath.commands.push(2);
        myPath.data.push(j,targety);
    }
    myPath.commands.push(2);
    myPath.data.push(0,1000);
    myDrawing = new Vector.<IGraphicsData>();
    myDrawing.push(myStroke,myFill, myPath);
    line.graphics.drawGraphicsData(myDrawing);
    lines.push(line);
    lasti -=  sinedirection;
}


/*
Functions to retrieve brightness of displacement map
*/

function getcolor(xx,targety):uint {
    var pixelValue:uint = bmd.getPixel(xx,targety);
    return pixelValue;
}


function getbrightness(colour):Number {
    var R:Number = 0;
    var G:Number = 0;
    var B:Number = 0;
    R +=  colour >> 16 & 0xFF;
    G +=  colour >> 8 & 0xFF;
    B +=  colour & 0xFF;
    var br = Math.sqrt(R * R * .241 + G * G * .691 + B * B * .068);
    return br;
}

/*
Makes the displacment map "breathe"
*/

function grow():void {
    TweenLite.to(this,inhale,{extrusion:extrusiontarget,onComplete:shrink,delay:beforeInhale});
}

function shrink():void {
    TweenLite.to(this,exhale,{extrusion:0,onComplete:grow,delay:beforeExhale});
}




/*
Smoothness of displacement map
*/
var blur:BlurFilter = new BlurFilter();

function setBlur():void {
    trace("sb");
    blur.blurX = smoothness;
    blur.blurY = smoothness;
    blur.quality = BitmapFilterQuality.HIGH;
    mc.word.filters = [blur];
    //reset the bitmap data
    resetBitmapData()
}

function mouseDownHandler(e) {
    grow();
    addEventListener(Event.ENTER_FRAME,myEnterFrame);
}
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);

//Draws lines;
setBlur();
drawLines();

旧代码:

/*
Click anywhere on the stage to start anim
*/


import flash.display.BitmapData;
import com.greensock.*;
import flash.display.Shape;
import uk.co.soulwire.*;
import net.hires.debug.Stats;
import uk.co.soulwire.gui.SimpleGUI;
import flash.display.MovieClip;


/*
Performance analyser and variable sliders
*/
var stats:Stats;
var gui:SimpleGUI;
var guiholder:MovieClip;
stats=new Stats();
stats.x = 1200
stats.y = 0;
addChild(stats);
gui = new SimpleGUI(this,"Parameters","h",1000,0);
gui.show();

/*
Stores the base coordinates
*/
var c:Coordinates;
c=new Coordinates();

/*
Holds the lines
*/
var holder:MovieClip=new MovieClip
addChild(holder)


/*
Generic variables
*/
var i:uint;
var j:uint;
var line:Shape;
var lines:Array = [];
var bmd:BitmapData;
var brightness = 0;
var sinus=0;






/**
*
Parameters used to control the animaitons and extrusions
*
**/


/*
How many pixels do we draw in each loop?
*/
var canvaswidth:Number = 999;
var linecount:Number=35
var res=2//Skip res-1 pixels per loop to lower the resolution

/*
Displacement map properties
*/
var extrusion:Number = 1;
var extrusiontarget:Number = .1;
var tolerance:Number = 1;
var smoothness = 10;

//Sinewave 
var lasti = 0;
var sinedirection = -1;
var sineamplitude:Number = 3;
var sinespeed = 0.5;
var sinedensity = 100;

/*
Breathing animation
*/
var inhale:Number = 2;
var exhale:Number = 2;
var beforeInhale:Number = 0;
var beforeExhale:Number = 0;

/*
Add sliders to control the above variables
*/
gui.addGroup("Pixels being drawn")
gui.addSlider("linecount", 5, 35);
gui.addSlider("canvaswidth",30,999);
gui.addSlider("res",1,10);

gui.addGroup("Displacement Map")
gui.addSlider("smoothness", 1, 100,{callback:setblur});
gui.addSlider("tolerance", 1, 255);
gui.addSlider("extrusiontarget", 0.1, 3);

gui.addGroup("Sinwave")
gui.addSlider("sinedirection",-1,1);
gui.addSlider("sineamplitude",0,30);
gui.addSlider("sinespeed",0,10);

gui.addGroup("Breathing")
gui.addSlider("beforeInhale",0,5);
gui.addSlider("inhale",0,5);
gui.addSlider("beforeExhale",0,5);
gui.addSlider("exhale",0,5);




/**
Loop
**/
function myEnterFrame(event:Event):void {
    /*
    Start a new iteration of line drawing, triggered when you click anywhere ons tage
    */
    initdraw();
}




/**
Clear the lines
Clear the bmp data
Redraw the bitmpa data
Redraw the lines
**/

function initdraw():void {
    /*
    Clear previous lines and displacement map data
    Lance drawing of 35 lines
    */
    for (i=0; i<lines.length; i++) {
        holder.removeChild(lines[i]);
        lines[i] = null;
    }
    bmd = null;
    bmd = new BitmapData(canvaswidth,400);
    bmd.draw(mc);
    lines = [];
    for (i=0; i<35; i++) {
//  for (i=0; i<c.coords.length; i++) {
        drawlines(i);
    }

}


/**
plot the cordinates of each point absed on sin data and bmp brihgtness
**/

function drawlines(linenumber):void {
    /*
    Start to draw a line
    */
    line =new Shape();
    line.graphics.lineStyle(1, 0xdddddd);
    line.graphics.beginFill(0x000000);
    line.graphics.moveTo(-1,0);
    /*
    Increase length by 1 * times resolution and 
    Adjust y values based on displacement map and sinewave data
    */
    for (j=0; j<canvaswidth; j+=res) {
        if (c.coords[linenumber][j] ==1100) {
            line.graphics.lineStyle(1, 0x000000);
        } else {
            line.graphics.lineStyle(1, 0xFFffff);
        }
        brightness = Math.ceil(getbrightness(getcolor(j,c.coords[linenumber][j]))/tolerance) ;
        sinus= Math.sin((j + (lasti * sinespeed)) / sinedensity) * sineamplitude;
        line.graphics.lineTo(j,c.coords[linenumber][j]-sinus-(brightness*extrusion));

    }
    /*
    Close the path that the line is drawing
    */

    lasti -=  sinedirection;
    line.graphics.lineTo(500,1100);
    line.graphics.lineTo(-1,1100);
    line.graphics.endFill();
    lines.push(line);
    holder.addChild(line);

}






/*
Smoothness of displacement map
*/
var blur:BlurFilter = new BlurFilter();

function setblur():void {
    trace("sb");
    blur.blurX = smoothness;
    blur.blurY = smoothness;
    blur.quality = BitmapFilterQuality.HIGH;
    mc.word.filters = [blur];
}


/*
Functions to retrieve brightness of displacement map
*/

function getcolor(xx,yy):uint {
    var pixelValue:uint = bmd.getPixel(xx,yy);
    return pixelValue;
}


function getbrightness(colour):Number {
    var R:Number = 0;
    var G:Number = 0;
    var B:Number = 0;
    R +=  colour >> 16 & 0xFF;
    G +=  colour >> 8 & 0xFF;
    B +=  colour & 0xFF;
    var br = Math.sqrt(R * R * .241 + G * G * .691 + B * B * .068);
    return br;
}

/*
Makes the displacment map stringer then weaker
*/

function grow():void {
    TweenLite.to(this,inhale,{extrusion:extrusiontarget,onComplete:shrink,delay:beforeInhale});
}

function shrink():void {
    TweenLite.to(this,exhale,{extrusion:0,onComplete:grow,delay:beforeExhale});
}

function mouseDownHandler(e){
    grow();
    addEventListener(Event.ENTER_FRAME,myEnterFrame);
}


stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);

//Draws lines
initdraw();
setblur()
4

2 回答 2

0

一方面,您应该使用 drawPath,这样您就可以减少所需的函数调用量。由于您的点是静态的,因此它类似于您在 gpu 上构建缓冲区的方式。

  • 函数调用是绘图命令将是这里最昂贵的东西,所以你应该尝试内联任何实用函数。
  • 展平位图中的数据,因此它是一个更快的数组访问调用 [] 而不是 getpixel(etc)

什么是:

line.graphics.lineTo(500,1100);
line.graphics.lineTo(-1,1100);

?????????对于路径绘图仪来说,这是一项相当多的工作。如果您只是显示线条,为什么要使用填充?填充是不小的cpu工作量。

于 2012-07-06T15:52:50.227 回答
0

到目前为止,在 RAM 使用方面的性能只有很小的改进,但除了调整分辨率以显着减少循环中的处理之外,还没有提出任何建议,但我会继续关注它。还更新了数组以使用向量。

/*
Click anywhere on the stage to start anim
*/
import flash.display.BitmapData;
import com.greensock.*;
import flash.display.Shape;
import uk.co.soulwire.*;
import net.hires.debug.Stats;
import uk.co.soulwire.gui.SimpleGUI;
import flash.display.MovieClip;
import flash.events.Event;
/*
How many pixels do we draw in each loop?
*/
var canvaswidth:Number = 999;
var linecount:Number=35;
var res=4;//Skip res-1 pixels per loop to lower the resolution

/*
Performance analyser and variable sliders
*/
var stats:Stats=new Stats();
stats.x = 1200
stats.y = 0;
addChild(stats);

var gui:SimpleGUI = new SimpleGUI(this,"Parameters","h",1000,0);
gui.show();

/*
Stores the base coordinates
*/
var c:Coordinates=new Coordinates();

/*
Holds the lines
*/
var holder:MovieClip=new MovieClip();
addChild(holder)

/*
Generic variables
*/
var lines:Vector.<Shape> = Vector.<Shape>([]);
var bmd:BitmapData=new BitmapData(999,400);
var brightness = 0;
var sinus=0;

/**
*
Parameters used to control the animaitons and extrusions
*
**/

/*
Displacement map properties
*/
var extrusion:Number = 1;
var extrusiontarget:Number = .1;
var tolerance:Number = 1;
var smoothness = 10;

//Sinewave 
var lasti = 0;
var sinedirection = -1;
var sineamplitude:Number = 3;
var sinespeed = 0.5;
var sinedensity = 100;

/*
Breathing animation
*/
var inhale:Number = 2;
var exhale:Number = 2;
var beforeInhale:Number = 0;
var beforeExhale:Number = 0;

var blur:BlurFilter = new BlurFilter();
/*
Add sliders to control the above variables
*/
gui.addGroup("Pixels being drawn")
gui.addSlider("linecount", 5, 35);
gui.addSlider("canvaswidth",30,999);
gui.addSlider("res",1,10);

gui.addGroup("Displacement Map")
gui.addSlider("smoothness", 1, 100,{callback:setblur});
gui.addSlider("tolerance", 1, 255);
gui.addSlider("extrusiontarget", 0.1, 3);

gui.addGroup("Sinwave")
gui.addSlider("sinedirection",-1,1);
gui.addSlider("sineamplitude",0,30);
gui.addSlider("sinespeed",0,10);

gui.addGroup("Breathing")
gui.addSlider("beforeInhale",0,5);
gui.addSlider("inhale",0,5);
gui.addSlider("beforeExhale",0,5);
gui.addSlider("exhale",0,5);

/**
Clear the lines
Clear the bmp data
Redraw the bitmpa data
Redraw the lines
**/
function myEnterFrame(event:Event=null):void {
    /*
    Clear previous lines and displacement map data
    Lance drawing of 35 lines
    */
    bmd.draw(mc);
    for (var i:int=0; i<linecount; i++)
        drawlines(i);
}
function createLines()
{
    for (var i:int=0; i<linecount; i++)
    {
        var line:Shape = new Shape();
        lines.push(line);
        holder.addChild(line);
    }
}
/**
plot the cordinates of each point absed on sin data and bmp brihgtness
**/
function drawlines(linenumber):void
{
    /*
    Start to draw a line
    */
    var line:Shape = lines[linenumber];
    line.graphics.clear();
    line.graphics.beginFill(0x000000);
    line.graphics.moveTo(-1,0);
    /*
    Increase length by 1 * times resolution and 
    Adjust y values based on displacement map and sinewave data
    */
    for (var j:uint=0; j<canvaswidth; j+=res)
    {
        var currentNum:int = c.coords[linenumber][j];
        if (currentNum == 1100)
            line.graphics.lineStyle(1, 0x000000);
        else
            line.graphics.lineStyle(1, 0xFFFFFF);
        brightness = Math.ceil(getbrightness(bmd.getPixel(j,currentNum))/tolerance);
        sinus = Math.sin((j + (lasti * sinespeed)) / sinedensity) * sineamplitude;
        line.graphics.lineTo(j,currentNum-sinus-(brightness*extrusion));
    }

    /*
    Close the path that the line is drawing
    */
    lasti -=  sinedirection;
    line.graphics.lineTo(500,1100);
    line.graphics.lineTo(-1,1100);
    line.graphics.endFill();
}


var colourDict:Object = {};
function getbrightness(colour):Number
{
    if(colourDict[colour])
        return colourDict[colour];

    var R:Number = 0;
    var G:Number = 0;
    var B:Number = 0;
    R +=  colour >> 16 & 0xFF;
    G +=  colour >> 8 & 0xFF;
    B +=  colour & 0xFF;
    var br = Math.sqrt(R * R * .241 + G * G * .691 + B * B * .068);
    colourDict[colour] = br;
    return br;
}

/*
Makes the displacment map stringer then weaker
*/
function grow():void
{
    TweenLite.to(this,inhale,{extrusion:extrusiontarget,onComplete:shrink,delay:beforeInhale});
}

function shrink():void
{
    TweenLite.to(this,exhale,{extrusion:0,onComplete:grow,delay:beforeExhale});
}

function mouseDownHandler(e)
{
    grow();
    addEventListener(Event.ENTER_FRAME,myEnterFrame);
}

/*
Smoothness of displacement map
*/
function setblur():void
{
    trace("sb");
    blur.blurX = smoothness;
    blur.blurY = smoothness;
    blur.quality = BitmapFilterQuality.HIGH;
    mc.word.filters = [blur];
}

//Draws lines
createLines();
myEnterFrame();
setblur();
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
于 2012-07-06T05:43:53.973 回答