PaperVision3Dでトゥーンレンダリング
記事を見つけてから前々からやってみたかったPaperVision3Dでトゥーンレンダリングをやってみました。
こんな感じ
http://moeten.info/flex/20081205_papervision3Dtoonshader/bin-release/main.html
簡単な説明
アイドルマスターみたいにセル画塗り風にレンダリングするには、CellMaterialやCellShaderっというクラスを使用します。
シェードってことなのでライトが必要なので作っておきます。
//ポイントライトの作成 light = new PointLight3D(true); scene.addChild(light); //マテリアル作成 //var cellMaterial:CellMaterial = new CellMaterial( light , 0xFFFFFF, 0x000000,5); var cellShader:CellShader = new CellShader( light , 0xffffff,0x333333,5); var movieMat:MovieMaterial = new MovieMaterial(new Tex1() ); var cellShaderMat:ShadedMaterial = new ShadedMaterial( movieMat , cellShader); //球作成 sphere = new Sphere( cellShaderMat , 100 , 16 ,16); scene.addChild(sphere);
メタセコイアなどのオブジェクトでもできるといいなぁ。
参考リンク
ソースはこちら
<?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[ /* ********************************** 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.MovieMaterial; import org.papervision3d.materials.shaders.ShadedMaterial; import org.papervision3d.materials.shadematerials.CellMaterial; import org.papervision3d.lights.PointLight3D; import org.papervision3d.materials.shaders.CellShader; 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(); setupBox(); 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 ); } //メイン部分 [Embed (source="05.gif")]private var Tex1:Class; private var sphere:Sphere; private var light:PointLight3D; private function setupBox():void{ //ポイントライトの作成 light = new PointLight3D(true); scene.addChild(light); //マテリアル作成 //var cellMaterial:CellMaterial = new CellMaterial( light , 0xFFFFFF, 0x000000,5); var cellShader:CellShader = new CellShader( light , 0xffffff,0x333333,5); var movieMat:MovieMaterial = new MovieMaterial(new Tex1() ); var cellShaderMat:ShadedMaterial = new ShadedMaterial( movieMat , cellShader); //球作成 sphere = new Sphere( cellShaderMat , 100 , 16 ,16); scene.addChild(sphere); } //レンダリング+マウス操作 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; sphere.rotationY -=1; theta+=0.03; light.x = Math.sin(theta)*200; light.z = Math.cos(theta)*200; myLog.text = "x=>" + light.x + "\nz=>" + light.z ; renderer.renderScene(scene , camera , viewport ); } //リサイズイベント private function onResize(e : Event) : void { } ]]> </mx:Script> <mx:UIComponent id="myUI" width="100%" height="100%" /> <mx:TextArea id="myLog" width="204" height="55" x="10" y="10"/> </mx:Application>