shuto_log.aep

自分がやったことなどを備忘録的な感じで残していこうと思います。

レイトレ合宿6 参加レポート

レイトレ合宿6に参加してきました。

レイトレ合宿とは、自作のレンダラを持ち寄って画像の美しさを競うイベントで、自分は今回が初参加でした。

C++でパストレレンダラを書いて、こんな感じの画像を出力しました。 f:id:shutosg:20180904010902p:plain ※サンプル数を多めに取ってるので、実際の競技結果よりも少し綺麗です

結果は 19人中14位 と、C++自体もほぼ未経験だったためビリも覚悟していたのですが、そこそこ奮闘できたようです。

↑後日、順位に誤りがあって14位タイになりました

どうやら10位以内だと入賞扱いになるようなので、来年は入賞目指して頑張っていきたいと思います。

また、合宿には Arnold RendererRadeon ProRenderグランツーリスモの内製レンダラなどといった本職でもレンダラを開発されている方々や、CG技術書を執筆されている方、CGを専攻している学生さんなど、非常にレベルの高い方が多く参加されており、大変刺激的な時間を過ごすことができました。

今年は会話についていくのが精一杯だったので、来年はディスカッションできるように知識を増やしておこうと思います。

[目次]

レンダラについて

レイトレ合宿では、自作レンダラについてプレゼンする時間が設けられており、以下は発表で使用したスライドに修正を加えたものです。

基本的には はじめようレイトレーシング をもとに Processingで書いたレンダラC++に移植したものをベースに、追加でいくつかの機能を付け足していきました。はじレイレイトレーシングの基礎的な概念からパストレーシングの実装まで、イラストをふんだんに用いて非常に分かりやすく図解されており、入門にオススメです。

Processingは煩雑な記述なしにグラフィカルなプログラミングができ、プロトタイピングには向いていますが、実行速度などの問題からレイトレをするには限界があります。コミュニティや情報量の多さを鑑みても、レイトレをするにはC++が一般的なようです。(最近Rustという言語で書かれる方もそれなりに見受けられますが)

以上のような理由から、練習も兼ねてC++でレンダラを書くことにしました。なお、C++の入門には ロベールのC++入門講座第9版 を用いました。結構な量があるので今回は1週間ほどかけて第8章(全体の半分くらい)まで読んで基本的な文法や構文、ポインター、参照、class、継承、オーバーライド、演算子オーバーロードなどを学び、実装に移りました。テンプレートやスマートポインタは今後学んでいこうと思います。

レンダラの概要

コアな機能としては、一様分布乱数を用いた準モンテカルロパストレーシング薄レンズモデルの被写界深度対応 が挙げられます。

その他機能に関しては以下のとおりです。

  • プリミティブの描画
    • 球、ディスク、無限平面
    • カメラから見えないオプション
      • 絵作り用、反射マテリアルへの映り込みオブジェクトとして使える
      • オプションが有効の場合、プライマリレイ(depth == 0)のみ必ず、交差判定を行わないことで実現
  • ポリゴンメッシュの読み込み
    • objファイルの読み込みに対応(三角形ポリゴンのみ、頂点情報のみ)
  • マテリアル
    • Lambert拡散反射、完全鏡面反射、スネルの法則による屈折
    • 発光チャンネル
  • Cube Map IBL

高速化について

  1. BVHの構築による、ポリゴンメッシュ交差判定高速化
  2. OpenMPを用いた並列処理
  3. Lambert拡散反射のcosine weighted samplingによる収束の高速化

などを行いました。以下で詳細を説明します。

SAHによるBVHの構築、無駄な交差判定を削減

BVHを実装しない場合、ポリゴンメッシュを描画する際に、総当たりでポリゴンとレイの交差判定を行わなければならず、非常に多くの時間が費やされてしまいます。自分の場合はこれを実装したところ、レンダリング時間が約5倍速くなり、実装コストを鑑みても効果は絶大だと感じました。

  • SAHという手法を用いて分割
  • ただし、一部パラメータは適当な値を用いた
  • お餅さんのQiitaを参考に。非常に丁寧に解説されていています。

qiita.com

qiita.com

OpenMPによる並列処理

OpenMPに対応しているコンパイラであればコンパイルオプションの追加とディレクティブの追記だけで簡単に並列処理が可能です。パストレの場合、画素ごとで完全に独立した処理である事が多いので、それぞれ異なるスレッドで並列的に計算させたほうが効率的にCPUリソースを使うことができます。

  • 画素の行ごとに異なるスレッドを割り当てて並列化した
    • レイトレ合宿三連覇の Shockerさん によると、単なる行ごとのスレッディングよりもブロック状に分割された領域ごとのスレッディングの方がテクスチャのメモリヒット率が高く効果的だそうです
  • Windows環境ではOSの制約によって本番環境の72論理コアを活かすことができず*1、CPU使用率50%での実行となった
  • これはOSの問題なので、Windows用にコンパイルすると Rustでも同様の現象 だったらしい

