PaperVision3Dでエフェクトと鏡面反射をやってみました。

日曜プログラミングってことでPaperVision3Dでエフェクトと鏡面反射をやってみました。
こんな感じ
エフェクトサンプル(重いよっ)
http://moeten.info/flex/20080920_pv3d2Test/bin-release/main.html

鏡面反射サンプル
http://moeten.info/flex/20080920_pv3d2Test/bin-release/main2.html

ソースはこちら
関係ないけど今日svn更新したらこんなファイルが

テンション上がるわぁ
参考リンク

フィルター main.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" backgroundAlpha="1" backgroundColor="0x000000"
    layout="absolute" creationComplete="init()" viewSourceURL="srcview/index.html">
<mx:Script>
<![CDATA[
import org.papervision3d.core.effects.utils.BitmapDrawCommand;
import org.papervision3d.core.effects.BitmapColorEffect;
import org.papervision3d.view.layer.BitmapEffectLayer;
import org.papervision3d.core.effects.BitmapLayerEffect;
import org.papervision3d.core.effects.utils.BitmapClearMode;
import org.papervision3d.cameras.Camera3D;
import org.papervision3d.render.BasicRenderEngine;
import org.papervision3d.scenes.Scene3D;
import org.papervision3d.view.Viewport3D;
import org.papervision3d.materials.BitmapColorMaterial;
import org.papervision3d.materials.WireframeMaterial;
import org.papervision3d.materials.utils.MaterialsList;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.objects.primitives.Cube;
import org.papervision3d.objects.primitives.Sphere;
import org.papervision3d.core.material.TriangleMaterial;
private var scene    : Scene3D;
private var viewport : Viewport3D;
private var renderer : BasicRenderEngine;
private var sphere   : Sphere;
private var camera   : Camera3D;
private var cameraTarget : DisplayObject3D;
//初期化
private function init():void{
    setupScene();
//    setupSphere();
    setupListeners();
    setupCamera();
    setupBlokjes();
}
//シーンの作成
private var bfx:BitmapEffectLayer;
private function setupScene():void{
    //ビューポートの作成
    viewport = new Viewport3D( myImage.width , myImage.height , true , false , true , true );
    myImage.addChildAt(viewport , 0);
    renderer = new BasicRenderEngine();
    scene    = new Scene3D();
    //エフェクトレイヤーの作成
    bfx = new BitmapEffectLayer( viewport, myImage.width, myImage.height , true, 0, BitmapClearMode.CLEAR_PRE);
    //bfx.addEffect( new BitmapLayerEffect( new BlurFilter(10,10,4) ) );
    bfx.addEffect( new BitmapColorEffect( .95, 1.0, .98, 0.98 ) );
    var ct:ColorTransform = new ColorTransform(0, .5, 1, 0.18); // BLUE
    var drawCommand:BitmapDrawCommand = new BitmapDrawCommand(null, ct, BlendMode.ADD );
    bfx.drawCommand = drawCommand;
    bfx.drawLayer.filters = [  new GlowFilter(0xFFFFFF,.5, 0, 50, 10)];
    bfx.drawLayer.blendMode = BlendMode.MULTIPLY;
    bfx.clippingPoint = new Point(9, -20);
    viewport.containerSprite.addLayer(bfx);
}
//カメラ設定
private function setupCamera():void{
    cameraTarget = new DisplayObject3D();
    camera = new Camera3D();
    camera.z = - 1000;
    camera.y = 10;
}
//イベントリスナー設定
private function setupListeners():void{
    addEventListener(Event.ENTER_FRAME, onRenderTick);
    addEventListener(Event.RESIZE, onResize);
}
//オブジェクト(スフィア)作成
private function setupSphere():void{
    var m : WireframeMaterial = new WireframeMaterial(0xff0000);
    sphere = new Sphere(m , 200 , 8 , 6);
    //シーンにオブジェクトを追加
    scene.addChild(sphere);
}
//オブジェクト(キューブ)作成
private var cubeArr:Array = new Array();
private function setupBlokjes() : void {
    var size:Number    = 500;
    var spacing:Number = 70;
    var xCubes:Number  = 1;
    var yCubes:Number  = 1;
    var cube : Cube;
    var cWidth:Number  = ((xCubes-1) * size) + ((xCubes-1)  * spacing);
    var xOffest:Number = cWidth / 2;
    var cHeight:Number = ((yCubes-1) * size) + ((yCubes-1)  * spacing);
    var yOffest:Number = cHeight / 2;
    for(var y:int = 0 ; y < yCubes ; y++){
        for(var x:int = 0 ; x < xCubes ; x++){
            cube = new Cube( getBlokjeMaterialList() , size , size, size );
            cube.x = (x * size) + (x  * (spacing - 1)) - xOffest;
            cube.y = (y * size) + (y  * (spacing - 1)) - yOffest;
            //シーンにオブジェクトを追加
            scene.addChild(cube);
            cubeArr.push( cube );
            //エフェクト追加
            bfx.addDisplayObject3D(cube);
        }
    }
}
//マテリアルカラーをランダム作成
private function getBlokjeMaterialList() : MaterialsList{
    var ml : MaterialsList = new MaterialsList();
    var front  : TriangleMaterial = new BitmapColorMaterial(Math.random()* 0xffffff);
    var back   : TriangleMaterial = new BitmapColorMaterial(Math.random()* 0xffffff);
    var left   : TriangleMaterial = new BitmapColorMaterial(Math.random()* 0xffffff);
    var right  : TriangleMaterial = new BitmapColorMaterial(Math.random()* 0xffffff);
    var top    : TriangleMaterial = new BitmapColorMaterial(Math.random()* 0xffffff);
    var bottom : TriangleMaterial = new BitmapColorMaterial(Math.random()* 0xffffff);
    ml.addMaterial(front  , "front");
    ml.addMaterial(back   , "back");
    ml.addMaterial(left   , "left");
    ml.addMaterial(right  , "right");
    ml.addMaterial(top    , "top");
    ml.addMaterial(bottom , "bottom");
    return ml;
}
//レンダリング+マウス操作
protected function onRenderTick(e:Event):void {
    var reach:Number = 0.01;
    var ease:Number = 0.1;
    var cameraDistance:Number = 1200;
    camera.x += (Math.sin(mouseX * reach) *   cameraDistance - camera.x) * ease;
    camera.z += (Math.cos(mouseX * reach) * - cameraDistance - camera.z) * ease;
    camera.y += (Math.sin(mouseY * reach) *   cameraDistance - camera.y) * ease;
    camera.lookAt(cameraTarget);
    for( var i:int = 0 ; i < cubeArr.length ; i ++ ){
        cubeArr[i].rotationY += 1;
    }
    //レンダリング
    renderer.renderScene(scene, camera, viewport);
}
//リサイズイベント
private function onResize(e : Event) : void {
}
]]>
</mx:Script>
<mx:Image id="myImage" width="100%" height="100%" />
</mx:Application>

