陈童的博客's Archivers

From everyinch on 2013-05-01 16:59:51

立体投影万花筒 -- Stereographic Projection Kaleidoscope

点击图像打开实例文件:
<img class="aligncenter size-medium wp-image-937" title="kal7" alt="" src="http://www.everyinch.net/wp-content/uploads/2013/05/kal7-300x212.jpg" width="300" height="212" />
PBK文件源码:
[code lang="as3"]
kernel stereographics
<
namespace : "advanced stereographic projection";
vendor : "Chentong";
version : 1;
description : "enhanced by warp(s), turn(s), scale(s) & zoom(s)";

>
{

# define PI 3.141592
# define DOUPLEPI 6.28318531

parameter float2 center
<
minValue: float2( 0.0, 0.0 );
maxValue: float2( 2000.0, 2000.0 );
defaultValue: float2( 180.0, 180.0 );
description: "set input image center";
>;


parameter float2 xy_replication
<
minValue: float2(1.0, 1.0);
maxValue: float2(181.0, 181.0);
defaultValue: float2(28.0, 28.0);
description: "xy.replicate map";
>;

parameter float radius
<
minValue: float(0.0);
maxValue: float(100.0);
defaultValue: float(72.0);
description: "set radius";
>;

parameter float scale
<
minValue: float(0.1);
maxValue: float(4.0);
defaultValue: float(2.3);
description: "set aspect ratio";
>;

parameter float zoom
<
minValue: float(0.10);
maxValue: float(5.00);
defaultValue: float(1.00);
description: "set zoom";
>;

parameter float turn
<
minValue: float(0.00);
maxValue: float(1.00);
defaultValue: float(1.00);
description: "set rotation";
>;

parameter float warp
<
minValue: float(0.1);
maxValue: float(PI);
defaultValue: float(2.3);
description: "set warp";
>;
input image4 src;
output pixel4 dst;

void evaluatePixel()
{
// 相对于 xy 中心点的位置
float2 pos = outCoord()-center;
// 平面直角坐标 -- 极坐标
// distance (r)
float r = sqrt( pos.x * pos.x + pos.y * pos.y );
// angle (a)
float theta = atan( pos.y / pos.x );

// 光谱半径
float spectral = scale * r;

// 衰减
float damp = -sin( warp ) * 1.0 + cos( warp );

float rad = xy_replication.y * zoom;
float maxpi = 2.0 * atan( scale );

float edgewise = 2.0 * atan( spectral / rad );
float meridian = theta + DOUPLEPI * turn;

// 计算新的 xy 位置
float ny = ( xy_replication.y ) * ( 2.0 * edgewise / maxpi ) - ( xy_replication.y );
float nx = ( xy_replication.x - 1.0 )* meridian / PI - ( xy_replication.x );

// 极坐标 -- 平面直角坐标
float vx = radius * cos( nx );
float vy = radius * sin( ny );

dst = sampleLinear(src, center + float2( vx, vy * damp ) );
}
} [/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 StereographicProjection extends Sprite{
[Embed(source="pbj/asp.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;

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

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

shader = new Shader(new ShaderClass());
shader.data.center.value = [256.0,192.0];
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{
var pos:Number = Math.cos(angle+=0.1)*40+50;
shader.data.radius.value = [pos];
//var turn:Number = Math.cos(angle+=0.01);
//shader.data.turn.value = [turn];
//var scale:Number = Math.cos(angle+=0.05)*2+2;
//shader.data.scale.value = [scale];
image.filters = [filter];
}
}
}[/code]

查看完整版本: 立体投影万花筒 -- Stereographic Projection Kaleidoscope

Tags: 立体投影万花筒


©陈童的博客