チュートリアル / GEMBAコンバート道
第5回:エフェクト編

  • 3ds Max
  • エフェクト
  • コラム
  • チュートリアル
  • データ
  • 上級者
  • 中級者
  • 映画・TV

こんにちは、GEMBAの水橋です。コンバート道、第5回はエフェクト編です。
今回は爆発や破壊など、エフェクト作業をするための下準備だったりシーンの最適化のお話をしたいと思います。

第5回エフェクト編

実際のプロジェクトでは、ショットをエフェクトから作り始めるのは稀だったりします。
カメラやBGが既に用意されていたり、キャラがいてアニメーションがついていたり、ショット作業の多くはエフェクト以外の要素が決まった状態からスタートします。

打合せ等で仕様を決めておいたり、アセットを作っておいたり、実作業の見積もりより、下準備に時間をかければ、トライ&エラーが多く行え、ヘビーなシミュレーションが短時間で済むかもしれません。
そして効率よく最適化すればクオリティアップに貢献できるのではないでしょうか。
そのためのヒントをスクリプトを交え、コンバートしていきたいと思います。

シーンをベイクする

複雑な親子構造やコンストレインを駆使したシーンからはじめる場合、無駄な操作が増え、シーンの状態が複雑難解になりがちです。
そんな状態では、エフェクト用のエミッターやコリジョンを用意するのに時間がかかります。なので、複雑なシーンをシンプルなものにコンバートします!

1.キーアニメーションのベイク

トランスフォーム(位置・回転・スケール)のアニメーションは1Fずつベイクして(焼き付けて)しまいましょう。

(
	local objs = selection as array
	local plots = #()
	for obj in objs do (
		append plots (point())
	)
	for i = animationrange.start to animationrange.end do (
		slidertime = i
		animate on (
			for k = 1 to objs.count do (
				plots[k].transform = objs[k].transform
			)
		)
	)
	for i = 1 to objs.count do (
		objs[i].parent = undefined
		objs[i].transform.track = plots[i].transform.track
	)
	delete plots
)

選択しているオブジェクトのトランスフォームをワールド座標にプロットするスクリプトです。親子関係やコンストレインなど無視しします。
これで、必要のないヘルパーや親子階層などを削除できます。

似たようなものとして、破壊系プラグイン「RayFire」の機能の「RFCache」があります。
トランスフォーム情報をキャッシュとして保存できますので、お持ちの方はこちらで事足りるかもです。

細かいところを解説

local objs = selection as array
local plots = #()
for obj in objs do (
	append plots (point())
)

選択されたオブジェクトは配列に格納し、 同じ数だけのポイントヘルパーを作成しています。

for i = animationrange.start to animationrange.end do (
	slidertime = i
	animate on (
		for k = 1 to objs.count do (
			plots[k].transform = objs[k].transform
		)
	)
)

アニメーション範囲をForループさせています。
スライダータイムに順番にフレームを代入していくことで、アニメーションを再生します。
1Fずつポイントヘルパーのトランスフォームをアニメーションさせます。

for i = 1 to objs.count do (
	objs[i].parent = undefined
	objs[i].transform.track = plots[i].transform.track
)

オブジェクトの親をundefinedにすることで、リンクが切れます。
そこにワールドでベイクされたヘルパーのトランスフォームを入れ替えます。

delete plots

ベイクに使ったヘルパーはもう必要ないので削除します。

2.キャッシュ化する

トランスフォームだけではなくデフォーマなどで変形している場合は、頂点単位でのアニメーションのベイクが必要です。
なるべく複雑なモディファイヤを一つにまとめましょう。
方法はいくつか考えられます。

● PointCacheでキャッシュ化
 ○ 第4回のスクリプトを使う
● Alembicでキャッシュ化
● XMeshなどのプラグインでキャッシュ化
● ローポリスキンラップ
 ○ 簡単なコリジョンが欲しい時
● PFでエミッターを作る(PFBaker)
 ○ 簡単なエミッターが欲しい時

なるべくオブジェクト数を減らして、シンプルなシーンを作成するのがコツです。
キャッシュ化については以前の記事で度々登場しているので割愛させてもらいます。

そのかわり、簡易的にエミッターやコリジョンが欲しい場合の方法をご紹介。

ローポリスキンラップ

コリジョンやエミッターがハイポリである必要がない場合、ローポリで軽くしてしまいましょう。というやり方です。

まず、軽くしたいモデルをコピーします。

ポリゴン化してモディファイヤなどを消します。
このとき、ついでに不必要なマテリアルも剥がしてしまいます。

$.material = undefined

スクリプト一行で簡単にできます。覚えておくとなにかと便利です。

1つのオブジェクトにアタッチします。

モディファイヤのProOptimizerでポリゴン数を減らします。

SkinWrapでアニメーションしているモデル(コピー元のオブジェクト)を適用します。

PointCacheでアニメーションを保存して、SkinWrap以下のモディファイヤCollapseでまとめたら、コンバート完了!

ビフォアー・アフター

ビューポート上のFPSが約2fpsだったものが、約80fpsも出るようになりました!
単純計算で40倍も軽快になったことになります!スバラシイ

PFでエミッターを作る

形状など関係なく大まかなエミッターが欲しい場合、ParticleFlowを使う方法があります。

まず、こんな感じのPFを作成します。

PositionとLock/Bondにエミッターにしたいオブジェクトを割り当てます。

ここで、PFlowBakerというスクリプトを使用します。

PFlowBaker
http://www.scriptspot.com/3ds-max/scripts/pflow-baker

パーティクルがメッシュにBakeされ、エミッターやコリジョンに使えるようになります。
Mesherなどでやってもよさそうですが、この方法のいいところは、キャッシュをとらずにオブジェクトのアニメーションにできるというとこです。

他にもいろいろシーンを軽くする方法があると思います。
自分の中で最近はZBrushのDynameshとZRemesherでローポリ作成するのが流行りです。ちょっと安定しませんが・・・。

アタッチやオブジェクト内の不要なポリゴン削除、リダクションを一気にやってくれます。
みなさんの自己流を機会があれば是非聞いてみたいです!

とりあえず、おまけの動画とスクリプト

スクリプトのリンク

ではでは、今回も読んでくださいましてありがとうございました。

製品購入に関するお問い合わせ
オートデスク メディア&エンターテインメント 製品のご購入に関してご連絡を希望される場合は、こちらからお問い合わせください。