4.8K Views
November 27, 23
スライド概要
■概要
物理ベース手法として知られているカメラを構成するレンズ群に対して光線追跡を行いゴーストの変形をシミュレートする方法に取り組みました。
その際の計算内容や、取り組んだ最適化、描画画面外に光源がある場合の対処などについてお話いたします。
※CAPCOM Open Conference Professional RE:2023 で公開された動画を一部改変してスライド化しております。
■想定スキル
Ray tracing周りの知識がある、もしくは実装経験がある方
詳細は下記公式サイトをご確認ください。
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
CAPCOM Open Conference Professional RE:2023
https://www.capcom-games.com/coc/2023/
カプコンR&Dの最新情報は公式Twitterをチェック!
https://twitter.com/capcom_randd
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
株式会社カプコンが誇るゲームエンジン「RE ENGINE」を開発している技術研究統括によるカプコン公式アカウントです。 これまでの技術カンファレンスなどで行った講演資料を公開しています。 【CAPCOM オープンカンファレンス プロフェッショナル RE:2023】 https://www.capcom-games.com/coc/2023/ 【CAPCOM オープンカンファレンス RE:2022】 https://www.capcom.co.jp/RE2022/ 【CAPCOM オープンカンファレンス RE:2019】 http://www.capcom.co.jp/RE2019/
Ray Tracing Lens Flare では、レイトレーシングを用いたレンズフレアについてお話いたします。 ©CAPCOM 1
アジェンダ [導入] • レンズフレアとは • カメラの簡単な構造 • 処理内容の概要 [光源遮蔽処理] • 画面外に光源がある場合の対応 [描画時の問題と緩和策] • ゴーストの分離現象 [光線追跡] • レンズ群の単純図形としての表現 • 単純な幾何問題としての光線追跡/強度評価 [光波計算] • 回折パターンの計算 • 前玉のゴミ・傷効果の反映 [高速化のための工夫] • 描画に寄与しない光線の除外 • パフォーマンスの変化 [まとめと展望] 本日のアジェンダがこちらです。 まず、レンズフレアとは何かについて簡単にお話しします。 次に、従来の表現方法を紹介した後、カメラの基本構造などについて説明いたします。 2 レンズフレアを実現するための処理といたしましてカメラ内での光線追跡と、 その周辺処理、光波の計算についてお話いたします。 そのあと、遮蔽処理や問題点とその緩和方法、高速化のための取り組みについて触れ、まとめといたします。 ©CAPCOM 2
導入: レンズフレアとは 以下は全て実装したものの出力 スターバースト ゴースト拡大 捻り ゴースト • 高輝度部分が主に画角に入ることで生じる光学現象 • 主に「スターバースト(回折フレア)」と「ゴースト」で構成 • 特にゴーストは複雑な変形を見せるものが存在 ではまず導入といたしましてレンズフレアの説明を行います。 示しているのは実装した結果です。 レンズフレアは高輝度な光源がカメラの画角に入ることによって主に生じる光学現象であり、 ゲームでは画面を印象的に演出するために用いられるエフェクトです。 3 主に光源位置に発生する星形のスターバーストと、 光源と画面中心を結ぶ直線上に整列して生じる多角形状のゴーストに分けられます。 ゴーストは多角形状に見えることもあれば、ひねった図形のように複雑なものも存在します。 ©CAPCOM 3
導入: 従来 [スプライトベース] • 光源と画面中心を通る直線上に画像を配置 • 画像を配置するだけなのでゴーストは変形不可 • 位置・形状・色はアーティスト依存 スプライトベース [イメージベース] • 再帰的に画像をスケーリング・合成 • 光源の移動に応じたゴーストの変形は困難 • アーティストへの依存性が大 • 尤もらしいゴーストの非線形な変化の表現が困難 従来、この表現をするために様々な手法が提案されてきました。ここではその一部に触れます。 まずは、スプライトベースです。 こちらは、光源と画面中心を結ぶ直線上に画像を連続的に配置していくものです。 4 そのため、ゴーストに複雑な変形は基本的にみられず位置などはアーティストに依存します。 次に、イメージベースです。こちらは再帰的に画像のスケーリングを行うことによって、 多数の光源が画面内にあっても一定のコストで処理が行えるものです。 しかし、やはりこちらも複雑なゴーストの自然な変形は難しい点があります。 ©CAPCOM 4
導入: 物理ベース手法 [物理ベース] • 稠密なグリッドを構成し,光線追跡と補間によって実現する手法[1] • 複雑な変形を伴い,画質良好 • 事前計算,ゴースト毎90光線方向 × (64 × 64)光線 × 20ズーム倍率 × 8Fストップ等 • 1ゴースト当たり128 × 128グリッドで実行 この見た目が再現できればアーティストの表現の幅を広げられる →こちらでも光線追跡してみよう(事前計算なし) 尤もらしいレンズフレアを表現するための 反射率/明るさ/スターバースト/ゴースト計算部分や高速化などを考えた 物理ベースなものとして、稠密なグリッドの光線追跡を行うことで 複雑な変形を伴って尤もらしい振る舞いをするものが提案されています。 事前計算が多く実行時もそれなりに稠密なグリッドを用いるため、基本的に高負荷なものとなっています。 5 しかし論文内で紹介されているレンズフレアは見た目が非常に良く、 再現することでアーティストの表現の幅を広げられると考えました。 そこで弊社も光線追跡を行うことにしました。 その際スターバーストやゴーストの見た目が尤もらしいレンズフレアを表現するための計算や、生じる問題への対処をしました。 他にも実用的な速さで動作させるための高速化などを考えましたのでそれについて共有いたします。 ©CAPCOM 5
導入: カメラの簡単な構造 絞り羽根 レンズ センサ • 複数のレンズと,絞り羽根.受光するセンサ • 絞り羽根で光量を調節 • レンズフレアのシミュレーションは,この構造内での光線追跡と光波分布の計算によって実行 まず最初に、想定するカメラの構造を紹介します。 カメラの内部は主に、複数のレンズと光量を調節する絞り羽根、そして、受光するセンサ素子で構成されています。 6 レンズフレアは光がこれら構造内に突入し、センサに到達することにより生じるので、 この構造内における光線追跡と、生じる光波分布のシミュレートで実現します。 ©CAPCOM 6
導入: 処理内容の概要 ①光線追跡 ②光波分布画像生成 マスク 入力 ③光波分布画像マッピング スター ゴースト バースト 出力 • 前玉(最前面のむき出しのレンズ)側にグリッドを配置/光線を射出しレンズ群に突入 →センサ面での歪んだグリッドを計算 • 光線追跡時に,各光線の強度/絞り羽根通過位置などを記録 • 絞り羽根の形状に依存したスターバースト/ゴースト画像を生成 • グリッドの位置に生成した画像をマッピング 詳細な説明を行う前に、本レンズフレアの大まかな流れを示しておきます。 まず、1番のように前玉と呼ばれる最前面のむき出しのレンズ側に等間隔グリッドを生成し、 各格子点からカメラに向かって光線を射出する操作により、センサ上で歪んだグリッドを得ます。 7 また、光線追跡時には各光線の強度や絞り羽根上での通過位置を記録します。 次に、2番のように絞り羽根を模したマスク画像からスターバースト/ゴーストの画像を生成します。 その後、3番のように先ほど得た通過位置を参考に強度などを反映しながら、 歪んだグリッド上にマッピングを行いレンダリングを完了します。 本発表では主に、光線追跡/光波分布画像生成/光波分布画像マッピングに焦点を当てて解説を行います。 ©CAPCOM 7
現在位置 光線追跡 光波分布画像生成 光波分布画像マッピング では、光線追跡部分の説明に移ります。 8 ©CAPCOM 8
光線追跡: レンズの単純図形としての表現 レンズ(側面) 𝒓 光軸 レンズ (正面) 両凹 平凸 両凸 平面 𝒉 球面 𝒓 𝒉 𝒉 • レンズは平面と球面の組み合わせで表現可能 • 平面 or 球面(レンズ) vs 直線(光線)の交差判定の反復処理が,光線追跡の主な処理 • 単純な方程式を解くだけなので,BVHなど用意せずCompute Shaderで実行可能 レンズに対しての光線追跡なので、ここではどう簡単にレンズを表現するかを考えます。 例えば画面左上のように、平凸レンズを横から観察すると、平面と球面で構成されていることが容易にわかります。 9 これは他の凹レンズや凸レンズについても同様で、 画面右上のように基本的にレンズは「平面」と「球面」の組み合わせで表現できます。 従って、光線を表す「直線」と「平面」または「球面」の交差判定の繰り返しが、 レンズフレアにおける光線追跡になります。 この交差判定は単純に方程式を解くだけなので、BVHなどは用意せずにCompute Shaderで簡単に実行できます。 ©CAPCOM 9
光線追跡: レンズデータの解釈 番号 曲率半径 次の表面までの距離 0 𝑟0 = ∞ 𝑑0 1 𝑟1 < 0 𝑑1 2 𝑟2 > 0 𝑑2 … … … 𝑟>0 No.0 𝑟2 𝑟1 𝑧 𝑧=0 𝑧 • • • • No.2 𝑧 = 𝑑0 + 𝑑1 𝑟=∞ 𝑟<0 No.1 𝑧 = 𝑑0 + 𝑟1 𝑑0 𝑑1 𝑑2 𝑧 = 𝑑0 + 𝑑1 + 𝑟2 𝑟<0 光線追跡のためには,平面/球面の集合にすることが必要 レンズのデータには,その曲率半径や次の表面までの距離などが掲載 曲率半径の正負で凸な向き.表面要素間距離で位置を計算 番号1であれば,中心は𝑧 = 𝑑0 + 𝑟1 (𝑧 = 𝑑0 より左に中心) レンズの情報は、ネットで調べて得られるレンズのテーブルに記載されています。 そこには、画面左上のように各表面要素における曲率半径と次の表面への距離が記載されています。 光線追跡のために、この情報を平面と球面の集合に解釈しなおす必要がありますので、 それについて考えます。 10 まず、今画面向かって右向きを正の方向とします。すると、 曲率半径の正負によってどちらに向かって表面が凸になっているかを知ることができます。 今回の場合は、先ほどのテーブルの下のように曲率半径が正であれば向かって左向きに凸、 負であれば向かって右向きに凸な球面になります。 ©CAPCOM 10
光線追跡: レンズデータの解釈 番号 曲率半径 次の表面までの距離 0 𝑟0 = ∞ 𝑑0 1 𝑟1 < 0 𝑑1 2 𝑟2 > 0 𝑑2 … … … 𝑟>0 No.0 𝑟2 𝑟1 𝑧 𝑧=0 𝑧 • • • • No.2 𝑧 = 𝑑0 + 𝑑1 𝑟=∞ 𝑟<0 No.1 𝑧 = 𝑑0 + 𝑟1 𝑑0 𝑑1 𝑑2 𝑧 = 𝑑0 + 𝑑1 + 𝑟2 𝑟<0 光線追跡のためには,平面/球面の集合にすることが必要 レンズのデータには,その曲率半径や次の表面までの距離などが掲載 曲率半径の正負で凸な向き.表面要素間距離で位置を計算 番号1であれば,中心は𝑧 = 𝑑0 + 𝑟1 (𝑧 = 𝑑0 より左に中心) また、平面の場合は何も書かれていないか∞と書かれています。 そして、テーブルに記載された曲率半径と次の表面までの距離を使えば、 計算に必要な平面/球面の位置が分かります。 11 今、画面右上のように最初の表面要素の位置を𝑧 = 0としましょう。 すると番号0であれば曲率半径が無限大なので単純にその場に平面を作ります。 番号1であれば、番号0から𝑑0 進んだ位置に球面の端が来ることになるので、 𝑧 = 𝑑0 + 𝑟1 にその中心を持つことになります。 その時の球面は𝑟1 が負であることから、中心を𝑧 = 𝑑0 から見て左に持ちます。 このような計算を繰り返して、球面と平面の集合としてカメラのレンズ群を定義します。 ©CAPCOM 11
光線追跡: 想定する反射回数 反射 反射 絞り羽根 • • • • ゴーストは表面での反射成分.反射率は微小 偶数回反射した成分がセンサに到達 あらゆる表面要素での反射を考慮すると計算が膨大→2回反射のみ想定 表面要素𝑛個なら,ゴーストは 𝑛𝐶2 個発生 光線を追跡する対象を簡単な図形の集合にできたので、光線追跡でどういった経路を使うかを考えます。 ゴーストは、表面での微弱な反射成分であり、偶数回反射したもののみがセンサに到達して現れます。 12 では、偶数回反射するあらゆる光線を想定するかといえば計算が膨大になるため到底できません。 そこで、反射率が小さいことを用いて、表面要素の中から2つだけ反射面を選択し、 その他の表面要素では屈折する経路を想定します。 考える表面要素を𝑛個とした場合に生じるゴーストの数は、そこから2つ選ぶ組み合わせの数になります。 ©CAPCOM 12
光線追跡: 絞り通過位置の記録 𝑃(𝑥, 𝑦) 𝑈, 𝑉 = D O 𝑥 𝑦 , 𝐷/2 𝐷/2 𝑢0 , 𝑣0 テクスチャ 𝑣 𝑈 2 + 𝑉 2 > 1 ⇔遮蔽 𝑢, 𝑣 = 𝑈 + 1 𝑉+1 , 2 2 • 各光線がゴーストのどこを表現するかという情報が必要 • 絞り羽根に遮蔽されてるかの判断が容易 • 記録した通過位置が標本すべきテクスチャの位置を表現 𝑢1 , 𝑣1 𝑢 光線追跡において、計算の対象にした光線は、ゴースト画像をマッピングするグリッドを構成します。 そのため、画像のどこを標本するかという情報を持たねばなりません。 13 各光線は絞り羽根を通過する際に、𝑈, 𝑉で表される値を記録します。 これは、絞り羽根の中心を原点とした座標をその開いている部分の半径で割った値です。 この2乗の和の平方根が1より大きい場合はその光線が遮蔽されていることを表します。 また、𝑈, 𝑉は少しの計算でゴースト画像を標本する際の𝑢, 𝑣として使用することができます。 ©CAPCOM 13
光線追跡: 反射防止膜 𝑡𝑋 , 𝑟𝑋 , 𝑟𝑋′ , 𝑡𝑋′ : フレネル係数 𝐸𝑋 : 電場 ② 𝑛 単 ガ 層 ラ 膜 ス 𝑡1′ 𝑟1′ 光 𝑟0 𝑡0 ① 𝐸0 • • • • • 𝑟1 𝑡1 𝑙 位相変化: 𝑒 𝑗2𝛿 光路差: 2𝑛𝑙 位相差と光路差の関係 2𝛿 = 2𝜋 4𝜋𝑛𝑙 2𝑛𝑙 = 𝜆 𝜆 反射成分の総和 𝐸𝑟 = 𝑟0 + 𝑡0 𝑡1′ 𝑟1 𝑒 𝑗2𝛿 + ⋯ 𝐸0 ① ② 反射率: 𝑅 = 𝐸𝑟 2 𝐸0 ≅ 𝑟0 + 𝑡0 𝑡1′ 𝑟1 𝑒 𝑗2𝛿 = 𝑟02 + (𝑡0 𝑡1′ 𝑟1 )2 +2𝑟0 𝑡0 𝑡1′ 𝑟1 cos 2 4𝜋𝑛𝑙 𝜆 波長依存 ゴーストの色を計算することが目的 「①空気・単層膜間での反射成分」+「②単層膜・ガラス間での多重反射成分の総和」が反射光の電場 反射率は波長依存→色を再現 実際の計算は斜め入射 膜厚や波長に対する屈折率変化は非公開なので,仮の値・式(MgF2,分散曲線方程式…)を使用 マッピングする際に必要な情報が得られたので、次にゴーストの色を評価するための処理に移ります。 カメラのレンズは基本的にゴーストのようなノイズを低減するために、レンズ表面に反射を抑制する膜が張られています。 14 この膜を反射防止膜と呼び、これによる効果を計算することで尤もらしいゴーストの着色や強度の再現を狙います。 今、画面左上の図のようにレンズ表面に屈折率𝑛厚み𝑙の膜がある状況を考えます。 この時、膜の内部を往復した際の位相変化を𝑒 𝑗2𝛿 としておきましょう。 屈折率と実際の厚みから垂直入射時の光路差は2𝑛𝑙であり、位相差は光路差で表すことができます。 位相差は勝手に決めた値ですが、この等式により計算が可能となり、 これは反射率計算に必要な関係式になります。 ©CAPCOM 14
光線追跡: 反射防止膜 𝑡𝑋 , 𝑟𝑋 , 𝑟𝑋′ , 𝑡𝑋′ : フレネル係数 𝐸𝑋 : 電場 ② 𝑛 単 ガ 層 ラ 膜 ス 𝑡1′ 𝑟1′ 光 𝑟0 𝑡0 ① 𝐸0 • • • • • 𝑟1 𝑡1 𝑙 位相変化: 𝑒 𝑗2𝛿 光路差: 2𝑛𝑙 位相差と光路差の関係 2𝛿 = 2𝜋 4𝜋𝑛𝑙 2𝑛𝑙 = 𝜆 𝜆 反射成分の総和 𝐸𝑟 = 𝑟0 + 𝑡0 𝑡1′ 𝑟1 𝑒 𝑗2𝛿 + ⋯ 𝐸0 ① ② 反射率: 𝑅 = 𝐸𝑟 2 𝐸0 ≅ 𝑟0 + 𝑡0 𝑡1′ 𝑟1 𝑒 𝑗2𝛿 = 𝑟02 + (𝑡0 𝑡1′ 𝑟1 )2 +2𝑟0 𝑡0 𝑡1′ 𝑟1 cos 2 4𝜋𝑛𝑙 𝜆 波長依存 ゴーストの色を計算することが目的 「①空気・単層膜間での反射成分」+「②単層膜・ガラス間での多重反射成分の総和」が反射光の電場 反射率は波長依存→色を再現 実際の計算は斜め入射 膜厚や波長に対する屈折率変化は非公開なので,仮の値・式(MgF2,分散曲線方程式…)を使用 次に、反射光は「空気・単層膜間での反射成分」と、「単層膜・ガラス間での多重反射成分の総和」を合わせたものになります。 従って反射率は、反射成分の総和𝐸𝑟 と外部から入射した電場𝐸0 を用いて計算できます。 15 これによって得た反射率は、波長に依存するため、各波長に対して異なる反射率が取得でき色を再現できるようになります。 また、本スライドでは説明の単純化のため垂直入射の場合を書いていますが、実際は斜め入射で計算しています。 その波長の持つ刺激と合わせて使用することで、 最終的に得られるレンズフレアにおいて様々な明るさと色を持ったゴーストが描けます。 また、膜厚や波長に対する屈折率変化など、公開されていない数字は多いので仮の値で計算しています。 ©CAPCOM 15
光線追跡: 集光度 前玉 センサ面 強度調整係数 明(密) 明(密) 暗(疎) 𝑆 𝑆 𝑆 𝑆 𝑆0 𝑆1 暗(疎) 4𝑆 𝑆0 + 𝑆1 + 𝑆2 + 𝑆3 • • • • 明(密) 𝑆2 𝑆3 明(密) 暗(疎) 単一のゴースト内でも,明暗が発生→その再現が目的 前玉側とセンサ側でグリッドの形状が変化 集光するほど明るくなる=面積に反比例 センサ面/前玉での周辺4矩形の面積を用い,集光度合いを示す強度調整係数を計算 次に、集光度合いの評価です。先ほどの反射率により生じるゴーストごとに、 明るさが違うことも再現できますが、単一のゴーストの中でも明暗の分布がみられます。 16 その再現を考えましょう。 左上に示すように前玉で入力された等間隔なグリッドはセンサ面で歪み、粗密が起こります。 ©CAPCOM 16
光線追跡: 集光度 前玉 センサ面 強度調整係数 明(密) 明(密) 暗(疎) 𝑆 𝑆 𝑆 𝑆 𝑆0 𝑆1 暗(疎) 4𝑆 𝑆0 + 𝑆1 + 𝑆2 + 𝑆3 • • • • 明(密) 𝑆2 𝑆3 明(密) 暗(疎) 単一のゴースト内でも,明暗が発生→その再現が目的 前玉側とセンサ側でグリッドの形状が変化 集光するほど明るくなる=面積に反比例 センサ面/前玉での周辺4矩形の面積を用い,集光度合いを示す強度調整係数を計算 また、一定の明るさの光線をレンズに入力した場合、出力面での広がりが小さければ、 光が収束することで明るく、広がりが大きければ光が拡散することで暗くなります。 従って、この性質を使えば単一のゴーストの中で発生する明暗の再現ができます。 17 そこで、画面上中央のように、ある光線に注目し、センサ面での周辺の4つの矩形の面積の和をとります。 これと、入力面での周辺4つの矩形の面積の和をとって得た比が、前述の特性をうまく表す強度を調整する係数となります。 ©CAPCOM 17
光線追跡 現在位置 光波分布画像生成 光波分布画像マッピング では、光波分布画像生成部分の説明に移ります。 18 ©CAPCOM 18
光波計算: スターバースト 絞り羽根 強度計算 マスク画像 スターバースト 𝑔 𝑥, 𝑦 𝑦 𝑦′ 𝑥 ℱ 𝑔 𝑥′, 𝑦′ 𝑥′ 𝑑 Fraunhofer回折 ′ ′ ′ 𝑔 𝑥 ,𝑦 𝐼 𝑥 ,𝑦 ≅ 𝐴𝑒 𝑗 2𝜋 𝑥 ′ +𝑦 ′ 𝑑+ 2𝑑 𝜆 ′ = 𝑔 𝑥 ,𝑦 ′ 2 𝑀𝑋𝑌𝑍 : 等色関数 𝐿: 分光分布特性 2 𝐺 2𝜋𝑥 ′ Τ𝜆𝑑 , 2𝜋𝑦 ′ Τ𝜆𝑑 ൘𝑗𝜆𝑑 𝐴2 ≅ 2 2 𝐺(2𝜋𝑥 ′ Τ𝜆𝑑 , 2𝜋𝑦 ′ Τ𝜆𝑑) 2 𝜆 𝑑 伝搬先 XYZ表色系出力 𝐺 2𝜋𝑥 ′ Τ𝜆𝑑 , 2𝜋𝑦 ′ Τ𝜆𝑑 = ℱ[𝑔 𝑥, 𝑦 ] 2 ′ 開口面 波長で積分+RGB変換 ℱ: フーリエ変換 𝑧 𝐶XYZ 𝑥 ′ , 𝑦 ′ ≅ න 𝜆MAX 𝜆MIN 𝐼 𝑥 ′ , 𝑦 ′ 𝑀𝑋𝑌𝑍 𝜆 𝐿 𝜆 𝑑𝜆 • 他の波長での分布を計算する必要性無し • 𝝀𝟎 で強度スペクトル計算→強度 𝟐 ൗ𝝀 倍, 𝝀ൗ𝝀𝟎 倍拡大しながら加算.RGBに変換. 𝝀𝟎 より良い表現のためには、波動光学の理論を用いた画像生成が重要です。 まずは、スターバーストの画像生成から始めましょう。 ここではFraunhofer回折という回折の近似計算を用います。 これはフーリエ変換を用いた手法で高速フーリエ変換によって高速に評価できる手法です。 19 具体的には左上のように、絞り羽根を模したマスク画像を用意し、 それにフーリエ変換を施すことで回折像としての周波数スペクトルを得ることができます。 ここでマスク画像は空いてるかどうかの情報さえあれば良いのでRチャンネルのみです。 計算された周波数スペクトルは実数と虚数として現れるので、2乗和をとって強度に変換します。 ©CAPCOM 19
光波計算: スターバースト 絞り羽根 強度計算 マスク画像 スターバースト 𝑔 𝑥, 𝑦 𝑦 𝑦′ 𝑥 ℱ 𝑔 𝑥′, 𝑦′ 𝑥′ 𝑑 Fraunhofer回折 𝐺 2𝜋𝑥 ′ Τ𝜆𝑑 , 2𝜋𝑦 ′ Τ𝜆𝑑 = ℱ[𝑔 𝑥, 𝑦 ] 2 ′ ′ ′ ′ 𝑔 𝑥 ,𝑦 𝐼 𝑥 ,𝑦 ≅ 𝐴𝑒 𝑗 開口面 波長で積分+RGB変換 ℱ: フーリエ変換 2𝜋 𝑥 ′ +𝑦 ′ 𝑑+ 2𝑑 𝜆 ′ = 𝑔 𝑥 ,𝑦 ′ 2 2 𝐺 2𝜋𝑥 ′ Τ𝜆𝑑 , 2𝜋𝑦 ′ Τ𝜆𝑑 ൘𝑗𝜆𝑑 𝐴2 ≅ 2 2 𝐺(2𝜋𝑥 ′ Τ𝜆𝑑 , 2𝜋𝑦 ′ Τ𝜆𝑑) 2 𝜆 𝑑 𝑧 伝搬先 XYZ表色系出力 𝑀𝑋𝑌𝑍 : 等色関数 𝐿: 分光分布特性 𝐶XYZ 𝑥 ′ , 𝑦 ′ ≅ න 𝜆MAX 𝜆MIN 𝐼 𝑥 ′ , 𝑦 ′ 𝑀𝑋𝑌𝑍 𝜆 𝐿 𝜆 𝑑𝜆 • 他の波長での分布を計算する必要性無し • 𝝀𝟎 で強度スペクトル計算→強度 𝟐 ൗ𝝀 倍, 𝝀ൗ𝝀𝟎 倍拡大しながら加算.RGBに変換. 𝝀𝟎 Fraunhofer回折では単一の波長に対しての結果を与えますが、 実際にセンサに到達するのは様々な波長の成分です。 では、「他の波長に対しても同様の計算が必要か?」といえばそうではありません。 20 中段左のFraunhofer回折の式に注目すると、計算されたフーリエ変換による強度像𝐼は、 赤い矩形で囲ったように、強度と大きさが波長に依存しています。 従って、1度強度スペクトルを取得すれば、それをある波長𝜆0 のものであるとし、 他の波長𝝀ではそれを強度 𝝀𝟎 𝟐 ൗ𝝀 倍、大きさ 𝝀ൗ𝝀 倍することで得ます。 𝟎 この仕組みに従って他の波長での結果を取得し、中段右の式のように、 可視光域にわたって積分後、RGBに変換することでスターバースト画像を得ます。 ©CAPCOM 20
光波計算: スターバースト計算時の制限 実関数のフーリエ変換と対称性 定義: 𝐺 𝑢 +∞ = ℱ[𝑔(𝑥)] ≡ −∞ 𝑔(𝑥)𝑒 −𝑗2𝜋𝑢𝑥 𝑑𝑥 +∞ ∗ +𝑗2𝜋𝑢𝑥 න 𝑔∗ 𝑥 = 𝑔 𝑥 → 𝐺 𝑢 = 𝑔(𝑥)𝑒 8枚羽根 (点対称) 7枚羽根 (非点対称) 7枚羽根結果 (点対称) 𝑑𝑥 = 𝐺(−𝑢) −∞ 原点対称: 𝐺(𝑢, 𝑣) 2 = 𝐺(−𝑢, −𝑣) 2 (∵ 𝑧 ∗ = 𝑧 ) • 奇数羽根絞りは,スターバーストが非対称 • 振幅/強度スペクトルは原点対称 • Fraunhofer回折の計算だけでは非対称スターバーストは再現不可 →計算結果の画像中心から放射方向に𝑢,𝑣を変化させて再現 一方で、この手法には制限があります。 今回のシミュレーションに用いた計算方法は、フーリエ変換によって実現されるためその性質を継承します。 21 今、左上の式のように、実関数をフーリエ変換の入力とした場合を考えましょう。 実関数は複素共役がそれ自身になるため、フーリエ変換の定義から、振幅・強度スペクトルが原点対称になることが分かります。 右上のように実際に奇数枚の羽根のカメラで発生したスターバーストは、点対称ではなく若干非対称に見えます。 しかし前述のことから本手法では奇数枚羽根の計算をしても原点対称な回折像しか得られません。 もし、非対称にしたい場合は、角度に対してランダムな値を与える関数を用意し、 それに応じて計算結果の𝑢, 𝑣を操作し変形を加えるといった対応が考えられます。 ©CAPCOM 21
光波計算: 前玉のゴミ・傷効果の反映 前玉ゴミ ナシ 前玉ゴミ アリ ゴミ画像 影響 小 影響 大 Rチャンネル • • • • 前玉にはゴミ/傷が存在 マスク画像に,ゴミ画像乗算 適当に線を描いたもので十分 影響の強弱も調整可能 次に、スターバーストの見た目をより尤もらしくする方法を考えましょう。 カメラの前玉は空気に露出するため傷やほこりが付きます。 少なくともこれは左上のように回折像に影響を及ぼすため、この効果を反映することを考えます。 22 実現は非常に容易で、右上のようにゴミや傷を模した画像を用意し、マスク画像に乗算した状態で計算を実行するだけです。 また、マスク画像はRチャンネルのみなので、勿論乗算するゴミ画像もRチャンネルのみです。 またこの時、ゴミを表す部分は「0」にしておくことが重要です。これは、 絞りのマスク画像に対して乗算を行うためゴミ部分で「遮蔽」を表現する必要があるためです。 また、ゴミ画像を2値で作っておき、その間を遷移するパラメータを追加しておけば、 その変化に従ってゴミの影響を調整することができるので便利になります。 ©CAPCOM 22
光波計算: ゴースト ゴースト 乗算 ℱ −1 ℱ FRF AS: 𝑔 𝑥, 𝑦; 𝑧 = 𝑧0 + 𝑑 = ℱ −1 ℱ 𝑔 𝑥, 𝑦; 𝑧 = 𝑧0 𝐻FRF 𝑢, 𝑣; 𝑑 chirp function −2 2 2 𝑢 2 + 𝑣 2 ≤ 𝜆−2 𝐻FRF 𝑢, 𝑣; 𝑑 = 𝑒 𝑗2𝜋𝑤𝑑 𝑤(𝑢, 𝑣) = ൝ 𝜆 − 𝑢 − 𝑣 0 otherwise 制限: 𝑢limit = 𝜆 実部 虚部 Δ𝑢, Δ𝑣: 標本間隔(周波数) 帯域制限角スペクトル法 2Δ𝑢𝑑 2 +1 −1 , 𝑣limit = 𝜆 𝑯𝐅𝐑𝐅_𝐥𝐢𝐦𝐢𝐭𝐞𝐝 𝒖, 𝒗; 𝒅 = 𝑯𝐅𝐑𝐅 𝒖, 𝒗; 𝒅 𝐫𝐞𝐜𝐭 2Δ𝑣𝑑 2 +1 −1 𝒖 𝒗 𝐫𝐞𝐜𝐭 𝟐𝒖𝐥𝐢𝐦𝐢𝐭 𝟐𝒗𝐥𝐢𝐦𝐢𝐭 • 光線追跡によって得たグリッドにマッピングする画像 →出来ることなら厳密に計算 →角スペクトル法(AS:Rayleigh-Sommerfeld積分の畳み込み形式) • 周波数応答関数(FRF)は伝搬距離が長くなると周波数が上昇→FRFにエイリアシング誤差が発生 • エイリアシング誤差を抑制するため帯域制限角スペクトル法(Band Limited-AS)[2]を採用 スターバーストについての説明は終わり、次はゴーストに関する説明に移ります。 ここでも、尤もらしい分布を得るために波動光学的な伝搬計算を行います。 スターバースト生成に用いたFraunhofer回折は近似計算でした。 23 今回は光線追跡によって得たグリッドにマッピングする画像を生成するので、折角なら高い精度で計算したいと思いました。 そこで厳密な回折を扱うRayleigh-Sommerfeld積分を、高速に評価する角スペクトル法を今回の計算にもちいました。 この手法では画面左上のようにスターバーストの計算時と同様、 絞り羽根を模したマスク画像を用意しておき、それと周波数応答関数を用いて計算を行います。 その内容は画面右上に示す式のように、フーリエ変換で計算できる畳み込み演算です。 ©CAPCOM 23
光波計算: ゴースト ゴースト 乗算 ℱ −1 ℱ FRF AS: 𝑔 𝑥, 𝑦; 𝑧 = 𝑧0 + 𝑑 = ℱ −1 ℱ 𝑔 𝑥, 𝑦; 𝑧 = 𝑧0 𝐻FRF 𝑢, 𝑣; 𝑑 chirp function −2 2 2 𝑢 2 + 𝑣 2 ≤ 𝜆−2 𝐻FRF 𝑢, 𝑣; 𝑑 = 𝑒 𝑗2𝜋𝑤𝑑 𝑤(𝑢, 𝑣) = ൝ 𝜆 − 𝑢 − 𝑣 0 otherwise 制限: 𝑢limit = 𝜆 実部 虚部 Δ𝑢, Δ𝑣: 標本間隔(周波数) 帯域制限角スペクトル法 2Δ𝑢𝑑 2 +1 −1 , 𝑣limit = 𝜆 𝑯𝐅𝐑𝐅_𝐥𝐢𝐦𝐢𝐭𝐞𝐝 𝒖, 𝒗; 𝒅 = 𝑯𝐅𝐑𝐅 𝒖, 𝒗; 𝒅 𝐫𝐞𝐜𝐭 2Δ𝑣𝑑 2 +1 −1 𝒖 𝒗 𝐫𝐞𝐜𝐭 𝟐𝒖𝐥𝐢𝐦𝐢𝐭 𝟐𝒗𝐥𝐢𝐦𝐢𝐭 • 光線追跡によって得たグリッドにマッピングする画像 →出来ることなら厳密に計算 →角スペクトル法(AS:Rayleigh-Sommerfeld積分の畳み込み形式) • 周波数応答関数(FRF)は伝搬距離が長くなると周波数が上昇→FRFにエイリアシング誤差が発生 • エイリアシング誤差を抑制するため帯域制限角スペクトル法(Band Limited-AS)[2]を採用 さて、理論的には極めて厳密な角スペクトル法ですが、実際に数値計算でゴーストを生成する場合においては注意が必要です。 画面右上に示した周波数応答関数𝐻FRF の式に注目すると、伝搬距離𝑑が大きくなるほどより短い周期をもつことが分かります。 24 つまり、計算する距離が長くなるほどに、信号周波数が上昇するチャープ関数になっていることが分かります。 従って、数値計算においては伝搬する距離が大きくなると、離散化に伴うエイリアシング誤差が、 周波数応答関数に現れ計算結果に重大なノイズを生じてしまいます。 そこで弊社では、周波数応答関数を必要十分な帯域に制限する、 帯域制限角スペクトル法を採用することでこの問題を回避しています。 ©CAPCOM 24
光波計算: 帯域制限前後の比較 角スペクトル法(AS) FRF実部 FRF虚部 拡大図による比較 回折像 帯域制限角スペクトル法(BL-AS) FRF実部 FRF虚部 回折像 AS BL-AS • 伝搬距離が伸びてくると回折像全体にノイズ発生 • 帯域制限角スペクトル法の使用により,ガビガビしている部分が解消 こちらが実際に回折伝搬計算時に通常の角スペクトル法と、 帯域制限角スペクトル法を用いた場合の計算結果の比較になります。 25 角スペクトル法に対して、帯域制限角スペクトル法では確かに周波数応答関数は打ち切られ、中心の矩形領域外が0となっています。 画面右に示したそれぞれの手法で得られた回折像の拡大図を確認すると、通常の角スペクトル法では回折像にノイズが生じています。 一方で帯域制限角スペクトル法ではそのようなノイズが解消され問題のない見た目になっており、 厳密なゴーストの回折波が得られたことになります。 ©CAPCOM 25
光線追跡 光波分布画像生成 現在位置 光波分布画像マッピング 以上で、レンズフレアに必要な情報はそろったので、描画に移りましょう。 26 ©CAPCOM 26
描画 複雑な変形 • グリッドにゴーストをマッピング.光源位置にスターバーストをマッピング • 明るさや色など,尤もらしいものが再現 • 歪んだグリッドへゴーストをマッピングするので非線形な変化を自然に実現可能 ここでは特に説明するものはありません。 今までに得た情報を用いてグリッドにテクスチャマッピングを行い、 レンダーターゲットに描くだけです。 27 明るさや色についても、意識せずともある程度自然なものが再現できる上、 歪んだグリッドにマッピングできることで自然に非線形な変化を伴うゴーストを描画できます。 ©CAPCOM 27
画面外に光源がある場合の遮蔽処理1/2 光源 カメラ カメラ シャドウマップ 画面端 • デプスバッファでの遮蔽では画面外に光源がある場合にフレアの出現不可 • シャドウマップと,カメラ座標から遮蔽判定 ここからは遮蔽処理や高速化などについて紹介していきます。 まずは画面外に光源がある場合の対応です。 スクリーンスペースでは基本的にカメラの深度バッファを使用することで遮蔽を行うと思いますが、 その場合画面外でフレアを出すことができません。 28 そこで、弊社では今フレアを出す光源としているライトのシャドウマップと、 フレアを描画しているカメラの位置を用いた深度比較をすることによって遮蔽判定を行います。 ©CAPCOM 28
画面外に光源がある場合の遮蔽処理2/2 シャドウマップ 𝑟MIN カメラ座標 𝑟 𝑟MIN 小 𝑟 大 𝑟MIN 𝑟 露出 遮蔽 𝑟MIN • • • • • • 遮蔽 (最近傍) カメラの位置の深度と比較するだけでは遮蔽状態が2値→滑らかな遷移が必要 単位円内をランダムに標本した点を事前に128点記録[(0,0)を含む] スクリーン上のカメラ位置に用意したランダム点を𝑟倍したものをシフトし点ごとに遮蔽判定 配列に遮蔽時は判定点までの長さ(≤ 𝑟)を,露出なら𝑟を記録 𝑟 記録した長さの最小値𝑟MIN を求め,遮蔽率を MIN (0:遮蔽 1:露出)として計算 𝑟 レンズフレアの大きさ/明るさを示すパラメタに乗算 しかしここで、シンプルにカメラ位置での遮蔽判定結果を使うと2値での判定になり、 遮蔽されるかされないかの境界でレンズフレアの遮蔽状態が即座に切り替わってしまいます。 例えばアーティストからの指摘で、風揺れする樹木の葉による遮蔽のケースで、 頻繁に遮蔽状態が変わるためチカチカとしてしまい、画面をうるさくするというものがありました。 29 そこで、滑らかに遮蔽状態を再現する方法を考えます。 まず、単位円内をランダムに標本した点を128点用意しておきます。 次に画面上中央のように、遮蔽判定したい領域を決める半径𝑟を与えて、用意した点を𝑟倍したものをカメラの位置にシフトします。 その後、各点でシャドウマップを用いて深度ベースの遮蔽判定を行います。 ©CAPCOM 29
画面外に光源がある場合の遮蔽処理2/2 シャドウマップ 𝑟MIN カメラ座標 𝑟 𝑟MIN 小 𝑟 大 𝑟MIN 𝑟 露出 遮蔽 𝑟MIN • • • • • • 遮蔽 (最近傍) カメラの位置の深度と比較するだけでは遮蔽状態が2値→滑らかな遷移が必要 単位円内をランダムに標本した点を事前に128点記録[(0,0)を含む] スクリーン上のカメラ位置に用意したランダム点を𝑟倍したものをシフトし点ごとに遮蔽判定 配列に遮蔽時は判定点までの長さ(≤ 𝑟)を,露出なら𝑟を記録 𝑟 記録した長さの最小値𝑟MIN を求め,遮蔽率を MIN (0:遮蔽 1:露出)として計算 𝑟 レンズフレアの大きさ/明るさを示すパラメタに乗算 この時、用意した点の中に原点が含まれるのは、 遮蔽判定にカメラ自身の位置を含まないとカメラの位置での遮蔽が行えないためです。 次にこの遮蔽判定を行うシェーダをCompute Shaderで書き、グループ数1、128スレッドで起動します。 30 そして、各スレッドは各ランダム点での遮蔽結果に応じて、 遮蔽時はカメラ位置から測った対応点の長さを、露出なら𝑟を記録します。 その結果をgroupsharedな配列に書き込み、記録した長さの最小値𝑟MIN を計算し𝑟で除算します。 これによりカメラ位置の近傍で遮蔽される要因があるほどに0に近く、そうでない場合に1に近くなる値を得ます。 これを、レンズフレアの大きさと明るさを示す値に乗算すれば、滑らかな遮蔽を表現することが可能になります。 ©CAPCOM 30
描画時の問題と緩和策 分離して不自然 𝜆0 𝜆1 𝜆2 𝜆3 𝜆4 𝜆5 各区間内で違う波長を標本 紫 外 • • • • 赤 外 処理負荷や消費メモリの関係から,9波長ほどを標本して処理 波長帯を複数に分割.毎フレーム異なる波長を標本 時間方向のブレンドによって,見かけ上の標本波長数を増大 フレアの移動時に若干のブラーが残存 次に生じた問題への対処についてです。 処理負荷や消費メモリの観点から、基本的に多くとも9種類ほどの波長を可視波長帯から標本して使用するしかありません。 31 そのため、ゴーストによっては画面左上のように、各波長に対する成分が大きく分離したようになり不自然な見た目となります。 そこで、この問題を緩和するための策として、使用している波長帯を複数に分割し毎フレーム各領域内で異なる波長を標本します。 そして、毎フレーム過去のレンダリング結果とブレンドすることで、見かけ上の標本波長数を増大させ分離部分を緩和します。 しかし、この対応によってレンズフレアが移動したときに若干ブラーが残るので、 その部分への対策は別途考える必要があります。ここではブラーについては言及しません。 ©CAPCOM 31
高速化のための工夫: 概要 𝑃(𝑥, 𝑦) 𝑢0 , 𝑣0 テクスチャ カリング前 カリング後 𝑣 D O 𝑢 𝑢1 , 𝑣1 𝑈, 𝑉 = 𝑥 𝑦 , 𝐷/2 𝐷/2 𝑢, 𝑣 = 𝑈 + 1 𝑉+1 , 2 2 • オーバードロー過多のためコスト高 • 𝑢,𝑣から描画に寄与する点かどうかが判定可能 • 描画に寄与しない頂点を除外 最後の項目として高速化です。 基本的にオーバードローが多いエフェクトであるためコストが高いです。 32 描画段階では、光線追跡時に記録した𝑈, 𝑉を、テクスチャをフェッチするための𝑢, 𝑣に変換します。 ここで記録されている値は𝑈, 𝑉の定義から開口の外側、 つまり絞り羽根部分に光線が当たった場合は遮蔽されているということを意味しました。 従ってそれらから計算された𝑢, 𝑣にはテクスチャの定義されている範囲外を指し示すものがあり、 ゴーストの描画に全く貢献しないそのような値を持つ無効な光線を除外します。 ゴーストによっては、グリッドのわずかな部分しか有効な𝑢, 𝑣を持っていない場合があり、 例えば右上の例のように、この除外処理によって大幅に無駄な頂点を省くことができます。 ©CAPCOM 32
高速化のための工夫: 処理 そのまま 𝑣 𝑣=1 カリング 𝑢MAX , 𝑣MAX 1,1 vs. 𝑢 破棄コード 0,0 𝑢MIN , 𝑣MIN 𝑢=1 if(isCulled) pos.z = asfloat(0xffffffff); • 判定したい点と辺を共有する隣接点群に記録された𝑢𝑣のAABBを算出 • 除外判定時,その座標にNaNを設定することで頂点を破棄* [引用] *Coordinates coming in to clipping with infinities at x,y,z may or may not result in a discarded primitive. Coordinates with NaN at x,y,z or w coming out of clipping are discarded.(1) 具体的な処理としては、画面左上のようにある光線に注目し、 この頂点を共有して三角形を成す周辺の頂点の𝑢, 𝑣からAABBを生成します。 このAABBが 𝑢, 𝑣 = 0, 0 , (1, 1)で定められるAABBと交差を持たない場合、 描画に寄与する頂点を損なうことなく、頂点を破棄することができます。 33 実際の処理としては、破棄したい頂点位置にNaNを設定することで、その頂点を含む三角形ごと破棄しています。 例えばDirectXであれば、DirectX-Specsに頂点の扱いに関する記載があります。 ©CAPCOM 33
高速化のための工夫: パフォーマンスの変化例 PlayStation5での計測. 3840 × 2160の縦横1/4の解像度(960 × 540)に出力 投入頂点は1ゴーストあたり16 × 16頂点 × ゴースト325個 × 9波長 = 748,800 カリング OFF 遮蔽処理 光線追跡 スターバースト描画 ゴースト描画 カリング ON 0.005 0.989 0.007 4.332 10倍速 6.5倍速 遮蔽処理 光線追跡 スターバースト描画 ゴースト描画 0.005 0.994 0.007 0.407 カリング処理 0.259 0.666 単位 : [millisecond] 実際の運用では,フレーム当たりの波長数を減らす/描画範囲を小さくするなどが考えられる PlayStation5にてこのカリング処理によるパフォーマンス変化を確認しました。 頂点としては75万ほど投入しています。 34 カリングをすることによりゴーストの描画は約10倍ほど高速化されました。 カリング処理を含めても約6.5倍速であり、意味のある最適化であったと考えます。 また実際の運用では波長数を減らしたり、描画範囲を狭くするといった負荷低減策を講じることになるかと思います。 ©CAPCOM 34
まとめと展望 [まとめ] • 数値的回折伝搬手法により尤もらしい光波分布画像を生成 • 光線追跡で自然な変形を伴うゴーストを描画 • 画面外での遮蔽処理の一つの解決策を提案 • 波長分散の大きい部分でゴーストが分離して出現 →時間方向ブレンドで見かけ波長数増加 • そのままでは奇数枚絞り羽根のスターバーストの非対称性を再現不可 • スクリーンスペースで光源位置を取得できないので,多数の光源には対応困難 • レンズの公開されていない情報が多数 [展望] • 開口周辺に光線が収斂するようにし,少ないグリッド分割数でも綺麗にゴーストを表現 • 多数の光源への対応 以上をまとめさせていただきます。 数値伝搬計算手法や、光線追跡によって尤もらしい見た目のレンズフレアの描画を目指し、 画面外においても遮蔽を実現するなどしました。 35 問題としては、まず、奇数枚羽根の非対称なスターバーストを表現できないことがあります。 しかし、こちらに関しましてはテクスチャを変形することで実現が可能です。 他にも、負荷的な視点やスクリーンスペースで光源位置を取得できないことから、 多数の光源に対応できないといったものがあげられます。 ©CAPCOM 35
まとめと展望 [まとめ] • 数値的回折伝搬手法により尤もらしい光波分布画像を生成 • 光線追跡で自然な変形を伴うゴーストを描画 • 画面外での遮蔽処理の一つの解決策を提案 • 波長分散の大きい部分でゴーストが分離して出現 →時間方向ブレンドで見かけ波長数増加 • そのままでは奇数枚絞り羽根のスターバーストの非対称性を再現不可 • スクリーンスペースで光源位置を取得できないので,多数の光源には対応困難 • レンズの公開されていない情報が多数 [展望] • 開口周辺に光線が収斂するようにし,少ないグリッド分割数でも綺麗にゴーストを表現 • 多数の光源への対応 また、レンズの情報で公開されていないものが多いという問題もありました。 展望をあげさせていただくと、絞りの開口部周辺の必要十分な範囲に光線が集まるようにし、 少ないグリッド分割数できれいなゴーストを出すことによる高速化がまずあります。 36 他にも多数の光源からレンズフレアを出せるようにするアルゴリズムを考えるというものがあります。 以上で私からの発表を終わります。 ©CAPCOM 36
引用文献 (1) Direct3D 11.3 Functional Specification “15.4 Clipping” April 23, 2015 https://microsoft.github.io/DirectXSpecs/d3d/archive/D3D11_3_FunctionalSpec.htm#15.4%20Clipping(08/29/2023) 参考文献 [1] Hullin, M., Eisemann, E., Seidel, H.P., Lee, S., “Physically-based real-time lens flare rendering,” ACM Trans. Graph. 30(4), 108:1–108:10 (2011). DOI 10.1145/2010324.1965003. [2] K. Matsushima, T. Shimobaba, "Band-Limited Angular Spectrum Method for Numerical Simulation of Free-Space Propagation in Far and Near Fields," Opt. Express 17(22), 19662-19673 (2009). 37 ©CAPCOM 37