2009.02 Monthly archives

[Away3D] Away3D 2.3 Feature – NormalMapGenerator

2009.02.27

normalMap Test(要:FlashPlayer9)

Away3D 2.1で、すでにサポート済みの normalMap(放線マップ)と関連して、今回新たに実装されたのが「NormalMapGenerator」。3Dアプリなどであらかじめ作成しておいたnormalMapを適用するのが通常なところを、Away3DでnormalMap自体を作ってしまおうというもの。

とにかくやってみたのが、上のデモ。中学校の技術の授業で作った「ミートハンマー」(笑)
ハンマーの細かいデコボコがnormalMapによるもので、実際のメッシュは真っ平ら。ほんとはローポリとはいえ、ある程度のディテール持たせとくのがセオリーだと思うんで、このサンプルはかなりよろしくないですな;背景でビミョーなファインアート化してるのが、Away3Dによって動的に生成されたnormalMap。

手順はだいたい下記のような感じ。

  • normalMap生成用のハイポリモデルと表示用のローポリモデルを作成(それぞれUV指定しておく)
  • ハイポリモデルをNormalMapGeneratorに渡してビットマップ生成(これがnormalMap)
  • 作成されたnormalMapで、Dot3BitmapMaterial作成
  • ローポリモデルにDot3BitmapMaterialを適用

ちょっとハマったのが、Object3DLoaderで読み込んだメッシュのマテリアルを書き換えるところ。Collada.loadで autoLoadTextures を無効化するのと、loader.handleから該当メッシュのみ取り出す必要があるってのがややこしかった。

var loader:Object3DLoader = Collada.load('hoge.dae', {autoLoadTextures:false});

var mesh:Mesh = Mesh((loader.handle as ObjectContainer3D).getChildByName('fuga'));
mesh.material = dot3BitmapMaterial;

※Flash10 branchには、Dot3BitmapMaterialのPixelBender版がある。パフォーマンスにどの程度違いがあるか気になるところ。

なんつーか、単純にローポリモデルのディテール補完したいだけなら、あらかじめ作っておいたほうが楽だなぁ。どっちにしても一度ハイポリモデル作らなくちゃならないってのが、normalMapの難儀なとこ。せっかく動的生成できるなら、もっと変な使い方したい感じ…ちょっと思いつかないけど。
個人的にはこういうハイエンドっぽい方向性より、シンプルなマテリアルのプリミティブで気持ちいい動きとか作るほうが好きだ。

[Away3D] Away3D 2.3 Feature – nearClipping

2009.02.19

Away3D 2.3 の新機能レポ。

カメラに近いポリゴンをうまいことクリッピングできるようになった。
FrustumClipping と NearfieldClipping がそれ。

FrustumClipping は、いわゆるシザリング(だと思う)。ニアプレーンとの交点でポリゴンを切って、UVとか再設定してくれる。NearfieldClipping のほうは、いまいちはっきりしないけど、UV再定義してないっぽくて近いポリゴンのテクスチャが伸びる。マテリアルのprecisionを有効にしてると見た目も負荷もほとんど変わんない。使い分け方がわかんね。

んで、以前PV3Dで作った迷路を大幅にグレードアップしてみた。

nearClipping Study(要:FlashPlayer9)

■操作方法
カーソルキー [CursorKey] … 移動 (move)
[Z], [X] Key … ティルト (Tilt)

※そこそこ重いのでちょっとしたブラクラになり得ます。ご注意ください。

デフォルトの RectangleClipping だと1人称視点のウォークスルーとか難しかったけど、これでちょっと現実味でたー。

Leopardにrascut入れたらトラブった

2009.02.13

メインで使ってたPowerBook のHDDのb-treeがスっ飛んじゃったんで、これを期にサブで使ってたMacBookProに環境移行中。
んで、rascutがまともに動かないトラブルに遭遇したんでメモっとく。

環境は、OSX10.5.6。
いきなりgemが使えるので、普通にインストール。

sudo gem install rascut --include-dependencies

これだと/Library/Ruby/Gems/1.8/gems/rascut-0.1.3/にインストールされる。

このままだと不具合が起きるので、
下記のページを参考に各ファイルを修正

rascutが動かない。 – 俺はまだ死んではいない
Flex [てきとうにめも]

■/Library/Ruby/Gems/1.8/gems/rascut-0.1.3/lib/rascut/fcsh_wrapper.rb

    @@ -60,10 +60,10 @@
    def process
    unless @process
    - orig_lang = ENV['LANG']
    - ENV['LANG'] = 'C' # for flex3 sdk beta locale
    + orig_java_options = ENV['_JAVA_OPTIONS']
    + ENV['_JAVA_OPTIONS'] = '-Duser.language=en' # for flex3 sdk beta locale
    @process = IO.popen(@config[:fcsh_cmd] + ' 2>&1', 'r+') unless @process
    - ENV['LANG'] = orig_lang
    + ENV['_JAVA_OPTIONS'] = orig_java_options
    end
    @process
    end

■/Library/Ruby/Gems/1.8/gems/rascut-0.1.3/lib/rascut/httpd.rb

   @path = env["PATH_INFO"] == '/' ? @root : F.join(@root, env['PATH_INFO'])
   ↓
   @path = env["PATH_INFO"].empty? || env["PATH_INFO"] == '/' ? @root : F.join(@root, env['PATH_INFO'])

mime-typesが足りないようなので、インストールして

sudo gem install mime-types

/Library/Ruby/Gems/1.8/gems/rascut-0.1.3/lib/rascut/httpd.rbを追加修正

require'mime/types' を追記

"Content-Type"   => MIME_TYPES[ext] || "text/plain",
↓
"Content-Type"   => MIME::Types.type_for(@path).to_s || "text/plain",

てとこまでで、ようやくrascutがサーバーモードで起動できた。
ところが、.asファイルを編集→保存しても、ブラウザをリロードしてくれなかったりいろいろおかしい。

んで、困ってたとこでRUNELEAF_LOGさんの記事を発見。
rack のバージョンが問題とのことで、

sudo /usr/bin/gem install -v 0.3.0 rack
sudo /usr/bin/gem uninstall -v 0.9.1 rack

にて解決した。やれやれだぜ。

追記
コメント欄で、os0x さんに正しい解決策を伝授していただきました。
なんという無駄エントリー。やれやれなのはオレ自身だぜ。

[PV3D2.0] BumpMapの動的書き換え

2009.02.04

Yasu@ClockMakerさんのエントリー「PV3Dの球面に対して波紋効果(Waterball)」を読んで、面白そうだったのでオレもやってみた。かなり勉強になった。

BumpMap Animation Test(要:FlashPlayer9)
※テッカテカの玉をクリックすると波紋が広がります。

原理としては、Shader(この場合EnvMapShader)の bumpmap に割り当ててあるBitmapDataに下記のようなイメージを動的に生成してる。

これだけでデキター!かと思ったら、そんなに甘くなかった。
shadedMaterialに渡すShader、

BumpMap = new BitmapData(width, height, false, 0);
shader = new EnvMapShader
(
    light,
    envMap,
    envMap,
    0x666666,
    BumpMap,
    BumpMap
);

こいつの定義時に指定したbumpmapとかって参照してるわけではなく、内部で別のBitmapDataを作ってるので上の例でいうところの、BumpMap をいくら更新してもマテリアルには反映されないみたい。BumpMapの更新をShaderに渡すには、

shader.bumpmap = BumpMap;

でオケ。(これが分かんねーのなんの)

あと、Yasuさんのエントリで触れられている

ShadedMaterial を使った場合に Mouse3D の取得値がおかしい(やたら小さくなる)

の件に関して。

ShadedMaterialを使ったオブジェクトから返ってくるMouse3Dの座標がUV値であるというのがポイント。ShadedMaterialのように、複数のビットマップが渡せるマテリアルで実座標が返ってくると困ったことになる。なんでか? EnvMapShaderで言えば、環境マップとバンプマップとスペキュラマップのサイズが全て同じなら問題ないけど、違うサイズのマップが混在した場合に実座標が返ってきたら「どれの座標よ?」てなことになる。

ということで ShadedMaterial とか使った場合は、Mouse3DのVirtualMouseの x, y(これがUV値)に、それぞれ実座標を知りたいテクスチャの幅と高さを乗算すればいいと。

vrmouse = viewport.interactiveSceneManager.virtualMouse;

virtualMouseが指すテクスチャのx座標 = vrmouse.x * 座標を取りたいテクスチャの幅;
virtualMouseが指すテクスチャのy座標 = vrmouse.y * 座標を取りたいテクスチャの高さ;

オレの能力不足も手伝って、かなり重いなぁ。Bitmap操作の修業が明らかに足りてない。
こういうエフェクト、それなりに余裕をもって動いてくれれば、さりげない使い方も考えられそうだけど、ここまでマシンパワー使っちゃうと主体性が強すぎてデモにしか使えねー。現状ではローポリとテクスチャの書き込みが重要だとつくづく思う。
が、Bitmap操作の修業から逃げてはいけない>オレ