さて、COLLADAオブジェクトに、画像テクスチャを貼り、なおかつライトによるシェーディングを設定できるか、という件です。

まず、昨日の要領で、LWのサーフェイス名にマテリアルを割り当て、マテリアル設定ができるようにします。いつまでもサイコロのサンプルというのも何なので、以前に仕事で使ったPCをサンプルに使います。

var mat1:BitmapFileMaterial = new BitmapFileMaterial("collada/pc.jpg",true);
var materials:MaterialsList = new MaterialsList(
{
NotePc: mat1 //「NotePc」というのが、LW側のサーフェイス名(※頭を数字にしないこと)
} );

// Colladaファイルの読み込み
var dae:DAE = new DAE();
dae.load("collada/pc.dae",materials);
scene.addChild(dae);

で、以下のようになります。(画像をクリックしてください)

$Flash 3D 試行錯誤-PCサンプル


テクスチャに少し陰影も付けているので、これはこれで良さそうなのですが、実験のためにこれにシェーディングをつけてみます。

で、その後、いろいろ試行錯誤がありました。

●「CompositeMaterial」でテスト

まず、テクスチャーを複数重ねるなら、「CompositeMaterial」クラスというのがあるからそれで画像とシェーディングを重ねれば良いだろうと思い、ためしてみました。

結果、画像テクスチャを設定することはできたのですが、「Flatshadematerial」など、シェーディングマテリアルを追加すると、長いエラーが出てフリーズしてしまいます。

どうやら、「CompositeMaterial」は、Colorと画像や、Colorとワイヤーフレームなどの組み合わせなら大丈夫なのですが、「Flatshadematerial」以上のシェーディングマテリアルは重ねられないようでした。

ちなみに、重ねる際は先に設定したマテリアルが下になるようです。ある地色の上に画像マップを適用したかったら、先に画像マップを「.addMaterial」で追加してから、色を追加し、色にアルファ値(0~1.0)を指定して透過させると良いようです。

●「ShadedMaterial」でテスト

よくよく調べてみましたら、「ShadedMaterial」というクラスがあることが分かりました。これは、画像とシェーダーを組み合わせてマテリアルを作成し、それをオブジェクトに設定する、というものです。

設定したのが以下です。(画像をクリックしてください)

$Flash 3D 試行錯誤-シェディング付き


このサンプルでは、マウスカーソルに合わせて照明が移動するよう設定しました。マウスを動かして効果を試してみてください。

ソースは以下のようになります。

//ライトを作成
var light:PointLight3D = new PointLight3D(true);
//ベースとなる画像マテリアルを作成
var baseMat :BitmapAssetMaterial = new BitmapAssetMaterial("pc",true);
//シェーダーを作成
var shader:GouraudShader = new GouraudShader(light, 0xFFFFFF, 0x333333, 0);
//シェーデッドマテリアルを作成
var material:ShadedMaterial = new ShadedMaterial(baseMat, shader, 0);

var materials:MaterialsList = new MaterialsList({NotePc: material} );
// 「NotePc」はLWでのサーフェイス名

// Colladaファイルの読み込み
var dae:DAE = new DAE();
dae.load("collada/pc.dae",materials);
scene.addChild(dae);

※注意点

注意すべき点は赤字の行なのですが、「BitmapFileMaterial」ではなく、「BitmapAssetMaterial」を使っています。これは、Flashのライブラリに取り込んだ画像ファイルを利用するクラスです。画像は取り込んだ後、「プロパティ」→「リンケージ」で「pc」というクラス名にしてあります。

「BitmapFileMaterial」で「collada/xxx.jpg」みたいに読み込むと、どういうわけかシェーディングが反映されませんでした。

ということで、画像と、ライトによるシェーディングは反映できることが分かりました。
でも、テクスチャに書き込んじゃった方が作業的には早そうです。

作るコンテンツの性質次第で使い分けるべきでしょうね。

てことで、「画像とシェーディング」の設定についてのメモでした。

次回は、

・LWで簡単に作ったサンプルで、本当にアニメーションが書き出されないか、確認。

アニメーションは書き出されないと思われるので、対処方法の検討、です。
さきほど自分で作った宿題ですが、なんとか解決できました。

まず、問題の歪みですが、先程の投稿の中でアップしたサンプルデータですが、カメラを寄せて表示すると、以下のようになります。

$Flash 3D 試行錯誤-歪みあり


「4」と「6」の文字が歪んでしまっていますね。

