OpenGLプログラミング/Motion Blur

出典: フリー教科書『ウィキブックス(Wikibooks)』
ナビゲーションに移動 検索に移動
Normal.
Motion blur.

はじめに[編集]

色、深度、ステンシルバッファ以外にも、ほとんどのグラフィックスカードは、アキュムレーションバッファといわれるものをそなえてます。 これらは本質的には色ごとに精度16ビット以上のカラーバッファです。 しかしながら、アキュムレーションバッファに直接描画することはできません。 その代わりに、アキュムレーションバッファ全体に一度に作用する操作はほんのいくつかだけです。

  • glAccum(GL_LOAD, value): ノーマルカラーバッファの内容をコピーして、 valueで乗算し、アキュムレーションバッファへ。
  • glAccum(GL_RETURN, value): アキュムレーションバッファの内容をコピーし、 valueで乗算し、カラーバッファへ。
  • glAccum(GL_ACCUM, value): ノーマルカラーバッファの内容を加算し、 valueで乗算し、アキュムレーションバッファへ。
  • glAccum(GL_ADD, value): アキュムレーションバッファ内のすべてのピクセルに valueを加算する。
  • glAccum(GL_MULT, value): アキュムレーションバッファ内のすべてのピクセルに valueを乗算する。

すべての場合において、 valueは浮動小数点です。 これらの関数は、フレーム数の(加重)合計や平均を計算しやすくします。 この最初のチュートリアルでは、これを使用して、ほぼすべてのOpenGLプログラムに簡単にモーションブラーを追加できる方法を説明していきます。

モーションブラー[編集]

モーションブラーが起こるのは、オブジェクトが(カメラに対して)非常に速く移動するときか、またはカメラの露光時間が長いときで、露光中にオブジェクトが半ピクセル以上移動することになり、したがって不鮮明に表示されます。 モーションブラーは、通常は望ましいことではないですが、本物のカメラでは避けることが難しいときもあり、その理由は露光時間がシーンの(大部分の)光の量に依存するからです。 そこに光が少ないほど、露光時間が長くなり、モーションブラーの効果は強くなります。 これはビデオカメラで屋外でのビデオ撮影をするときに、同じカメラで室内でのビデオ撮影をするときとは異なって "感じる"ことの理由の一つです。

Simulating motion blur[編集]

アキュムレーションバッファを使用したモーションブラーエフェクトの作成は、実際には非常に簡単です。 OpenGLアプリケーションが動作する通常の方法はこれです:

while(true) {
  do_time_evolution(timestep);
  draw_scene();
  glSwapBuffers();
  wait_until_next(timestep);
}

ここで、関数 do_time_evolution()はシーン内の動くオブジェクトの座標の更新、および/ ​​またはカメラ自体の動きを処理してくれます。 シーンが描画された後、 glSwapBuffers()を使って画面に表示され、そして必要に応じてフレームレートの制限までしばらく待機します。 モーションブラーを追加するには、より小さいタイムステップでシーンを複数回描画し、平均のみを表示します:

int n = <number of frames to accumulate>
int i = 0;

while(true) {
  do_time_evolution(timestep / n);
  draw_scene();

  if(i == 0)
    glAccum(GL_LOAD, 1.0 / n);
  else
    glAccum(GL_ACCUM, 1.0 / n);

  i++;

  if(i >= n) {
    i = 0;
    glAccum(GL_RETURN, 1.0);
    glSwapBuffers();
    wait_until_next(timestep);
  }
}

最良の効果が得られるのは多数のフレームを集積するときですが、GPUのパワーによって即座に制限されることになります。 集積するフレームの数を変更可能にできるとベストで、そうでないとひとつのfull  timestep内でどのくらいのフレーム数をレンダリングするかを自動的に決定しようとしてしまいます。

エクササイズ[編集]

  • 前のチュートリアルのいずれかにモーションブラーを追加してみましょう。 もっと面白いものはミニポータルとglescraftで、シーンのあちこちを歩きまわらせることです。
  • シーンに後処理エフェクトを追加する場合は、モーションブラーを適用するのはこれを行う前と後のどちらがよいでしょうか?
  • GPUがアキュムレーションバッファに対応していない場合、テクスチャにレンダリングすることで glAccum() の機能を再現できるでしょうか?