反射 main2.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    backgroundAlpha="1" backgroundColor="0x000000"
    layout="absolute" creationComplete="init()">
<mx:Script>
<![CDATA[
import org.papervision3d.materials.BitmapColorMaterial;
import org.papervision3d.materials.WireframeMaterial;
import org.papervision3d.materials.utils.MaterialsList;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.objects.primitives.Cube;
import org.papervision3d.objects.primitives.Sphere;
import org.papervision3d.core.material.TriangleMaterial;
import org.papervision3d.core.effects.view.ReflectionView;
private var sphere   : Sphere;
private var cameraTarget : DisplayObject3D;
//初期化
private function init():void{
    setupScene();
    setupSphere();
    setupListeners();
    setupCamera();
    setupBlokjes();
}
//シーンの作成+リフレクション
private var r:ReflectionView;
private function setupScene():void{
    r = new ReflectionView( myImage.width , myImage.height , true , false );
    //リフレクションを置く場所
    r.surfaceHeight = -600;
    //ぼかし具合
    r.viewportReflection.filters = [new BlurFilter(8, 8, 1)];
    //色の変更
    //setReflectionColor(0, 50, 0, 0, 50, 0);
    myImage.addChildAt( r , 0 );
}
//カメラ設定
private function setupCamera():void{
    cameraTarget = new DisplayObject3D(); //なんかないと怒られる
    r.camera.z   = - 800;
    r.camera.y   = 10;
}
//イベントリスナー設定
private function setupListeners():void{
    addEventListener(Event.ENTER_FRAME, onRenderTick);
    addEventListener(Event.RESIZE, onResize);
}
//オブジェ(スフィア)の作成
private function setupSphere():void{
    var m : WireframeMaterial = new WireframeMaterial(0xff0000);
    sphere = new Sphere(m , 200 , 8 , 6);
    sphere.x = 800;
    sphere.y = 0;
    //シーンにオブジェクトを追加
    r.scene.addChild(sphere);
}
//オブジェ(キューブ)の作成
private var cubeArr:Array = new Array();
private function setupBlokjes() : void {
    var size:Number    = 400;
    var spacing:Number = 150;
    var xCubes:Number  = 2;
    var yCubes:Number  = 1;
    var cube : Cube;
    var cWidth:Number  = ((xCubes-1) * size) + ((xCubes-1)  * spacing);
    var xOffest:Number = cWidth / 2;
    var cHeight:Number = ((yCubes-1) * size) + ((yCubes-1)  * spacing);
    var yOffest:Number = cHeight / 2;
    for(var y:int = 0 ; y < yCubes ; y++){
        for(var x:int = 0 ; x < xCubes ; x++){
            cube = new Cube( getBlokjeMaterialList() , size , size, size );
            cube.x = (x * size) + (x  * (spacing - 1)) - xOffest;
            cube.y = (y * size) + (y  * (spacing - 1)) - yOffest;
            cubeArr.push( cube );
            //シーンにオブジェクトを追加
            r.scene.addChild(cube);
        }
    }
}
//マテリアルカラーをランダム作成
private function getBlokjeMaterialList() : MaterialsList{
    var ml : MaterialsList = new MaterialsList();
    var front  : TriangleMaterial = new BitmapColorMaterial(Math.random()* 0xffffff);
    var back   : TriangleMaterial = new BitmapColorMaterial(Math.random()* 0xffffff);
    var left   : TriangleMaterial = new BitmapColorMaterial(Math.random()* 0xffffff);
    var right  : TriangleMaterial = new BitmapColorMaterial(Math.random()* 0xffffff);
    var top    : TriangleMaterial = new BitmapColorMaterial(Math.random()* 0xffffff);
    var bottom : TriangleMaterial = new BitmapColorMaterial(Math.random()* 0xffffff);
    ml.addMaterial(front  , "front");
    ml.addMaterial(back   , "back");
    ml.addMaterial(left   , "left");
    ml.addMaterial(right  , "right");
    ml.addMaterial(top    , "top");
    ml.addMaterial(bottom , "bottom");
    return ml;
}
//レンダリング+マウス操作
protected function onRenderTick(e:Event):void {
    var reach:Number = 0.01;
    var ease:Number = 0.1;
    var cameraDistance:Number = 1200;
    //カメラワーク
    r.camera.x += (Math.sin(mouseX * reach) *   cameraDistance - r.camera.x) * ease;
    r.camera.z += (Math.cos(mouseX * reach) * - cameraDistance - r.camera.z) * ease;
    r.camera.y += (Math.sin(mouseY * reach) *   cameraDistance - r.camera.y) * ease;
    r.camera.lookAt(cameraTarget);
    //無駄に回転しておく
    sphere.rotationY += 1;
    for( var i:int = 0 ; i < cubeArr.length ; i ++ ){
        cubeArr[i].rotationY += 1;
    }
    //レンダリング
    //renderer.renderScene(scene, camera, viewport);
    r.singleRender();
}
//リサイズイベント
private function onResize(e : Event) : void {
}
]]>
</mx:Script>
<mx:Image id="myImage" width="100%" height="100%" />
</mx:Application>