陈童的博客's Archivers

From everyinch on 2013-05-01 16:47:01

放射状万花筒

点击图像打开实例文件:
<img class="aligncenter size-medium wp-image-937" title="kal6" alt="" src="http://www.everyinch.net/wp-content/uploads/2013/05/kal6-300x212.jpg" width="300" height="212" />
PBK文件源码:
[code lang="as3"]

# define PI 3.141592
# define DOUPLEPI 6.28318531

kernel RadialCaleidoscope
< namespace : "RadialCaleidoscope";
vendor : "ChenTong";
version : 1;
description : "Caleidoscope -effect for radial reflection";
>
{
parameter float angle
// 类似于 2*PI/n, 整数 n >3
<
minValue:float(0.0001);
maxValue:float(PI);
defaultValue:float(0.628318531);
>;
parameter float direction
<
minValue:float(0.0);
maxValue:float(DOUPLEPI);
defaultValue:float(0.0001);
>;
parameter float2 basepoint
// 或 中心点
<
minValue:float2(0.01);
maxValue:float2(496.01,496.01);
defaultValue:float2(150.01,150.01);
>;

input image4 src;
output pixel4 dst;

void
evaluatePixel()
{
// 相对于中心点(基点)的位置
float2 po = outCoord() - basepoint;
// 极坐标的角度和半径
// 加 4*PI 保持角度为正角度
float theta = atan(po.y,po.x)-direction +2.0*DOUPLEPI;
float radius = sqrt(po.x*po.x+po.y*po.y);

// 求余操作
float newAngle = mod(theta,angle);
float section = floor(theta/angle);

// 镜像奇数位置
if (mod(section,2.0)>0.5) newAngle = angle-newAngle;

// 将极坐标转换为平面直角坐标
dst = sampleLinear(src,basepoint+float2(radius *cos(newAngle += direction), radius *sin(newAngle)));
}
}
[/code]
AS类文件:
[code lang="as3"]
package{
import flash.display.Bitmap;
import flash.display.GradientType;
import flash.display.Shader;
import flash.display.Shape;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.filters.ShaderFilter;
import flash.geom.Matrix;

[SWF(width="800",height="600",frameRate="10",backgroundColor="0x000000")]
public class RadialKaleidoscope extends Sprite{
[Embed(source="pbj/RadialCaleidoscope.pbj",mimeType="application/octet-stream")]
private var ShaderClass:Class;

[Embed(source="assets/Flower6.jpg")]
private var Flower:Class;

private var container:Sprite;
private var shader:Shader;
private var filter:ShaderFilter;

private var image:Bitmap;
private var maskShape:Shape;
private var gradientShape:Shape;
private var radius:Number = 250;

private var angle:Number = 0;
private var value:Number = 0;

public function RadialKaleidoscope(){
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;

container = new Sprite();
addChild(container);

shader = new Shader(new ShaderClass());
shader.data.basepoint.value = [256.0,192.0];
shader.data.angle.value = [0.2168];
filter = new ShaderFilter(shader);
image = new Flower();
container.x = (800-image.width)/2;
container.y = (600-image.height)/2;
container.addChild(image);
image.filters = [filter];

maskShape = new Shape();
maskShape.graphics.beginFill(0xffffff,1);
maskShape.graphics.drawCircle(0,0,radius);
maskShape.graphics.endFill();
addChild(maskShape);
maskShape.x = 400;
maskShape.y = 300;
container.mask = maskShape;

gradientShape = new Shape();
var matrix:Matrix = new Matrix();
var colors:Array = [0x000000,0x000000];
var alphas:Array = [0,1];
var ratios:Array = [150,255];
matrix.createGradientBox(radius*2,radius*2,0,-radius,-radius);
gradientShape.graphics.lineStyle();
gradientShape.graphics.beginGradientFill(GradientType.RADIAL,colors,alphas,ratios,matrix);
gradientShape.graphics.drawCircle(0,0,radius);
gradientShape.graphics.endFill();
addChild(gradientShape);
gradientShape.x = 400;
gradientShape.y = 300;

addEventListener(Event.ENTER_FRAME,onEnterframe);
}

private function onEnterframe(e:Event):void{
value = Math.cos(angle+=0.02)*Math.PI+Math.PI*2;
shader.data.direction.value = [value];
image.filters = [filter];
}
}
}
[/code]

查看完整版本: 放射状万花筒

Tags: 万花筒


©陈童的博客