Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
8
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

@y_UM4

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

 やることは非常に単純で、シェーダー側(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とか)も今まで通り使えるはず。

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
8
Help us understand the problem. What are the problem?