残像とモーションブラー

・残像を少々

 最初パーティクルについてやろうと思ってたんですが、その前にこの2つをやっといた方がいいかということで。

 まず残像。残像というと、バーチャファイター3がやってますね。あれは単純にキャラを残像の分だけ書いてるんだと思います。それと、格闘ゲームでよく見かける青い残像。


最初にやったのはファイナルファイトの
ロレントか?キャラはDoGA-L2の
サンプルを流用。ハゲじゃないです

 これもポリゴンでやるならそのキャラ分描画しないといけないでしょうね。

 それよりお手軽・高速で画面全体に使える残像。そんな残像がα合成を使えば可能です。

 やり方は、画面のクリアの代わりに半透明で背景色を画面全体に描画するだけです。それ以外は普通の描画と同じで。


普通の場合。
まず描画

  


背景色(この例では
黒)で画面をクリア

  
次に描画。これが
普通の流れ

 


残像を使う場合。
まず描画

  


クリアの代わりに
背景色の半透明

  
次に描画。残像に
なってますね

 ではこの手法に関する注意点を列挙。

 クリアしないと言っても、Zバッファはクリアしてください。ちなみに、”ZバッファをClear2でクリア+半透明ポリゴンで塗りつぶし”と”Z値1.0(一番奥)の半透明ポリゴンで塗りつぶし(Z書き込みあり)”でFPSを比べた結果、45FPS・40.5FPSでした。やっぱりClear2の方が早いですね。HELでは断然Clear2の方が早いし。

 この方法は、ちゃんとした残像とは言えません。物体を描画した時、その物体で残像が上書きされてしまうので残像が見えなくなります。ちゃんとした残像は物体と残像が重なると思いますが、まぁこれでも残像みたいだし速いからいいでしょう。この後のモーションブラーでは、ちゃんと重なる方法を使う必要があります。

 この例では背景色を黒としていますが、どんな色だろうと模様だろうとできます。背景があっても、その背景を半透明で書けば残像ができます。オーバードロー(ピクセルの上書き)があるとそこだけ残像が薄くなりますが。解決方法は前回の「映り込みと床と影と」を参照。

 残像と加算合成を一緒に使うと、残像を使わない時に比べて加算合成で書く物体が明るくなるでしょう。残像が残ってる上に加算合成する事になるので。その性質を利用すると、エッジが目立たなくなったりより明るさを強調できたりして便利です。お試しあれ。

 フルスクリーンでFlipを使うか、ウィンドウモードでバックバッファからBltを使うかで残像の消える速度が違います(1つのサーフェイスに対するクリア回数がFlipのせいで違ってくる)。その差は2倍。バックバッファが3つなら3倍。結果をなるべく同じにしたいなら、残像の消える速度をモードによって調整する必要がありますね。あぁ面倒。

 クリアの代わりに使うのは、何も半透明に限定されている訳ではありません。混合要素の使い方次第では、変わった残像もできるでしょう。明るい残像とか、最初で例に挙げた青い残像とかも可能です。色の着く残像はなかなか綺麗です。

 この手法を最初に見たのはスターフォックス64、それから使い方がうまかったのが”ゆけゆけ!トラブルメーカーズ(N64)”。その後、アーケードでジャスティス学園やソウルキャリバーでも減算合成を使った残像効果を使ってました。コンシューマ機は64しか持ってないんですよ……。PCのゲームはあまりやらないので(もっぱらデモ版)、PCでこの残像効果を使っているゲームは見た事が無いです。

 メタルギアソリッド(PS)では、残像をモーションブラーの代わりとして使っています。おかげでエッジも目立たないし。こっちはフィードバックエフェクトを使ってちゃんとした残像効果になってますが。フィードバックエフェクトについては後々書く予定。

 残像ネタはこれで終わり(短い)。次は残像と似て非なるもの、モーションブラーについて。

 

・モーションブラ〜

 テレビなどで、物体が高速に移動した時にその物体がぶれたように見える(特にスローだとよくわかる)現象。それがモーションブラー(motion blur)です。今の季節だと雪の映像などに見て取れると思います。

 原理などの詳しい説明はMasaさんの98/4/11と98/4/22分のコラムを読んでください。このページでの説明はしません。ここで説明しようとしても同じ事しか書けないし何より文章力の違いが……。
では、それを読んだという前提で話を進めます。

 例として、白い点が高速に左から右へ移動するとします。普通の描画だとこうなります。シャッタースピードがすごく高速でもこう見えると思います。


一番上が1フレーム目、真ん中が2フレーム目、
下が3フレーム目という画像。見難いので縦2倍横2倍に拡大

 1フレームのうちシャッターが50%の時間分開いてると、以下のような見え方になります。


