[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)