In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

[PV3D] Refrection Cube - Gradation Version

CubeでもPlaneでも何でもオブジェクト単位で反射を適用します。

通常のReflectionViewだと均質な反射となりますが、この手法だと下側にいくほど、透過されている表現になります。
Get Adobe Flash player
by clockmaker 23 Dec 2010
/**
 * Copyright clockmaker ( http://wonderfl.net/user/clockmaker )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/zvod
 */

// forked from mash's papervision3d simple example (cube)
/**
 * ReflectionViewを使った反射バージョン
 */
package {
    import flash.display.*;
    import flash.events.*;
    import flash.filters.*;
    import flash.geom.*;
    import flash.utils.*;
    import org.papervision3d.core.effects.view.ReflectionView;
    import org.papervision3d.lights.*;
    import org.papervision3d.materials.shadematerials.*;
    import org.papervision3d.materials.utils.MaterialsList;
    import org.papervision3d.objects.primitives.*;
    import org.papervision3d.view.layer.ViewportLayer;
    
    [SWF(frameRate="60")]
    /**
     * @author yasu
     * @since 2010/12/23
     */
    public class Main extends ReflectionView {
        private static const MAX_NUM:Number = 2;
        
        /**
         * 新しい Main インスタンスを作成します。
         */
        public function Main() {
            objects = [];
            for (var i:int = 0; i < MAX_NUM; i++) {
                // 立方体を作成します
                var cube:Cube = Cube(scene.addChild(new Cube(new MaterialsList(
                    {
                        all: new FlatShadeMaterial(new PointLight3D(), 0x2288CC, 0x004466)
                    }))));
                cube.x = 1000 * i - 1000 * MAX_NUM / 4;
                // ビューポートレイヤー
                var cubeLayer:ViewportLayer = cube.createViewportLayer(viewportReflection);
                // マスク
                var maskSp:Shape = new Shape();
                viewportReflection.containerSprite.addChild(maskSp);
                // 配列に格納
                objects[ i ] = { obj: cube, layer: cubeLayer, mask: maskSp };
            }
            // 反射を設定します
            surfaceHeight = -600
            viewportReflection.alpha = .6;
            viewportReflection.filters = [ new BlurFilter(8, 8, 1)]
            // アニメーションを設定してます
            addEventListener(Event.ENTER_FRAME, enterFrameHandler);
        }
        private var objects:Array;
        
        protected function enterFrameHandler(event:Event):void {
            camera.y = 500 + 800 * Math.sin(getTimer() / 1000);
            singleRender();
            for (var i:int = 0; i < objects.length; i++) {
                objects[ i ].obj.yaw(2);
                updateMask(objects[ i ].layer, objects[ i ].mask);
            }
        }
        
        /**
         * リフレクション部分にグラデーション反射を適用します。
         * @param layer
         * @param shape
         */
        private function updateMask(layer:ViewportLayer, shape:Shape):void {
            layer.mask = null;
            // 透明領域のトリミング
            var rectangle:Rectangle = layer.getRect(viewportReflection.containerSprite);
            // マスクの作成 
            shape.graphics.clear();
            shape.x = rectangle.x;
            shape.y = rectangle.y;
            createGradation(shape.graphics, rectangle.width, rectangle.height);
            // グラデーションの適用
            shape.cacheAsBitmap = true;
            layer.cacheAsBitmap = true;
            layer.mask = shape;
        }
        
        /**
         * 線形のグラデーションを作成します。
         * @param graphics
         * @param w
         * @param h
         */
        private function createGradation(graphics:Graphics, w:int, h:int):void {
            //線状のグラデーション
            var type:String = GradientType.LINEAR;
            var colors:Array = [ 0x0, 0x0 ];
            var alphas:Array = [ 0, 1 ];
            var ratios:Array = [ 0, 255 ];
            var mtrx:Matrix = new Matrix();
            mtrx.createGradientBox(w, h, 0, 0, 0);
            //グラデーションを45度回転する
            mtrx.rotate(Math.PI / 2);
            var spread:String = SpreadMethod.PAD;
            var interpolation:String = InterpolationMethod.RGB;
            var focalPointRatio:Number = 0;
            //グラデーションで塗る
            graphics.beginGradientFill(type, colors, alphas, ratios, mtrx, spread, interpolation, focalPointRatio);
            //四角形を描く
            graphics.drawRect(0, 0, w, h);
            graphics.endFill();
        }
    }
}