線のようになってて、線の長さが1フレームの
移動距離の半分。すこし色が薄くなってますね

 シャッター開きっぱなしだとこんな感じですかね。星の観測用に長時間開きっぱなしでもこんな感じですね。


もっと薄くなってます。線の長さは移動距離と
同じで、前のフレームと線が繋がります

 線の透明度は適当です。モーションブラー時の透明度まではちゃんと理解してないので……。暗くなっているように見えますが、これは背景が黒で点が薄くなっているため暗くなっているように見えます。この画像では点の明度がそれほど高くないのでかなり暗く見えますが、明るければモーションブラーを使ってもあまり暗くなりません(星の観測用の写真とか)。
コロニーウォーズ(PS)の星なんかもこの方法を使っていたような。

 このような点の場合はもちろん、単純な形の物ならモーションブラーを使うのも楽なんですけど、3次元の物体に使うとなると話は別です。点を線にする延長で考えるとポリゴン数を増やすという方法が思い付きますが、テクスチャやライティングがあるので多分無理でしょう。
簡単な方法として、1フレームをいくつかに分割してその分だけ薄くして重ねて描画する方法があります。点の例で言えば、点を薄く幾つも書いて線みたいにします。モーションブラーについてのコラムにも書いてありましたね。

 例えば、第1フレーム→第2フレーム→第3フレームという順に描画するとして、第2フレームを描画したい。シャッターは大体開きっぱなし、1フレームを4つに分割して描画するなら、描画するのは第1.25フレーム・第1.5フレーム(第1と第2のちょうど中間)・第1.75フレーム・第2フレームで、それぞれ不透明度1/4だから25%(逆に言えば透明度75%)で描画するということになります。シャッタースピードが1フレームの50%分開いてるなら、描画するフレームは第1.625フレーム・第1.75フレーム・第1.875フレーム・第2フレームとなります。
なんだか小難しく説明してますが、要は不透明度1/分割するフレーム数時間を等分に分割して描画するだけです。


高速移動にモーションブラー。
分割数は4。よく見えん

 この画像だと移動速度速すぎですね。分割数を上げてもよく見えないのには変わり無いでしょう。滑らかにはなりますが。

 

・突っ込んだ

 ここまで説明した分でもうモーションブラーはできるはずですが、もうちょっと突っ込んだ説明をします。いろいろと注意すべき所とかがあるんで。

(1)スクリーンのビット数

 分割数が4なら25%の不透明度で4回描画と書きましたが、なんだか意味がわかりませんね。実際にやるなら明度25%を4つ加算合成するということになるでしょうか。そうするとそれぞれ足して合計100%になるので。過程を図で表すとこんな感じ。


まず第2フレームを明度25%で描画。
別に第1.25フレームから書いてもいいです


同様に第1.5フレームを明度25%で描画。
この時(2つ目の描画)から加算合成を使う


これも同じく第1.25フレームを明度25%で描画。
青で書いてるのは今描画した分ということを表してます


最後に第1.25フレームを明度25%で描画。
これで完成

 これで綺麗なモーションブラー。……と、言いたい所ですが、これにはある弱点が。それは、スクリーンのビットが少ないと丸め誤差によってグラデーションが綺麗に見えなくなる事。100%→25%にした時に下位の方のビット(25%なら半分の半分だから2ビット)が切り捨てられてしまいます。25%にして4つ加算すると、誤差は100%→25%にした時の誤差×4にもなります。分割数が多くなれば多くなるほど深刻になってきます。

 スクリーンのビット数は3Dで現在よく使われるのは16ビットです。これではRGB各ビットに5ビット程度しか使えません。分割数が4だと実質使えるのはたった3ビットになってしまいます。そして、16ビットのピクセルフォーマットは555と565があります。565(5bit6bit5bit)だと赤・青と緑の誤差の出方が違ってくるため、ただの灰色なのに緑っぽくなったり紫っぽくなったりしてしまいます。

 そこで、それよりは誤差が目立たない方法。先に明度を落として描画するのではなく、描画する時に初めて今まで描画した分の明度を落とす。以下のような感じ。


まず第2フレームを何も考えず普通に描画。
これも第1.25フレームから書いてもいいです


ここからがちょっと違う。半透明で描画をする。明度はそのまま。
不透明度は1/2、つまり50%(透明度も1/2→50%)


3つ目の描画は不透明度1/3、透明度2/3で描画。
つまり不透明度は33.3…%


