2023年4月24日月曜日

Flustum Culling 影考慮版

視錐台カリングを以前作ったけど、不具合があることに気がついた。

オブジェクトのカリングと影の描画が連動しているため、カリングされてしまうと影の描画も無条件でやめてしまう。
影の位置が離れている場合や長く伸びている場合、オブジェクトの描画をやめても影の描画はしないといけない場合もある。

影の描画がなくなっている

正しい描画

アンリアルエンジンのサイトでオブジェクトをカリングした状態でも影描画している様に見えた。影はカリングに関係なく無条件に描けばいいのか?

とりあえずその実装をしてみることにしたが、単純にはできなさそう。
現状メッシュ描画の際、オブジェクトのインスタンス単位にWorld Matrixのバッファを用意して、バッファの個数をDrawIndexedInstancedのインスタンス数に指定することで描画している。カリングされなかったものだけバッファを詰めて、インスタンス数を減らして指定する。
このため、単純に影用のバッファを含めてしまうとカリングもできなくなってしまう。

そこで考えたのが、バッファを2重にする方法。
カリングされないバッファの後ろにカリングされた影描画分を詰める。
影描画は全体の数を使って描画し、それ以外はカリングされていない数を使って描画する。
これにより1つのバッファでカリングと全体描画が出来るようになった。

出来るようにはなったけど、これだとパフォーマンスの問題が残る。
広いエリアで全オブジェクトの影描画が行われるとまずいだろう。

視錐台カリングの影考慮を検索してもなかなかヒットしなかったが、いろいろ試していく中で1つ有力な、目からウロコの情報が手に入った。
現状、メインカメラで視錐台カリングを行っているが、影描画用のライトをカメラに見立てて、その視錐台でカリングを行うというアイディア。
全然情報が出てこなかったけど、実は常識?


カスケードシャドウ対応視錐台カリング


カスケードシャドウを行う際、カスケード数分視錐台を準備している。
この視錐台をそのまま視錐台カリング処理に流し込めば、影描画の範囲を絞り込める。
また、カスケード数が4だとして、4回影描画を行うことになるがそれも狭い範囲から段々と数を変えて描画出来るようにする。

左がメインカメラ 右がサブカメラで上からの視点

まず、メインカメラの視錐台でカリングを行う。この結果をほとんどの描画では利用する。
次にカスケードシャドウ用の視錐台を範囲の狭い方から含まれるオブジェクトのチェックを行う。チェックの対象はメインカメラでカリングされたものだけ。
手前から赤、黄緑、青、黄色と影の範囲が広くなっていく。
それぞれの範囲内に含まれるオブジェクトにカリングレベルを設定していく。

影描画の際、今までは全部のカスケードレベルで同数のメッシュ描画を行っていたけど、カリングレベルを使って、その範囲に含まれるメッシュだけを描画するようカスケードシャドウ自体のパフォーマンスにも考慮させた。

左上の3✕3の物体と影

メインカメラで物体はカリングされても、影は残っている





0 件のコメント:

コメントを投稿