Help us understand the problem. What is going on with this article?

RaymarchingとGeometryを同一シーンにレンダーする

More than 1 year has passed since last update.

 やることは非常に単純で、シェーダー側(gl_FragDepth)でデプスを更新することである。

ModernOpenGL-AdventCal2017/21-render_raymarching_and_geometory_at_the_same_time

Feature

  • GBuffer生成し、1パス目でGeometryをレンダーし、2パス目でRaymarchingをレンダーする
  • 2パス目のRaymarchingで、1パス目と同じカメラ情報で、rayを定義する
  • rayの衝突判定からシーンの深度を構築し、その値でgl_FragDepthを更新する

GBuffer生成

GBufferは、特に変な設定はしない。
位置、法線、色(アルベド)をカラーバッファ、デプスバッファをレンダーバッファとして生成する。(ofFboではデフォルトで、レンダーバッファがデプスバッファになる)

    vector<GLint> formats = { GL_RGBA16F, GL_RGBA16F, GL_RGBA16F };
    ofFbo::Settings settings;
    settings.width = WIDTH;
    settings.height = HEIGHT;
    settings.textureTarget = GL_TEXTURE_2D;
    settings.wrapModeHorizontal = GL_CLAMP_TO_EDGE;
    settings.wrapModeVertical = GL_CLAMP_TO_EDGE;
    settings.minFilter = GL_NEAREST;
    settings.maxFilter = GL_NEAREST;
    settings.numColorbuffers = 3;
    settings.colorFormats = formats;
    settings.numSamples = 4;
    settings.useDepth = true;
    settings.useStencil = true;

    g_buffer.allocate(settings);
    g_buffer.checkStatus();

1パス目でジオメトリを普通にMRT

 1パス目のポリゴンのGBufferへのレンダリング。ここでも、特別なことは何にもしていない。
source

2パス目でRaymarchingのシーンを書き込む

 ここで重要なのは2つ
* 1パス目と同じカメラ情報で、rayを定義すること
* rayの衝突判定からシーンの深度を構築し、その値でgl_FragDepthを更新すること

 深度を更新しないと、適切な前後関係で、シーンがレンダーされない
しかし、RayMarchingは、ただの板ポリにfragment shaderで描画しているだけなので、深度値はつねに1である。
そのため自前で、Rayの衝突位置から深度値を計算する必要がある。
source

この深度値で、gl_FragDepthを更新する。

 2パス目ではglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);をせず、GBufferにレンダーする。
source

これで、RayMarchingとofBoxPrimitiveが共存するGBufferができる。

8月-24-2017 14-40-35.gif
GBufferの中身。正しい前後関係でレンダリングされていることが確認できる。

後はライティングを行う

 ここまでくると、後は一般的な遅延シェーディング処理を行うだけ。
8月-24-2017 13-50-24.gif

最終レンダリング結果 | 緑のSphereは、Raymarching。赤のCubeは、ofBoxPrimitive。
ライティングが一貫しているのが確認できる。

まとめ

 このテクニックを利用すれば、キャラクターアニメーションの後ろで、
フラクタルやトンネルがバキバキ動いているという複雑なシーンをレンダーすることができる。
 GBufferが生成できたので、スクリーンスペース系のテクニック(SSAOとか, SSRとか)も今まで通り使えるはず。

y_UM4
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした