2024年6月28日金曜日

MotionBuilder のFrameBufferObject

 MotionBuilderのCustomRenderのプラグインを利用して、ポストプロセス処理でレンズの歪曲収差の効果をつけたいと考え、OpenGLやGLSLシェーダー、MotionBuilderのレンダリングパイプラインを勉強、調査をしました。

その時に知りえたことを備忘録的にメモとして残します。

一般的なOpenGLとGLSLシェーダーを利用して歪曲収差を実現するときのメモ

  1. OpenGLはステートマシンなので状態を切り替えて処理をするため、コードを書く順番が大事なのと、今アクティブな状態は何かを把握しながらコードを書く必要がある
  2. ポストプロセスとして歪曲収差を実現する処理イメージ
    1. 自分で作ったFBOを作成
    2. そのFBOにColorBufferをアタッチ
    3. ポリゴンを描画
    4. 別のFBO(通常はデフォルトのFBO)に戻す
    5. 画面を覆う4角形ポリゴンを作成
    6. 1で描画したものをテクスチャーとして張り付け
    7. 歪曲収差のGLSLシェーダーを利用してFBOに描画
    8. FrontBufferとBackBufferをSwap
  3. VertexShaderとFragmentShaderがあり、FragmentShaderで2D的な処理を行う
  4. レンズの歪曲収差はBrown-Conrady Lens Distortionとかで調べると、お決まりの数式がある
  5. その数式にある係数をかえることで、レンズ特有な歪みを表現できるようす

MotinBuilderのレンダリングパイプラインについてのメモ

  1. MotionBuilderは独自のFBOをもっている。つまり、DefaultのFBOに描画はしていない
  2. FrontBufferとBackBufferのスワップはMoBuが行うので明示的に実行する必要がない
  3. MoBuがスワップを行うので、ポストプロセス処理したFBOのColorBufferをMotionBuilderの独自のFBOへBlit(コピー)する必要がある
MB独自のFBOを持っているので、レンダリング処理の最初に以下のコードでFBOを取得し、いろいろポストプロセス処理を行い最後に取得したMB独自のFBOへBlit(コピー)します。
以下に疑似コードをメモ。

//MBのFBO取得
GLint currentFBO;
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &currentFBO);

//FBO1にシーンのポリゴンを描画
//画面を覆う四角ポリゴン作成し、描画した内容をテクスチャーとして張り付ける
//GLSLシェーダーを使い四角ポリゴンをFBO2へ描画 
//具体的なコードは省略


//MBのFBOへFBO2のColorをBlitする
glBindFramebuffer(GL_READ_FRAMEBUFFER, FBO2);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, currentFBO);
glBlitFramebuffer(
    x, y, width, height, // コピー元の範囲
    x, y, width, height, // コピー先の範囲
    GL_COLOR_BUFFER_BIT, // ブリットするバッファ
    GL_NEAREST // 補間方式
);