- 2009年11月18日 (水)
- Tweet
PV3D演出サンプルNo.08:カスタムフラットシェーディング
Flashの3Dライブラリ Papervision3D(ペーパービジョン3D) 2.1 のデモ。高速に実行できるフラットシェーディング(テクスチャに陰影を付ける方法)を試してみました。陰影をつけることで質感に味がでてくるので、ブラッシュアップの一手法として紹介してみます。
技術的な解説は以下から。今回は当ブログ初登場の3D行列計算を試してみました。
フラットシェーディング
ライブラリにはFlatShaderクラスという汎用的なシェーディング機能が備わってますが(関連記事:Papervision3Dでビットマップのテクチャにライトを適用する方法)、込み入ったモデリングデータに適用しようとすると、速度がでない上に破綻することがあります。ビルドインのFlatShaderで試したのは次のデモ。
立方体の面が三角ポリゴンに分割され、破綻しているのが確認できます。ビルドインのFlatShaderは決して完成度が低いというわけではありませんが、あくまでも汎用的な機能なだけに、Cubeなどのオブジェクトには向かないのだと思います。
ちなみにオリジナルで実装したフラットシェーディングを使うと、次のようになります。
どの面に対しても三角ポリゴンのかけらは現れず、ビシッときまっています。
ロジック
予め陰影のついたビットマップデータをキャッシュし、各面の法線方向に応じて適用するキャッシュしたデータを割り当てて実現しています。
ビットマップデータのキャッシュの高速化については、以前このブログ内で何度か紹介しました(参考:[Flashの高速化を試す]BitmapDataを配列に格納することで2〜3倍の高速化、プレレンダリングして処理負荷の高いアニメーションを滑らかに)。今回も同様に1枚のビットマップ画像から数段階のキャッシュを作成して配列に格納しています。
各面に適用する陰影段階の求め方ですが、
- [1] 各面の法線ベクトルを求める
- [2] 対象物と各面のベクトルを求める
- [3] 1と2で求めたベクトルから角度差を求める
- [4] 角度差が小さければ明るい画像を、角度差が大きければ暗い画像を割り当てる
という4ステップで計算しています。
詳しく解説
[1]のZ方向の単位ベクトルは、行列のn13,n23,n33を使用すれば簡単に求まります。こちらは回転行列の列ベクトル│miscellaneousが参考になります。
var zAxis:Number3D = new Number3D( obj.transform.n13, obj.transform.n23, obj.transform.n33); zAxis.normalize();
[2]の対象物へのベクトルは、ダミーオブジェクトを作って lookAt()メソッドを使用し方向を自動計算させます。
// calc target's direction var dummyObj:DisplayObject3D = new DisplayObject3D(); dummyObj.copyTransform(obj.transform); dummyObj.lookAt(target);
これでダミーオブジェクトは対象物の方向を向きます。このダミーオブジェクトから[1]を求めた方法と同様にZ方向の単位ベクトルを求めます。
// target's Z axis vector var targetZAxis:Number3D = new Number3D( dummyObj.transform.n13, dummyObj.transform.n23, dummyObj.transform.n33);
[3]の角度差はNumber3D.dotメソッドを使って求めます。dotは行列の内積を求めるメソッドです。内積から角度を求める方法は線分の長さと角度を参考にしました。
var rot:Number = Math.acos(Number3D.dot(zAxis, targetZAxis));
[4]のビットマップデータの割り当ては各面の[3]で求めた角度を単純に割り算して適用しています。今回のデモでは角度のみの陰影計算ですが、本来はライトからの距離も計算したほうがよいかもです。
以上、技術的な解説が長くなりましたが、誰かが困ったときのお役にたてればと幸いということで残してみました。いつも勉強する際はネットから情報を集めて勉強させて頂いているので、吸収させて頂いた分は還元したいと思って公開しています。解説が至らずご不明な点がありましたらお気軽にコメントくださいませ。
2009年11月18日(水) 13:01
ブログ内容についてではないのですがclockmaker effectのダウンロード先が404になっているのですが、再度掲載していただけないでしょうか?
サンプルを拝見して是非使ってみたいと思いました。
2009年11月18日(水) 19:26
ご指摘ありがとうございます。管理不足で失礼しました。
リンク先を修正しダウンロードできるようにしましたので、再度アクセス頂いてもよろしいでしょうか?
2009年11月18日(水) 23:09
早速の修正大変ありがとうございます!
ダウンロードできましたので試してみたいと思います!
2010年05月08日(土) 02:38
[…] 今回はデバッグがてらclockmaker.jp/blogのカスタムフラットシェーディングサンプルをfake3dで動かしてみました。それと前回ちらっと書いたDebugツールの紹介です。 papervisionで書いたものと […]
2011年12月14日(水) 17:43
貴方が執筆されたPapervision3d入門を基にシェーディング機能の勉強をしている者です。
GouraudMaterialの使い方で困っていることがあり、当方で下記手順を試しました。
[試した手順]
1.BlenderでモデリングしたCubeを、AS3Exportでasデータにエクスポート。
2.上記asデータにGouraudMaterialを使用(PointLightで赤系統を指定)。
[結果]
3.ポリゴン形状の線(白色)が表示され、面自体は指定した色にならない(グレーっぽい色)。
4.同じBlenderデータをCollada形式(dae形式)にエクスポートした場合、ポリゴン欠けなどを除いて指定通りの色・光の描写が得られました。
Papervisionのプリミティブ以外の、モデリングツールで自作したデータにGouraudMaterialを使用したことがありますか?
プリミティブ以外のデータにGouraudMaterialを使用できるのでしょうか?
お忙しいところ、当コメントを見て頂きありがとうございました。
とても困っています!