最後は不透明度1/4、透明度3/4で描画。
これで完成。”第2フレーム”ってボーリングみたいだ……

 つまり、うまく等分になるように不透明度を調節するという事です。分割数が8なら不透明度は1→1/2→1/3……1/8となります。透明度で表すなら0→1/2→2/3……7/8。だんだん透明になってますね。こうすると多くの場合において加算合成よりも誤差の影響が出難いです。明度はそのまま描画して、後で明度を落とすので。

 ちなみにこの方法もMasaさんが3DFCで言っていたらしいです。僕は行ってないので実際の所はわかりませんが。それ以前にも自分で思い付いていましたし、他にも同じ事を考えていた方もいたようだし。3Dってどうしても精度が心配になる……。スクリーンのビット数の他にもZバッファとか浮動小数点とか。

 それと、加算合成にはない特徴があります。この方法は、一番最初のフレームの描画の仕方がモーションブラーを使わない時と同じです(明度も)。そして、図を見ればわかると思いますが、途中で止めても描画結果は自然です(シャッタースピードが違うだけ)。加算合成だと途中で止めると色が暗いです。その性質を利用して、シャッタースピードを動的に変更できます。

 例えば、普段は普通に描画。でも描画し終わってもまだまだ時間が余っているなら前のフレームとの間の状態を描画。それでもまだ時間が余っているならその間の状態を描画……と繰り返すと、描画に時間がかかる時は普通、描画に時間がかからない時はモーションブラーありという感じにできます。加算合成だと描画する前に描画時間を予測する必要があります。

 でも、実際に動的にシャッタースピードを変えるようにするには多分いろいろと面倒だと思いますけどね……。

(2)オーバードロー

 出ました、またもやこの問題。加算合成によるモーションブラーだとオーバードローのあった所は明るくなり、半透明によるモーションブラーだとオーバードローのあった所は薄くなります。半透明の方が目立たないでしょうね。

 解決方法は前回やった「映り込みと床と影と」を参照。この場合は気にしないのが一番得策かも。

 オーバードローについては以上。なんだかやたらと短いですが、この問題はかなり深刻です。これがあるからモーションブラーは遅くなると言っても過言ではないかと。

(3)フィルレート

 モーションブラーを使うと、かなり遅くなります。必ずα合成使うし、速度のために”Zテストなし”とか”Z書き込みなし”にする、という方法が使える場合が少ないし(オーバードロー問題があるので)、フレームを分割する回数以上に描画を繰り返さないといけないし……。描画速度はかなりフィルレートに依存します。1秒間に可能なポリゴン描画枚数以上に。分割する数と同じ回数描画すると考えては駄目です。最悪の場合、分割数が4なら1つの物体を7回描画する事になります(最初の描画+オーバードロー回避用に2回×3)。

 背景の描画にもかなり時間を使うと思うので、背景はモーションブラーを使わず物体にだけ使う方が良いでしょう。それなら処理する部分も物体によって更新された部分だけになるし。

(4)分割数とシャッタースピード

 1フレームを分割する数は、多ければ多いほど滑らかになります(多すぎるとスクリーンのビット数次第で色が変になるが)。しかし、多ければ多いほど描画が増えるため遅くなります。分割数を変えて比較。


こんなテクスチャ
貼った箱をぐるぐる
回して実験

 
分割数4。
いかにも何度も
書いてる感じが。
 
分割数6。
よく見るとまだ何
度も書いてる感じ
 
分割数8。
静止画でも大丈夫
な範囲

 この回転速度だと、分割数が6は最低限欲しい所ですね。でも増やせば増やすほど処理速度は落ちていく……。回転速度によって分割数を変えるという方法もありますね。
この画像は、1フレームの時間のうちほとんどシャッターが開いている状態ですが、これを変える事で分割数をごまかすことができます。このように。


分割数4でシャッター
開きっぱなし

 
分割数4で50%の
時間開いた状態

 モーションブラーの効果は薄れますが、何度も書いたように見えるよりはマシになってるでしょう。

 

・果たして実用性は?

 これでモーションブラーは終わり。あまり大した事は書いてないですね。コラムを少し補足した感じですか。

 ここまでモーションブラーについてやってみて思ったんですが、3次元の物体にリアルタイムで使うもんじゃないですね、これは。人間の目なら、60FPS出てればモーションブラーの効果を使わなくても十分滑らかに見えますし。静止画や、ちょっとしたインパクトのためなら使えるでしょうけど。
それでもリアルタイムに使いたいなら、小さくて高速な物体だけに限定したり、簡単な残像効果でごまかしたり、予めモーションブラー効果のかかったテクスチャを使うのをお勧めします。αビット付きテクスチャならモーションブラーの効果も自然に見えるでしょうしね。

 単純な形の物体ならリアルタイムでも十分使えます。特に点の移動には効果を発揮すると思います。

 

 今回は、モーションブラーのサンプルデモを置いておきます。(4)分割数とシャッタースピードで使った物です。

mblurtes.lzh(57KB)

 使い方は一緒に入っているテキストを見てください。ただ立方体がぐるぐる回るだけです。

 

 

written by Y.Ohde  e-mail : oode@alles.or.jp

back