9月2日(金)~9月4日(日)に沖縄本島で開催されたレイトレ合宿8に参加しました。
自作のレンダラーでこんな動画を 10分の制限時間 でレンダリングして5位をいただきました!
レイマーチングとポリゴンをハイブリッドに描画できる単方向パストレーシングのレンダラーをOptiXで開発して16人中7位でした。
— がむ (@gam0022) September 4, 2022
レンダリング時間は10分(1フレーム2秒)だったので、
NEEやMISなどサンプリングの高速化も行いました。
動画は本戦で実際に出力されたファイルです。#レイトレ合宿 pic.twitter.com/LDgKL7gLsY
コロナの影響もあり、3年ぶりのレイトレ合宿でした…!
台風11号がちょうど沖縄に直撃してしまい、天候には恵まれなかったのは残念でしたが、とても充実した合宿でした。
合宿の様子や雰囲気を詳しく知りたい方は、Ki_NaN_komotiさんのブログ記事がオススメです。
2週間ぐらい経ちましたがレイトレ合宿の参加レポートを書きました
— Ki_NaN_komoti (@Kinakomoti2357) September 17, 2022
レンダラー開発記とレイトレ合宿の様子を書いています#レイトレ合宿https://t.co/Fhtvuz9n2H
本戦用のレンダラーの解説
こちらが本戦のプレゼン資料です。
GitHubにリポジトリも公開しています。急いで実装したので品質は低いです。
前回のレイトレ合宿7で開発したRedflashというレンダラーを動画に対応させました。
前回までにこれらの基本的な機能は実装していました。
- 単方向のパストレーシング
- Disney BRDF
- NEE
- MIS
- レイマーチングの衝突判定(OptiXのカスタムプリミティブとして実装)
- ACES Filmic Tone Mapping
- Deep Learning Denoising(ディープラーニングによるデノイザー、OptiXを使えば簡単に利用できる)
今年から静止画部門が廃止されたので、動画部門への対応を行いました。
- アニメーション(シーンの動的な更新)
- 動画のための画像の連番出力
レンダラーの出力設定
出力解像度の高さ・フレーム数の多さは、分かりやすくアピールポイントになるので、ギリギリを攻めました。
- 解像度は1920x1080
- フレーム数は300(30FPS * 10秒)
制限時間は10分(600秒)なので、1フレームあたりの時間は2秒でした。
長さは3秒以上10秒以下
というレギュレーションだったので、上限の10秒にしました。
パストレーシングの場合はゆったりしたアニメーションの方が映えそうなので、60FPSではなく30FPSにしました。 普通のPCのモニターのリフレッシュレートは60Hzだと思うので、24FPSなど中途半端なのは選択肢から除外していました。
PNGの保存(エンコード+ファイル保存)と、レンダリングは別スレッドで並列実行するようにしました。 解像度は2160pにするとPNGのエンコード時間がレンダリングよりもボトルネックになるので1080pを選びました。
前回のレイトレ合宿7の本戦の静止画部門では、1フレームに60秒使えました。 使える時間が30分の1まで急激に短くなったのは大変でした。
さらに実行環境(AWSのEC2インスタンス)も大幅にスペックダウンしていたのも痛手でした。
- p3.16xlarge(レイトレ合宿7)
- g4dn.xlarge(レイトレ合宿8)
g4dn.xlargeではRTコアが使えるようになったようですが、レイマーチングが主なので自分の場合は恩恵があまりありませんでした…
OptiXのバージョンについて
今回は最新のOptiX7でレンダラーを実装しようと思ったのですが、最終的には前回と同じOptiX6で提出しました。
アドベントカレンダーではOptiX7で実装をしていました。
OptiX7ではなぜかポリゴンとレイマーチングのプリミティブを混在するとパフォーマンスが異常に悪化する問題が発生してしまい、これを解決する方法が見つからず、提出まで時間もなかったので諦めてOptiX6を採用しました。
もしパフォーマンスの問題を解決できたとしても、OptiX7はかなり低レイヤーのAPIになっていたので、何かしらのラッパーを開発しないと使うのは大変に思いました。セットアップするだけでもかなり大量のコードの実装が必要でした。
アニメーション要素
10秒の尺に3種類のアニメーション要素を詰め込みました。
- ライトのアニメーション
- レイマーチングのパラメーターのアニメーション
- マテリアルのアニメーション
動画の内容もそれぞれのアニメーションの要素を1つ1つ紹介するような感じにしました。
ライトのアニメーション
2つのポイントライトをアニメーションしました。
OptiX6系では以下のようにmarkDirtyしてからlaunchすることでアクセラレーション構造を更新できました。
light_group->getAcceleration()->markDirty();
light_group->getContext()->launch(0, 0, 0);
top_group_light->getAcceleration()->markDirty();
top_group_light->getContext()->launch(0, 0, 0);
シーン内のプリミティブの数が少ないので、このあたりは工夫しなくてもパフォーマンス上の問題はありませんでした。
NEE用にライトの情報の構造体の配列(ComputeShaderのStructuredBufferのようなもの)を渡しているので、これも毎フレーム更新が必要でした。
レイマーチングのパラメーターのアニメーション
せっかくレイマーチングでフラクタル(Mandelboxの軽量版)を描画しているので、フラクタルのパラメーターをアニメーションさせてみました。
CUDAでtimeを受け取るようにして、timeを元にパラメーターをアニメーションしているだけなので、とても簡単に実装できました。
マテリアルのアニメーション
マテリアルのパラメーターをアニメーション可能にして、ここではEmissiveをアニメーションさせるようにしました。
Emissiveのアニメーションが映えるように、MengerSpongeにしました。平面が多いので光の反射が綺麗に見せられるかなと思ってこうなりました。 roughnessなどひたすら微調整して、最終的に気に入るルックにできました。
実装的にはマテリアルのパラメーターを更新する専用のCallable Program(OptiX用語で関数ポインターのようなもの)を定義しました。
CUDAの関数で好き勝手にアニメーションできるようにしました。
アダプティブなeps
前回のレイトレ合宿に引き続き、今回もアダプティブなeps計算をしています。
カメラからの距離に応じてレイマーチングの衝突判定につかうepsを変化させることで、実質的なLODのようなことをしています。
カメラ距離が変化してもちょうど良い感じのディテールでフラクタルを描画することができました。
デバッグ機能
WASD機能
いい感じのカメラアングルを探るためにWASDでカメラを移動できるようにしました。
余談ですが、Unityのシーンビューの右クリックでも同じようなことができます。Unityでカメラワークを実装するときもこの機能をよく活用しています。
デバッグ用のレンダラー
パストレーシングで描画すると処理が重くてフレーム落ちするのでアニメーションの確認には適しません。
アニメーションをリアルタイムに確認できるように、レンダリングの品質を落としたデバッグ用のレンダラーも実装しました。
AWSの上限緩和申請は早めにやろう
AWSの上限緩和申請(4vCPU)は時間がかかる場合もあるので、提出直前にやるのは良くなかったです。
他の参加者からはすぐに申請が通ったという声も聞いたので、自分だけ担当者ガチャに外れただけの可能性はあります。
AWSの上限緩和申請(4vCPU)、1週間くらいかかったな
— がむ (@gam0022) August 29, 2022
申請: 2022/08/23 1:49
承認: 2022/08/29 10:37
もっと事前にやっておくべきだった…
セミナー資料
レイトレ合宿ではセミナーも行われます。
今年は参加者全員で発表を行ったので、朝から晩までたくさんのセミナーを聞くことができました。
私は「レイマーチングのすすめ」という発表をしました。
過去資料を参照しながら、レイマーチングについて個人的に意外だと感じる部分や、Shadertoyなどで使わているテクニックについて、広く浅く紹介しました。
口頭での説明が前提の発表なので、資料だけでは分かりにくいと思いますが、雰囲気だけでも伝わればと思います。
印象に残った作品
どの作品も工夫があって面白かったのですが、その中でも個人的にかなり印象に残った作品をピックアップしました。
たた (@8picoz) さんがRust 100%のGPUレンダラーを開発していて、前々回のレイトレ合宿までは私もRustを使っていたということもあり、個人的にとても参考にしたいと思いました。 Vulkanのレイトレーシング機能をつかっていて、VulkanではSPIR-Vというシェーダーの中間コードの仕組みが使えるようになっているので、任意の言語でシェーダーを実装できるようになりました。 SPIR-Vをつかうことで、GPUコードもRustで実装をしたそうです。すごい良さそう!
こんな感じの動画をレンダリングして11位でした! #レイトレ合宿 pic.twitter.com/aSEekYHQgr
— たた (@8picoz) September 4, 2022
うしお (@ushiostarfish) さんはNeRFで絵を出していました。 既存の機械学習のライブラリを使わずに、CUDAでスクラッチ実装したとのことだったので、個人的にとても驚きした。 学習のための写真も自分で苦労して撮影したという裏話も聞けて良かったです。
一発ネタのNeRFで、もはやレイトレなのか分からなくなってきましたが、思いのほか反響があってよかったです!
— うしお (@ushiostarfish) September 9, 2022
実装と解説スライドなどこちらにありますhttps://t.co/YdeNXrIYBF
運営の皆さま、今年も大変お疲れ様でございました!大変充実したイベントをありがとうございました!#レイトレ合宿
Shocker (@Shocker_0x15) さんのNeural Radiance Cachingをボリュームに適用して高速化をしていました。 他の参加者と差別化できていて、結果も綺麗ですごいと思いました。機械学習の波がレイトレ合宿にも来ているのを感じました。
3年ぶりの #レイトレ合宿 8でMulti-scatteringな雲の動画をレンダリングして1位を頂きました!
— Shocker (@Shocker_0x15) September 4, 2022
普通にやると重すぎて間に合わないのでNeural Radiance Cachingをボリュームに適用して高速化しました。
レンダラー紹介スライドhttps://t.co/ry4W70XcgI pic.twitter.com/82OFf5rYue
hole (@h013) はゴールベースコースティクスを実装していました。分散の発生する処理がほとんどなく、Deterministicに結果が決まるそうで、ノイズがまったくないめちゃくちゃ綺麗な結果でした。 他の参加者と違うアプローチで差別化ができていて、結果もめちゃくちゃ綺麗でいいなと思いました。
レイトレ合宿終わりました。皆さんありがとうござました!
— hole (@h013) September 4, 2022
僕はコースティクスを実装し、こんな感じの動画をレンダリングして4位でした。
#レイトレ合宿 pic.twitter.com/NbHutC9KtB
Shinji Ogaki (@ShinjiOgaki) さんはCPUレンダラーかつデノイズしないという条件で、ノイズがまったくない綺麗な絵を出していて、圧倒的な実装力の違いを見せつけられました。強者の風格をとても感じる作品でした。
記事はまる一日で3000くらい閲覧があったようなので、合宿に興味がある人が多いのかも?
— Shinji Ogaki (@ShinjiOgaki) September 5, 2022
せっかくなので、少し尺の長い動画を載せておきます。#レイトレ合宿 #generative #creativecoding #processing pic.twitter.com/RqMLxaUIMX
感想
年々と制限時間が短くなっているのに、ほとんどの参加者はノイズのない綺麗なレンダリング結果を出していて、参加者のレベルがどんどんインフレしているのを感じました。
もはやノイズの少ない絵を出すだけでは差別化が難しいので、それぞれの参加者がユニークな切り口で勝負してくるハイレベルな戦いでした。
今年のセミナーは参加者全員で発表しました。参加者のバックグラウンドもさまざまだったので、いろんな分野の興味深い話や深い話を聞くことができて楽しかったです。
レイトレ合宿の運営の方々、その他の参加者のみなさん、本当にありがとうございました!
写真コーナー
天候には恵まれませんでしたが、ホテルがめちゃくちゃ豪華だったり、美味しいご飯を食べたりして沖縄を満喫しました。
写真から雰囲気が少しでも伝われば幸いです。
ホテルは棟ごと貸し切りをしました!まるでレンダリング用のシーンのようにピカピカなお部屋でした!すごい!
沖縄の料理なども堪能しました。合宿自体は2泊でしたが、個人的に延泊して4泊したので料理の写真が多くなっています。