Lambert拡散反射のcosine weighted sampling

モンテカルロパストレーシングの最大の デメリット とも言える「サンプルの分散の収束の遅さ」ですが、有用性の高い光経路を重点的にサンプリングすることで、より少ないサンプル数でこの分散を収束させることができ、このテクニックを importance sampling といいます。Lambert拡散反射のimportance samplingで比較的簡易的に実装できるものとして、BRDFのcos項に比例したサンプリングを行う cosine weighted sampling という手法があり、今回はこちらを実装しました。

具体的には 反射面の法線方向に近い光線を重点的にサンプリングすることで収束を早める ということなのですが、解説記事としては 竹重さんの記事 が非常に丁寧で、導出過程含めて解説されています。

レンダラ振り返り

他にもGGXのような曇った鏡面反射だったり光の分散(プリズム効果)のような特殊な表現もやってみたかったのですが、今回は時間がなく見送りました。やりたかったことはスライドに記載したとおり、いっぱいあるので今後もちまちまと実装を続けていきたいです。

githubにはこちらのリポジトリにて公開しています。C++を学んで10日ほどの初心者な実装なので、色々と問題有りそうなのはご承知おきください。

github.com

合宿について

レンダラを実装する以外にもレイトレ合宿には魅力がたくさんあります。ここからはレイトレ合宿の魅力的なコンテンツを紹介していきたいと思います。

  1. 神津島大自然
  2. シークレットイベント
  3. セミナー

神津島大自然

今年は伊豆諸島、神津島で開催されました。普段デスクワークで座ってばかりなので、たまには大自然(今回は主に海)に囲まれるのも良いですね。神津島はとにかく海が綺麗でした。

f:id:shutosg:20180906005212p:plain

f:id:shutosg:20180906005800p:plain

f:id:shutosg:20180906005839p:plain

来年はどなたか海をレンダリングするんでしょうかね。

シークレットイベント

シークレットイベントと称して、抜き打ちレイトレ検定と三葉レイちゃんの応援動画が用意されていました。

レイトレ検定

1つめのシークレットイベントとして、抜き打ちでレイトレ検定が開催されました!

自分は100点満点中64点、ビリから3番目だったので、しっかり復習をしておこうと思います。。

↑サンプリング目利きは全問正解者はいなかったようです。

三葉レイちゃんの応援動画

2つめのシークレットイベントはなんと三葉レイちゃんからの「レイトレ合宿応援動画」でした!

ただひたすらにレイトレ合宿を「すごい!」と褒め称えてくれる動画でした(笑) f:id:shutosg:20180906012518p:plain:w300f:id:shutosg:20180906012527p:plain:w300 f:id:shutosg:20180906012536p:plain:w300f:id:shutosg:20180906012544p:plain:w300

なお、三葉レイちゃんは技術系VTuberで、唐突にVisualStudioを開いてレイトレを始める動画や、ソフトウェアラスタライザを作る動画を投稿しています。

レイトレの動画に関しては今回自分もC++でレイトレをするにあたって、肌感を掴むのに最適でしたのでオススメです!


【レイトレ】CG技術系バーチャルYoutuber、レイトレーシングしてみた

セミナー

セミナーはZinさんによる「実装してきたこと、これからやってみたいこと」と、ishiyamaさんによる「『Volume Rendering 方程式から大気散乱モデルを導く』の詳細」でした。

Zinさんの方は、複数のトピックからなるお話で、

  • Blenderで作成したシーンの情報をJSON形式で出力して自作レンダラで読み込む話
  • レンダラ開発におけるテストについての話
  • 最近発表された気になる論文についての話

などでした。気になるトピックが多く、後ほど資料も公開されるそうなので、いろいろと参考にさせていただきたいと思いまず。

ishiyamaさんの方はアドベントカレンダーの内容を補足するような講義でした。かなりガッツリとVolume Renderingの話に突っ込んでいたので、非常にレベルが高かったです。講義を聞きながらは理解が追いつかなかったので、資料が公開されたらじっくり読んで来年までには理解できるようにしたいです…!

合宿まとめと今後について

初めての参加となったレイトレ合宿でしたが、皆さんとてもレイトレを始めとしたグラフィック技術に強い方が多く、とても刺激的で有意義な時間となりました。運営メンバーの方々、誘ってくださったPheemaさん、本当にありがとうございました!

今回書いたレンダラは初めてのC++だったこともあって無限に改善点があるので、継続的に直していくか新しいリポジトリで作り直して行こうと思います。

*1:Windowsではマシンに搭載されている論理コア数が64を超えると、論理コアをプロセッサグループという仮想的なグループに分割します。本番環境は72論理コアだったので36論理コアのCPUグループ2つに分割されました。プロセッサグループを跨いで安定した並列処理をさせるのは難易度が高く、手元で行ったテストでは 1つのプロセッサグループを使った36スレッド並列処理のCPU使用率50% が最もハイパフォーマンスでした。Linuxであれば問題なく72論理コアをフルに使えたようです。