両面テクスチャテスト
1枚のPlaneで、カメラからの角度に応じて動的にテクスチャを切り替えてみる。
結果:素直に表と裏で別のメッシュを用意したほうがいいね。。。
次のサンプルを参考にさせていただきました。
・PV3D演出サンプルNo.08:カスタムフラットシェーディング
http://clockmaker.jp/blog/2009/11/papervision3d-flatshader/
/**
* Copyright buccchi ( http://wonderfl.net/user/buccchi )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/sSZQ
*/
package {
import flash.display.*;
import flash.events.*;
import flash.geom.*;
import flash.net.URLRequest;
import flash.system.LoaderContext;
import org.papervision3d.core.math.Number3D;
import org.papervision3d.materials.BitmapMaterial;
import org.papervision3d.materials.utils.MaterialsList;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.objects.primitives.Plane;
import org.papervision3d.view.BasicView;
public class FlashTest extends BasicView {
private var _plane:Plane;
private var _frontTextureBmd:BitmapData; // 表テクスチャ
private var _backTextureBmd:BitmapData; // 裏テクスチャ
private var _mat:BitmapMaterial; // マテリアル
private var imgUrl:String="http://buccchi.jp/wonderfl/201108/m.png";
public function FlashTest() {
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaded);
loader.load(new URLRequest(imgUrl), new LoaderContext(true));
}
private function onLoaded(e:Event):void {
e.target.removeEventListener(Event.COMPLETE, onLoaded);
// 表テクスチャ生成
var bm:Bitmap = Bitmap(e.target.content);
_frontTextureBmd = new BitmapData(bm.width/2, bm.height, true, 0xFFFFFFFF);
_frontTextureBmd.draw(bm);
// 裏テクスチャ生成
_backTextureBmd = new BitmapData(bm.width/2, bm.height, true, 0xFFFFFFFF);
var matrix:Matrix = new Matrix(1, 0, 0, 1, -bm.width/2, 0);
_backTextureBmd.draw(bm, matrix);
// マテリアル生成
_mat = new BitmapMaterial(_frontTextureBmd, true);
_mat.doubleSided = true;
// Plane生成
_plane = new Plane(_mat, 500, 500, 2, 2);
scene.addChild(_plane);
//
camera.z -= 2000;
// レンダリング開始
startRendering();
addEventListener(Event.ENTER_FRAME, loop);
}
private function loop(e:Event):void {
_plane.rotationY += 10;
updateTexture(_mat, _plane);
}
/**
* カメラからの向きに応じてテクスチャを切り替え
*/
private function updateTexture(material:BitmapMaterial, obj:DisplayObject3D):void {
var radian:Number = getDirectionRadian(obj, camera);
if(radian*180/Math.PI < 90){
// 裏テクスチャに
_mat.bitmap = _backTextureBmd;
}else{
// 表テクスチャに
_mat.bitmap = _frontTextureBmd;
}
}
/**
* calc radian of two object's z-axis
* @param obj
* @param target
* @return
*/
private function getDirectionRadian(obj:DisplayObject3D, target:DisplayObject3D):Number {
// obj's Z axis vector
var zAxis:Number3D = new Number3D(obj.transform.n13, obj.transform.n23, obj.transform.n33);
zAxis.normalize();
// calc target's direction
var dummyObj:DisplayObject3D = new DisplayObject3D();
dummyObj.copyTransform(obj.transform);
dummyObj.lookAt(target);
// target's Z axis vector
var targetZAxis:Number3D = new Number3D(dummyObj.transform.n13, dummyObj.transform.n23, dummyObj.transform.n33);
// calc radian of two vector
var rot:Number = Math.acos(Number3D.dot(zAxis, targetZAxis));
return rot;
}
}
}