😵‍💫

ステレオレンダリングについて調べる

2023/04/30に公開

XRデバイス用のレンダリング方法であること以外ほとんど理解できてなかったので調べてみました。備忘録的な記事です🙇

参考にした記事は以下の通りです。
https://blog.unity.com/ja/technology/how-to-maximize-ar-and-vr-performance-with-advanced-stereo-rendering
https://tips.hecomi.com/entry/2018/11/04/232219

そもそもXRデバイスのレンダリングについて,,,

XRレンダリングは二つの目に合わせて一つずつレンダリングする必要がある。
つまり、合計2つのビューをレンダリングするので負荷が高くなる傾向があります。

マルチカメラ

二つの目に対応したUnityのCameraが用意されており、別々にシーンをレンダリングして重ね合わせる。グラフィックパイプラインをその分(2つ)用意する。XR初期のレンダリング手法。

マルチパス

二つのレンダリングパイプラインの共通項であるシャドウレンダリングとカリング処理を共通にすることで処理負荷を軽減させる。ここでいうカリングとは視錐台カリングのことです。
シャドウレンダリングはシャドウカスケードマップが生成されて、シャドウマップがスクリーン空間にマッピングされるので、カメラの位置に依存しないため共通化することができる。
カリングは一見Cameraが二つなので視錐台も二つあって共通化することが難しそうに思えます。
ただ、参考にした記事によると、カメラ位置を後ろに下げてサイズを少し大きくした視錐台を用意すると違和感がほとんどなく共通化できるそうです。理屈はあまりわかってないです。(https://www.facebook.com/photo.php?fbid=10154006919426632&set=a.46932936631.70217.703211631&type=3)

シングルパス

二つのレンダリングパイプラインを一つにしようという大胆?な改善案。
二つのターゲットをレンダリングする代わりに2倍幅のレンダリングをする、つまり二つのCameraのレンダリング領域をまとめることでパイプラインを一つにすることを可能にしました。
この手法がなぜ許されるかというと、ビューポート空間をスイッチしているからです。
マルチカメラでのレンダリングだとレンダリングターゲットを目ごとに切り替えていたところを目ごとにビューポート空間を切り替えることでパフォーマンスコストを抑えることに成功したということです。
とはいえ、ビューポートの切り替えもCPU,GPUコストがそれなりにかかるので決して最適解というわけではないそうです。

シングルパスインスタンシングレンダリング

おそらくGPUインスタンシングとシングルパスの合わせ技?だと解釈。
シングルパスはビューポートの切り替えをするたびに、同じものをレンダリングするのに余計にドロコールをしてしまいます。ドローコールを減らしたいという課題で効果を発揮するのはGPUインスタンシングです。GPUインスタンシングをどう異なるビューポートで実現しているのはVPAndRTArrayIndexFromAnyShaderFeedingRasterizer というDX11のAPIです。これは、ビューポートの配列とレンダーターゲットの配列を頂点シェーダーで使用することができるようになります。(なぜ使用できるようになるのかは理解が追いついていないです。)

シングルパスマルチビュー

おそらく解決したい課題はシングルパスインスタンシングと同じで、ビューポートの切り替えのたびに発生するドローコールをどう最適化するかだと思います。
OpenGLの拡張機能であるマルチビューを利用しドロコールを一回に抑えて実行できます。Unity側ではシングルパスインスタングとは区別せず抽象化して同様の実装でできるようにしてくれているみたいです。(おそらく)

パフォーマンス数値(参考記事より)

記事内でも触れられている通りシングルパスとシングルパスインスタンシングの数値は大きくは変わらないみたいです。

Discussion