Collada形式にトゥーンシェーダー
Collada形式を読み込んでセル画みたいなレンダリングトゥーンシェーダーをしてみました。
こんな感じ。
http://moeten.info/flex/20081208_pv3dColladaCell/bin-release/main.html
激重いよ!
基本的にテクスチャを準備して、ライトと関連付ければOKです。
メインな部分。
//Colladaの作成 [Embed(source="miku.png")]private var materialAsset:Class; private var collada:Collada; private function setupCollada():void{ var bitmap:Bitmap = new materialAsset() as Bitmap; var bitmapMaterial:BitmapMaterial = new BitmapMaterial(bitmap.bitmapData, true); var cellShader:CellShader = new CellShader(light, 0xffffff, 0x000000, 6 ); var shadedMaterial:ShadedMaterial = new ShadedMaterial(bitmapMaterial, cellShader); collada = new Collada("miku.dae" , new MaterialsList({all:shadedMaterial}) ,0.1 ); scene.addChild(collada); }
一応3Dキャラクタってことではちゅねでも
http://moeten.info/flex/20081208_pv3dColladaCell/bin-release/main_miku.html
見てみると分かると思うのですがテクスチャ関係がうまくできてません。
これは原因はテクスチャ画像がこんな感じになっているからだと思います。
画像が半分だけ作成されていることがわかると思います。たいていの3Dデータって左右対称なので節約って面でもよくこういった方法が使われるんだと思います。
3D作れる技術があればこういったトラブルも回避できるのになぁ汗
参考リンク
すべてのソースはこちら。
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init3D()" width="640" height="480" backgroundGradientColors="[0x999999,0x000000]" viewSourceURL="srcview/index.html"> <mx:Script> <![CDATA[ import org.papervision3d.materials.utils.MaterialsList; import org.papervision3d.objects.parsers.DAE; import org.papervision3d.materials.shaders.ShadedMaterial; import org.papervision3d.materials.shaders.CellShader; import org.papervision3d.materials.BitmapMaterial; import org.papervision3d.objects.parsers.Collada; import org.papervision3d.lights.PointLight3D; /* ********************************** PV3D ********************************** */ import org.papervision3d.cameras.Camera3D; import org.papervision3d.render.BasicRenderEngine; import org.papervision3d.scenes.Scene3D; import org.papervision3d.view.Viewport3D; import org.papervision3d.objects.DisplayObject3D; import org.papervision3d.objects.primitives.Sphere; import org.papervision3d.materials.WireframeMaterial; import org.papervision3d.objects.special.SimpleLevelOfDetail; import org.papervision3d.materials.BitmapFileMaterial; private var scene : Scene3D; private var viewport : Viewport3D; private var renderer : BasicRenderEngine; private var camera : Camera3D; private var cameraTarget : DisplayObject3D; //初期化 private function init3D():void{ setupScene(); setupCamera(); setupLight(); setupCollada(); setupListeners(); } //シーンの作成 private function setupScene():void{ viewport = new Viewport3D( myUI.width , myUI.height , true , false , true , true ); myUI.addChildAt(viewport , 0); renderer = new BasicRenderEngine(); scene = new Scene3D(); } //カメラ設定 private function setupCamera():void{ cameraTarget = new DisplayObject3D(); camera = new Camera3D(); camera.z = - 300; camera.y = 10; } //イベントリスナー設定 private function setupListeners():void{ this.addEventListener(Event.ENTER_FRAME , onRenderTick ); } //レンダリング+マウス操作 private var theta:Number = 0; protected function onRenderTick(e:Event):void { var reach:Number = 0.01; var ease:Number = 0.1; var cameraDistance:Number = 100; camera.x += (Math.sin(mouseX * reach) * cameraDistance - camera.x) * ease; camera.y += (Math.sin(mouseY * reach) * cameraDistance - camera.y) * ease; theta += 0.1; light.x = Math.sin(theta)*200; light.z = Math.cos(theta)*200; renderer.renderScene(scene , camera , viewport ); } //リサイズイベント private function onResize(e : Event) : void { } /* ***************** myMain ***************** */ //ライトの作成 private var light:PointLight3D; private function setupLight():void{ light = new PointLight3D(true); scene.addChild(light); } //Colladaの作成 [Embed(source="ball.png")]private var materialAsset:Class; private var collada:Collada; private function setupCollada():void{ var bitmap:Bitmap = new materialAsset() as Bitmap; var bitmapMaterial:BitmapMaterial = new BitmapMaterial(bitmap.bitmapData, true); var cellShader:CellShader = new CellShader(light, 0xffffff, 0x000000, 6 ); var shadedMaterial:ShadedMaterial = new ShadedMaterial(bitmapMaterial, cellShader); collada = new Collada("ball.dae" , new MaterialsList({all:shadedMaterial}) ,0.05 ); collada.y = -100; scene.addChild(collada); } ]]> </mx:Script> <mx:UIComponent id="myUI" width="100%" height="100%" /> </mx:Application>