立体投影万花筒 — Stereographic Projection Kaleidoscope

万花筒 everyinch 2127℃ 0评论

点击图像打开实例文件:

PBK文件源码:

<languageVersion: 1.0;>
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 ) );
   }
} 

AS类文件:

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];
		}
	}
}


转载请注明:陈童的博客 » 立体投影万花筒 — Stereographic Projection Kaleidoscope

喜欢 (0)
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

无觅相关文章插件,快速提升流量