[PV3D] Refrection Cube - Gradation Version
CubeでもPlaneでも何でもオブジェクト単位で反射を適用します。
通常のReflectionViewだと均質な反射となりますが、この手法だと下側にいくほど、透過されている表現になります。
/**
* 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();
}
}
}