赤青メガネで物体をさらに立体的に

PaperVision3Dで赤青メガネをつけて見ると物体が立体的に見えるっていうのをやってみました。

サンプルはこちら。
http://moeten.info/flex/20081115_pv3dGlass/bin-release/main.html

動作ムービーはこちら

簡単な説明
概念図

カメラを二つ用意してそれぞれでレンダリング。
この際、カメラの位置を微妙にずらしておく。
そして、レンダリングしたものにそれぞれに赤・青のレイヤーをスクリーンモードで重ねる。
あとは一枚に合成(multiply)すればOK
参考リンク

ソースはこちら

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    layout="absolute" backgroundColor="0xffffff"
    creationComplete="init3D()">
<mx:Script>
<![CDATA[
/* **********************************
            PV3D
********************************** */
import org.papervision3d.cameras.Camera3D;
import org.papervision3d.render.BasicRenderEngine;
import org.papervision3d.render.QuadrantRenderEngine;
import org.papervision3d.scenes.Scene3D;
import org.papervision3d.view.Viewport3D;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.objects.primitives.Cube;
import org.papervision3d.objects.primitives.Sphere;
import org.papervision3d.materials.utils.MaterialsList;
import org.papervision3d.materials.BitmapFileMaterial;
import org.libspark.pv3d.Metasequoia;
private var scene    : Scene3D;
private var viewport0: Viewport3D;
private var viewport1: Viewport3D;
private var renderer : BasicRenderEngine;
private var camera0  : Camera3D;
private var camera1  : Camera3D;
private var cameraTarget : DisplayObject3D;
private var metaseq:Metasequoia;
//初期化
private function init3D():void{
    setupScene();
    setupCamera();
    setupMetaseq();
    setupObject();
    setupListeners();
}
//シーンの作成
private function setupScene():void{
    viewport0 = new Viewport3D( myUI0.width , myUI0.height , false , false , true , true );
    myUI0.addChildAt(viewport0 , 0);
    viewport1 = new Viewport3D( myUI1.width , myUI1.height , false , false , true , true );
    myUI1.addChildAt(viewport1 , 0);
    renderer = new BasicRenderEngine();
    scene    = new Scene3D();
}
//カメラ設定
private function setupCamera():void{
    cameraTarget = new DisplayObject3D();
    camera0 = new Camera3D();
    camera1 = new Camera3D();
}
//イベントリスナー設定
private function setupListeners():void{
    addEventListener( Event.ENTER_FRAME, onRenderTick );
    addEventListener(Event.RESIZE, onResize);
}
//メタセコイア設置
private function setupMetaseq():void{
    metaseq = new Metasequoia();
    metaseq.load( "miku01.mqo" );
    metaseq.x = 0;
    metaseq.y = 0;
    metaseq.z = 0;
    scene.addChild( metaseq, "metaseq" );
}
private var sp:Sphere;
private var cube:Cube;
private function setupObject():void{
    sp = new Sphere( new BitmapFileMaterial("worldmap.gif"),30 );
    sp.x = 100;
    sp.y = 30;
    sp.z = 100;
    scene.addChild( sp );
    var mat:MaterialsList = new MaterialsList({all:new BitmapFileMaterial("cube.png")});
    cube = new Cube( mat , 40 , 40, 40 );
    cube.x = -100;
    cube.y = 50;
    cube.z = -100;
    scene.addChild( cube );
}
//レンダリング+マウス操作
private var a:Number = 0;
protected function onRenderTick(e:Event):void {
    var distance:int = 300;
    camera0.target = metaseq;
    camera0.z = Math.cos(a)*distance;
    camera0.x = Math.sin(a)*distance;
    camera1.target = metaseq;
    camera1.z = Math.cos(a+0.04)*distance;
    camera1.x = Math.sin(a+0.04)*distance;
    a+=0.01;
    sp.yaw(5);
    cube.yaw(5);
    cube.pitch(5);
    renderer.renderScene(scene, camera0, viewport0);
    renderer.renderScene(scene, camera1, viewport1);
    setImage();
}
//メガネで見る用
private function setImage():void{
    var bd0:BitmapData = new BitmapData(320 , 240 );
    var bd1:BitmapData = new BitmapData(320 , 240 );
    bd0.draw( myUI0 );
    bd0.draw( myImageCover0 , null , null , "screen" );
    myImage0.source = new Bitmap( bd0 );
    bd1.draw( myUI1 );
    bd1.draw( myImageCover1 , null , null , "screen" );
    myImage1.source = new Bitmap( bd1 );
    var bd3:BitmapData = new BitmapData( 320 , 240 );
    bd3.draw( myImage0 );
    bd3.draw( myImage1 ,null,null,"multiply");
    myImage3.source = new Bitmap( bd3 );
}
//リサイズイベント
private function onResize(e : Event) : void {
}
]]>
</mx:Script>
<mx:VBox>
    <mx:Label text="3D出力画像"/>
    <mx:Image id="myImage3" width="320" height="240"/>
    <mx:Label text="オリジナル"/>
    <mx:HBox>
        <mx:UIComponent id="myUI0" width="320" height="240"/>
        <mx:UIComponent id="myUI1" width="320" height="240"/>
    </mx:HBox>
    <mx:Label text="色"/>
    <mx:HBox>
        <mx:Image id="myImageCover0" width="320" height="240" source="red.jpg"/>
        <mx:Image id="myImageCover1" width="320" height="240" source="blue.jpg"/>
    </mx:HBox>
    <mx:Label text="色適応"/>
    <mx:HBox>
        <mx:Image id="myImage0" width="320" height="240"/>
        <mx:Image id="myImage1" width="320" height="240"/>
    </mx:HBox>
</mx:VBox>
</mx:Application>