ホーム > Flash (ActionScript) > [Papervision3D #1] テクスチャとシェーディングの同時適用法

[Papervision3D #1] テクスチャとシェーディングの同時適用法

Papervision3D で少し遊んでみました。本来ならテクスチャとシェーディングは同時適用できない(どちらもマテリアルのため)ですが、BlendMode を活用して同時適用してみました。

1/27 追記:
嘘でした、ごめんなさい。ShadedMaterial で実現できるようです。今日も迷子さんで詳しく解説されていますので、そちらをご参照ください。あー、自分嘘ばっか。もう知ったかぶりはしません・・・。

デモはこちら

シェーディングを施すと一気に質感が良くなりますね。Papervision3D のシェーディングは多分擬似だと思うのですが(擬似じゃない?自分の頭じゃ分かんない)、それにしても良く出来てるなぁ。以下はドキュメントクラスのコード。モデルデータとテクスチャは各自ゲットしてください。あと、GreatWhite (3.12.07) でパブリッシュしています。

コードは下記の通り。

package
{
    import flash.display.*;
    import flash.events.*;
    import org.ascollada.utils.FPS;
    import org.papervision3d.cameras.Camera3D;
    import org.papervision3d.core.proto.MaterialObject3D;
    import org.papervision3d.lights.PointLight3D;
    import org.papervision3d.materials.BitmapFileMaterial;
    import org.papervision3d.materials.ColorMaterial;
    import org.papervision3d.materials.shadematerials.*;
    import org.papervision3d.objects.parsers.MD2;
    import org.papervision3d.objects.primitives.Plane;
    import org.papervision3d.render.BasicRenderEngine;
    import org.papervision3d.scenes.Scene3D;
    import org.papervision3d.view.Viewport3D;

    [SWF(width=600, height=300, backgroundColor=0x000000, frameRate=18)]
    public class Document extends Sprite
    {
        private const MODEL_PATH:String = "files/skeleton.md2";
        private const TEXTURE_PATH:String = "files/skeleton.jpg";

        public function Document():void
        {
            configure();
            buildScene();
        }

        private function configure():void
        {
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.showDefaultContextMenu = false;
            mouseChildren = false;
            addChild(new FPS());
        }

        private function buildScene():void
        {
            var isShading:Boolean = false;

            var mView:Viewport3D = Viewport3D(addChildAt(new Viewport3D(600, 300), 0));
            var sView:Viewport3D = Viewport3D(addChildAt(new Viewport3D(600, 300), 1));

            var mScene:Scene3D = new Scene3D(true);
            var sScene:Scene3D = new Scene3D(true);

            var camera:Camera3D = new Camera3D(null, 5);
            var render:BasicRenderEngine = new BasicRenderEngine();

            var light:PointLight3D = new PointLight3D(true);
            light.y = -100;

            var texture:BitmapFileMaterial = new BitmapFileMaterial(TEXTURE_PATH);
            texture.smooth = true;

            var shading:MaterialObject3D =
            new PhongMaterial(light, 0xAAAAAA, 0x111111, 1);

            var mModel:MD2 = new MD2(texture, MODEL_PATH);
            var sModel:MD2 = new MD2(shading, MODEL_PATH);
            mModel.scale = sModel.scale = 10;
            mModel.rotationX = sModel.rotationX = 90;
            mModel.rotationY = sModel.rotationY = 90;
            mModel.y = sModel.y = -100;

            var ground:Plane = new Plane(new ColorMaterial(0x333333), 3000, 3000, 4, 4);
            ground.rotationX = -90;
            ground.y = -420;

            mScene.addChild(mModel);
            sScene.addChild(sModel);
            mScene.addChild(ground);

            var lightAngle:Number = 0;

            stage.addEventListener(Event.ENTER_FRAME, function ():void
            {
                light.x = Math.cos(lightAngle) * 100;
                light.z = Math.sin(lightAngle) * 100;

                camera.y = Math.sin(lightAngle) * 500 + 1000;

                render.renderScene(mScene, camera, mView);

                if (isShading)
                {
                    render.renderScene(sScene, camera, sView);
                }

                lightAngle += .05;
            });

            var n:Number = stage.stageWidth / 2;

            stage.addEventListener(MouseEvent.MOUSE_MOVE, function ():void
            {
                var cameraAngle:Number = (n - mouseX) / n * Math.PI;
                cameraAngle -= Math.PI / 2;

                camera.x = Math.cos(cameraAngle) * 1000;
                camera.z = Math.sin(cameraAngle) * 1000;
            });

            stage.addEventListener(MouseEvent.CLICK, function ():void
            {
                isShading = !isShading;

                sView.blendMode = (isShading) ? BlendMode.HARDLIGHT : BlendMode.NORMAL;
                sView.visible = (isShading) ? true : false;
            });

            stage.addEventListener(MouseEvent.MOUSE_WHEEL, function (e:MouseEvent):void
            {
                camera.zoom += e.delta * 0.2;

                if (camera.zoom < 2)
                {
                    camera.zoom = 2;
                }
                else if (camera.zoom > 20)
                {
                    camera.zoom = 20;
                }
            });
        }
    }
}
カテゴリー: Flash (ActionScript) タグ:
  1. コメントはまだありません。
  1. トラックバックはまだありません。