で、これに「precise」という設定を使って補正したのが以下です。(画像をクリックしてください)

$Flash 3D 試行錯誤-補正後


さて、preciseを設定する方法なのですが、

precise.マテリアル名 = true;

と書くわけなのですが、先程の投稿で書いたように、LWでUVマップと画像が設定されていた場合はマテリアルを使う必要がないので、どうやってpreciseを設定すれば良いのだろう?と悩みました。

そこで、あれこれいろんな人のブログを見たところ、どうやら、

「LW側で設定したサーフェイス名=マテリアル名らしい」※UVマップ名ではない。

ということが分かりました。

で、さっそく以下のように設定。

つまり、COLLADAにスクリプト側でテクスチャを貼り直す、という形になります。

//BitmapMaterialを6個のUVテクス用に作成
var mat1:BitmapFileMaterial = new BitmapFileMaterial("collada/1.jpg");
var mat2:BitmapFileMaterial = new BitmapFileMaterial("collada/2.jpg");
var mat3:BitmapFileMaterial = new BitmapFileMaterial("collada/3.jpg");
var mat4:BitmapFileMaterial = new BitmapFileMaterial("collada/4.jpg");
var mat5:BitmapFileMaterial = new BitmapFileMaterial("collada/5.jpg");
var mat6:BitmapFileMaterial = new BitmapFileMaterial("collada/6.jpg");

mat1.precise= true;  //作ったBitmapMaterialにPreciseを設定
mat2.precise= true;
mat3.precise= true;
mat4.precise= true;
mat5.precise= true;
mat6.precise= true;

(2010/06/18修正)
上のpreciseの設定ですが、一個一個trueにしなくても、BitmapMaterial作成時に、
var mat1:BitmapFileMaterial = new BitmapFileMaterial("collada/1.jpg",true);
と入れるだけで良かったようです。う、恥ずかし。


var materials:MaterialsList = new MaterialsList(
{
11: mat1, //「11」というのがLWでのサーフェイス名。そこにBitmapMaterialを割り当てる。
22: mat2,
33: mat3,
44: mat4,
55: mat5,
66: mat6
} );

あまりにもベタな書き方なのでちょっとカッコ悪いですが、実際にはもうちょっと効率的な書き方がありそうです。

これで、各UVテクスごとにマテリアルが設定できるようになりました。

てことは、もしかして、動的なシェーディングが設定できるのではないでしょうか?

てことで、次回の宿題は

1、UVテクスチャ(画像)を設定したマテリアルに、シェーディングが設定できるか?
2、LWで簡単に作ったサンプルで、本当にアニメーションが書き出されないか、確認。

としたいと思います。

てことで、
「LWから書き出したCOLLADAオブジェクトに、PV3D側でUV用のテクスチャを貼る」
の巻でした。
さて、オブジェクトにUVマップでテクスチャを貼ってみます。

UVの向きに矛盾などないか検証するため、さいころのように各面に番号を貼り付けます。

LWモデラーで面ごとにUVを貼ります。

LW画面


それを、Papervision3Dで読み込みます。(画像をクリックしてください)

SWF画面


特に問題なくテクスチャーが貼られているようです。

ちなみに、昨日のサンプルで設定していたFlatShadeMaterialを外しています。

dae.load("collada/base_poly.dae",material);

この赤字部分を外しました。

そして、注意事項ですが、コチラのサイトでも書かれているように、COLLADAファイル内の画像パスを手書きで修正しなくてはなりません。というか、画像もCOLLADAと一緒に一つのデータになるのかと思っていたのですが、COLLADAってバイナリデータじゃなくアスキーデータなんですね。

で、テキストエディタで開いて、LW内の画像パス読み込みリンクを、実際のアップ時のパスに書き換えます。そしてDAEファイルから正しい位置関係になるよう画像データも配置します。

ここまでで気になる点ですが、まず第一に、UVテクスチャを表示させるには、Papervision3D側のマテリアル設定をはずさないといけないらしいことです。つまり、動的なライティングやシェーディングは使えなくなるため、陰影は画像テクスチャにベイクしないといけないようです。

この点については、LWのセミナーで講演した方も「ベイクしないといけない」と言っていたので、おそらくそれしか方法がないのだと思います。良い方法が発見できたら試してみます。

動的にライティングやシェーディングが反映される3Dコンテンツを作ろうと思ったら、CPLLADAではなくPV3Dでオブジェクトやテクスチャを設定する方法にしなくてはいけないということですね。

この辺の制約は、作るコンテンツの性格に応じて頭を使って対処すべきなんでしょうね。

気になる点の二番目は、上のサンプルのような粗いオブジェクトだと、回転する際に数字が歪んで見えることがあります。これは、三角ポリゴンにしている影響だそうですが、これは直せないものかなと。

これはちょっと宿題にします。(preciseをどうにか使えないものか…)

てことで、UVマッピングのメモでした。
さて、今日までに、Papervision3Dのある程度のお約束事は学習してきていますが、その辺の細かなスクリプトの書き方などを掘り下げるのはちょっと後にし、かねてから気になっていたLightWave3Dのオブジェクトの読み込みについて試してみようと思います。

すでにこのテーマについて実験されている方は結構多いようですが、ほとんどの方は「うまく再現できない」とおっしゃっています。

こちらに書かれているように、アニメーションがうまくいかない、とのことです。
http://www.ahiru.org/archives/135
この方は、Unwrap3Dというニッチなアプリケーションを介したようですが、セミナーで講演されていた方は、「swift3d」を介する、とおっしゃっていました。

とりあえず、私が仕事で作る分には、おそらくボーンを使ったアニメーションというケースは少ないように思いますので、まずはLightWaveでどこまでいけるか試してみます。

ボーンアニメが必要な場合は、新しいソフトを買う前に、手持ちのPoserからの書き出しも試してみたいところです。

さて、LightWaveでのテストですが、まずはシンプルな直方体からやってみます。

3Dソフトのように、3Dオブジェクトをプレビュー確認するインターフェースがFlashには無いようなので、まずは覚えたてのPaperviewのスクリプトをあれこれつなげて、マウスアクションで回転するSWFを用意しました。(ちょっと適当なので、動きは要調整ですが)

さて、普通の四角ですが、以下のような感じで出ました。(画像をクリックしてください)

$Flash 3D 試行錯誤-四角

一応、ちゃんと出ているようです。背景は、オブジェクトが目立つようにグリーンにしました。
黒い面と白い面がはっきり分かれているのは、ライトが一方向だけからだからでしょう。黒い面が陰になっている部分です。

マウスで動いているのがカメラだから、回転しても陰の部分は同じ面です。

さて、今度はちょっと複雑な形状を使ってみます。

$Flash 3D 試行錯誤-SLアバター

これは、SecondLifeのアニメーション作成用にSL公式サイトで配布されているオブジェクトです。これをLWに読み込み、いったんLWO形式の状態にしてから、COLLADA(.DAE)に書き出します。

で、それを読み込んだのが以下です。(画像をクリックしてください)

$Flash 3D 試行錯誤-Flash内SLアバター

ポリゴンが多いのでちょっと重いですね。この辺も後々研究する必要ありそうです。

が、一応、オブジェクトとしてはちゃんと読めているようです。テクスチャーはまだ貼っていないのと、スクリプト上でフラットシェーディングを設定しているので、まあこんなもんでしょう。

とりあえず、これでオブジェクトは読めるとして、次はUVテクスチャを貼ったもののテストに進みましょう。
さて、今日から実際にトライアルしている内容を書き記していこうと思います。

まずは、パスについて。

私が参考にしている書籍に付属のデータでは、Papervision3Dのライブラリを、
sample/lib/org
というように格納してあり、
sample/各フォルダ/サンプル.fla(.as)
から
import org.papervision3d.view.*;
というように呼んでいました。

ちなみに、この一式を「Papervision3D」というディレクトにまとめて作業していました。

これで、最初のうちは問題なく各サンプルファイルをパブリッシュできていたのですが、DAEファイルを読み込む段になると、パブリッシュ時に
「基本クラス BasicView の定義が見つかりませんでした。」
というエラーが出るようになりました。

あれこれと調べたのですが、まったく原因が分からず困ってしまいました。

Webで検索して調べても、参考になる答えは無く、ただ、パスが原因かもしれない、という書き込みがあったため、試しに、すべてのデータをまとめたディレクトリをDドライブ直下に置き、その下にすぐにorgディレクトリが来るようにしてみました。

D/任意のディレクトリ名/org/....
D/任意のディレクトリ名/以下に.fla(.as)

これでエラーは出なくなりました。

とりあえずこれでうまくいったので、これ以上の原因追求はまたの機会にしますが、どうやらDAE読み込みを使う可能性があるならば、ディレクトリはあまり深くしちゃまずいようです。

とりあえずメモメモ。