レンダリング新機能ダイジェスト (HDR Grading,Shell Fur,Signed Distance Field)

13.1K Views

November 27, 23

スライド概要

■概要
[HDR Grading]:
OpenColorIOを活用して、SDRグレーディングからHDRグレーデイングに移行した事例をご紹介いたします。

[ShellFur]:
古くからある技術を次世代ハード品質で活用した事例を紹介します。

[Signed Distance Field]:
SDFを活用して実現した機能や、その最適化事例について紹介いたします。

※CAPCOM Open Conference Professional RE:2023 で公開された動画を一部改変してスライド化しております。

■想定スキル
レンダリングの知識がある方

詳細は下記公式サイトをご確認ください。
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
CAPCOM Open Conference Professional RE:2023
https://www.capcom-games.com/coc/2023/

カプコンR&Dの最新情報は公式Twitterをチェック!
https://twitter.com/capcom_randd
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

profile-image

株式会社カプコンが誇るゲームエンジン「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/

シェア

埋め込む »CMSなどでJSが使えない場合

関連スライド

各ページのテキスト
1.

レンダリング新機能ダイジェスト (HDR Grading,Shell Fur,Signed Distance Field) それではレンダリング新機能ダイジェストHDR Grading, Shell Fur, Distance Fieldの発表を始めます。 まずはHDR Gradingのセクションとして、OpenColorIOを活用したHDRグレーディングの導入事例についてお話いたします。 ©CAPCOM 1

2.

アジェンダ 新旧パイプラインの概要 HDRグレーディングパイプラインの対応 新パイプライン移行したことによるGUIの変更点 最適化 アーティストのグレーディング環境 今後の展望 こちらが本日のアジェンダになります。 まずHDRグレーディングに移行した前後のパイプラインの概要や背景の説明、 HDRグレーディングパイプラインの詳細、 HDRグレーディングパイプラインに移行したことによるGUIの対応、 最適化、アーティストのグレーディング環境、今後の展望 2 の流れでお話していきます。 ©CAPCOM 2

3.

背景 HDR出力には対応していたが、SDRグレーディングのまま • 輝度のクランプが発生しないようにLUTのアクセス時にワークアラウンド HDRファーストでグレーディングしたい要望が挙がった まずHDRグレーディングに移行した背景としては、元々エンジンはHDR出力には対応していましたが、 グレーディングはSDRグレーディングのままとなっており、後ほど説明いたしますが、HDR出力時にはグレーディングに 使用するLUTにアクセスする際、ワークアラウンドを行って輝度のクランプを回避している状態でした。 3 またコンテンツ自体もSDRファーストで制作されていたのが、HDRファーストで制作したい要望が強くなっていました。 ここまで何度か出てきたHDRグレーディングという言葉ですが、 本セッションではRGB値1を超えた色を扱った、 画面の階調や色調を加工する処理という意味合いとします。 ©CAPCOM 3

4.

旧パイプライン SDR出力 新パイプライン SDR出力 ではパイプラインの説明に入る前に、新パイプラインと旧パイプラインのSDR出力の見た目の比較をお見せします。 新旧比較して、新パイプラインの方が空や壁などが飽和せず表示できていたり、赤色の果物の色の出方に違いがあるのが 4 分かるかと思います。 ©CAPCOM 4

5.

旧パイプライン LUTのフォーマットはBT.709+sRGB • HDR出力時は1を超えた値を入力することができないのでワークアラウンド Old Pipeline sRGB LUT BT.709 Linear HDR Scene Render HDR PostEffect Exposure and Tonemap SDR ColorGrading sRGB OutPut SDR Display HDR10 Output HDR Display UI こちらが旧パイプラインとなります。 カラーグレーディングに使用しているLUTのフォーマットはBT.709のsRGBとなっています。 グレーディング処理が終わったらUI描画を行い、sRGBやHDR10など各ディスプレイ空間に変換して出力します。 ©CAPCOM 5 5

6.

HDR出力時のLUTのワークアラウンド 輝度が1.0以上だった場合はLUTの参照や補完方法を変える • 輝度で除算した色でLUTを参照、返り値に輝度を乗算 LUTによるクランプ有 LUTによるクランプ回避 前述したHDR出力時のLUTアクセス時のワークアラウンドについては、LUTに入力する色の輝度が1.0以上だった場合は、 輝度で除算してからLUTに参照し、LUTから得られた色に対して輝度で乗算する、といった方法でワークアラウンドを 行っていました。 6 確かにクランプは回避できますが、輝度1.0以上の高輝度部分のグレーディングについては、アーティストはコントロール できませんでした。 ©CAPCOM 6

7.

新パイプライン OpenColorIO+ACESを用いた変換 • グレーディング直前にACES AP1(以下AP1)に変換 • ACESのRRT+ODTによるディスプレイ出力 LUTはAP1+ACEScc(or ACEScct)に変更 New Pipeline BT.709 Linear HDR Scene Render HDR PostEffect OCIO GradingPass ( BT.709 AP1 ) AP1 Linear ACEScc ACEScct LUT Exposure HDR ColorGrading BT.2446 OCIO SDR OutputPass ( RRT and ODT ) UI ( sRGB ) SDR Display OCIO HDR OutputPass ( RRT and ODT ) UI ( HDR10 ) HDR Display こちらが新しいパイプラインとなります。 OpenColorIO+ACESを用いた変換パスを組み込んだのと、グレーディング時のカラースペースを変更しました。 7 変換パスに関しては、グレーディング前の色域変換(BT.709からAP1へ変換)、ディスプレイ空間へ変換するACESの RRT+ODT変換の2つがあります。 グレーディング時のカラースペースはBT.709+sRGBでグレーディングしていたのをAP1+ACEScc /ACEScctで グレーディングしています。 またRRT+ODT変換するようになった影響で、UIの描画順をディスプレイ空間への変換を行った後に変更しました。 ©CAPCOM 7

8.

新旧パイプライン比較 Old Pipeline sRGB LUT BT.709 Linear HDR Scene Render Exposure and Tonemap HDR PostEffect SDR ColorGrading sRGB OutPut SDR Display HDR10 Output HDR Display UI New Pipeline BT.709 Linear HDR Scene Render HDR PostEffect OCIO GradingPass ( BT.709 AP1 ) AP1 Linear ACEScc ACEScct LUT Exposure HDR ColorGrading BT.2446 OCIO SDR OutputPass ( RRT and ODT ) UI ( sRGB ) SDR Display OCIO HDR OutputPass ( RRT and ODT ) UI ( HDR10 ) HDR Display 8 ©CAPCOM 8

9.

LUTのフォーマット AP1+ACEScc/ACEScctで作成 • 主なグレーディングツールはDaVinci Resolve • FP16 サイズはアーティストが任意に選択 • 主に33x33x33を使用 LUTについてもう少し詳しく説明していきます。 アーティストは主にDaVinci Resolveを使って、AP1+ACEScc /ACEScctでグレーディングを行います。 9 LUTのサイズは同時に使用する場合はそれぞれのLUTのサイズを揃えてもらう制約はありますが、サイズ自体は特に制約はなく アーティストが任意に選択できます。 主にDaVinci Resolveのプリセットサイズである縦、横、奥行きが33のサイズのものが多いです。 ©CAPCOM 9

10.

LUTのシェーパー タイトル毎にACEScc/ACEScctを任意で選択 • 暗部の分布が異なる ACEScc ACEScct LUTのシェーパーに関してはACEcc /ACEScctをタイトル毎に任意で選択できるようにしています。 ACEScctはACESccのカーブにtoeが追加された暗部の分布が異なるものです。 10 それぞれの変換式に関してはACESのテクニカルドキュメンテーションの方に詳細がのっていますので、詳細を知りたいかたは 参照してください。 ACES Technical Documentation (acescentral.com) ©CAPCOM 10

11.

新パイプラインの方針 DCCツールとの連携を重視 導入の容易化 HDR/SDR出力の互換を容易化 New Pipeline BT.709 Linear HDR Scene Render HDR PostEffect OCIO GradingPass ( BT.709 AP1 ) AP1 Linear ACEScc ACEScct LUT Exposure HDR ColorGrading BT.2446 OCIO SDR OutputPass ( RRT and ODT ) UI ( sRGB ) SDR Display OCIO HDR OutputPass ( RRT and ODT ) UI ( HDR10 ) HDR Display それでは、新パイプラインの詳細に移ります。 新パイプラインではDCCツールとの連携を重視、導入の容易化、 HDRファーストでコンテンツ制作したときのSDR出力の互換を容易化、 11 というのを方針にしました。 ©CAPCOM 11

12.

DCCツールとの連携を重視 グレーディングはDCCツール上で行う • エンジンとDCCツールとで各種設定を合致させる必要がある 社内の様々なチームが使う可能性があるため扱いやすい形が良い • エンジンがDCCツール側に合わせる形 広く使われてるOpenColorIO+ACESの形式を採用 まず方針の1つ目であるDCCツールとの連携を重視する点についてですが、 DCCツールとの連携を重視するのは、グレーディングをエンジン上ではなく、DaVinci ResolveなどDCCツール上で12 行っていることに起因しています。 当たり前ですが、エンジン上での結果とグレーディングツール上での結果を一致させるためには、各種色の変換を一致させる 必要があります。社内の様々なチームが使う仕組みであると共に、設定の違いで絵が合わない等、無用なトラブルを避けるために 扱いやすい形が理想でした。 そこでDCCツール間でも設定の共有の仕組みに使われている、OpenColorIOを設定の共有フォーマットとし、これまた、 多くのDCCツールで採用されている、ACESのコンフィグを使用することにしました。 ©CAPCOM 12

13.

OpenColorIO 映像業界やDCCツールで導入されているオープンソースのカラーマネージメントのソ リューション • config(.ocio)とLUTを元に各種変換を生成 色に関する設定をDCC間で共有できる configはACESのものを利用 OpenColorIOとは映像業界やDCCツールで導入されている、オープンソースのカラーマネジメントのソリューションです。 .ocioファイルとそれに対応したLUTから各種変換を生成できます。 13 この仕組みを使うことで、DCC間で色に関する設定の共有が容易になります。 ConfigはAcademy Software Foundationにより、GitHubで公開されているACESのconfigを使用しています。 ©CAPCOM 13

14.

Academy Color Encoding System(ACES) 映像制作におけるカラーマネジメントのパイプライン • 各種カラースペースや変換が定義されている AP1カラースペースとRRT,ODTを利用 MIKE SEYMOUR fxguide "The art of digital color" August 23, 2011 https://www.fxguide.com/fxfeatured/the-art-of-digital-color/ (August 24, 2023) Academy Color Encoding System、略してACESは映画芸術科学アカデミーによって開発された、カラーマネジメントの パイプラインで、主に映像業界で導入されています。 14 ACESのパイプラインはいくつかのステージに分かれていて、IDT(Input Device Transform)という、カメラなどの撮影機材や 制作環境の特性を取り除きニュートラルな状態へ変換するステージ。 ACESという、AP1という広色域なカラースペースでレンダリングやグレーディングを行うステージ。 RRTは一旦飛ばして、ODT(Output Device Transform)という、sRGBやHDR10といったターゲットとなるディスプレイに 向けての変換を行うステージ。 RRT(Reference Rendering Transform)後のステージであるODTに向けて、最適になるようにトーンマッピングを行います。 ここでいわゆるフィルムルックな効果が適用されます。これらのステージからパイプラインが成り立っており、エンジンには AP1カラースペース、RRT,ODTを取り入れました。 ©CAPCOM 14

15.

エンジンとDCCの関係図 RE ENGINE DCC BT.709→AP1 OCIO BT.709→AP1 RRT+ODT ACES RRT+ODT OpenColorIOとACESの関係を整理すると、このような関係になります。 OpenColorIOが採用されているDaVinci ResolveなどDCCツール側とエンジン側とで、同じACESのconfigファイルを 15 利用することで、各種変換を容易に一致させることができます。 ©CAPCOM 15

16.
[beta]
OpenColorIOの組み込み
2種類のファイルで管理
• .ocio:OpenColorIOの元ファイル
• .ocioc: .ocioファイルの中から使う変換を指定するファイル
.ocio

.ocioc

displays:
ACES:
- !<View> {name: sRGB colorspave: Output – sRGB}
- !<View> {name: DCDM, colorspace: Output –DCDM}
- !<View> {name: DCDM P3D60 Limited, colorspace: Output – DCDM
- !<View> {name: DCDM P3D60 Limmited, colorspace: Output – DCDM
- !<View> {name: P3-D60, colorspace: Output – P3-D60}

“OCIOConfigPath” : “config.ocio”,
“DisplayName” : “ACES”,
“ViewName” : “sRGB”

float3 v4 = OCIO_Lut3d_1. SampleLevel(TrilinearClamp, nextInd, 0) . Rgb;
if (frac. r >= frac. g)
{
if (frac. g >= frac. b)
{
nextInd = baseInd + float3(0. , 0. , 0.0153846154);
float3 v2 = OCIO_lut3d_1.sampleLevel(TrilinearClamp, nextInd, 0). rgb;
nextInd = baseInd + float3(0., 0.0153846154, 0.0153846154);

ここからはOpenColoIOの組み込みについて説明します。
OpenColoIOの組み込みには2種類のファイルを用いました。
16
.ocioファイルは元々配布などされているOpenColorIO自体のファイルで、Display, Viewという区分に分かれて各種変換が
記述されています。
.ocioファイルや付属のLUTをDCCツールで使用しているものと同じものを使用します。
そして.ociocの方は.ocioファイルの中にある変換の中から、使用する変換を指定するファイルで、アーティストはこのファイルを
編集し使用したい変換を指定します。
この例では.ociocでACESというDisplay、sRGBというViewを指定することで、変換に必要なシェーダコード、LUT、変換行列を
事前に生成しておき、ランタイムで使用します。

©CAPCOM

16

17.

OpenColorIOの組み込み 各パスで使う.ociocファイルを指定 New Pipeline BT.709 Linear HDR Scene Render HDR PostEffect OCIO GradingPass ( BT.709 AP1 ) AP1 Linear ACEScc ACEScct LUT Exposure HDR ColorGrading BT.2446 OCIO SDR OutputPass ( RRT and ODT ) UI ( sRGB ) SDR Display OCIO HDR OutputPass ( RRT and ODT ) UI ( HDR10 ) HDR Display .ociocファイル作成したら、各変換パスで使用する.ociocファイルを指定します。 この例では、グレーデイング前の変換であるGradingPassにBT.709からAP1への変換を指定した.ociocファイルを設定。 SDRディスプレイへの変換パスである、SDROutputPassにはsRGBのRRTとODTの変換を指定した.ociocファイルを設定しています。 17 ©CAPCOM 17

18.
[beta]
OpenColorIOの組み込み
任意の色域変換を行いたい場合はソースのカラースペースをscene_linearで指定
• ルールはOpenColorIOライブラリで変更可能
.ocio

.ocioc

Roles :
scene_linear:Utility – Linear - - sRGB
texture_paint : ACES - ACEScc

“OCIOConfigPath” : “config_RenderingSpace_sRGB. Ocio”,
“DisplayName” : “ACES”,
“ViewName” : “Transform_AP1”

- !<View> {name : Transform_AP1, colorspace : ACES - ACEScg

{

float4 res = float4(outColor. rgb. r, outColor. rgb. g, outColor. rgb. b, outColor
float4 tmp = res;
res = mul(tmp, float4x4(0.61311571346586224, 0.070197158243296642, 0.0206190
outColor. rgb = float3(res.X, res. Y, res. Z);
outColor. A = res.w;

}

また任意の色域変換もサポートしています。
私たちは.ocioファイルのscene_linearで指定されているカラースペースをソースのカラースペース、指定したViewを変換先の
カラースペースとし、変換を生成できます。
18
前述したGradingPassで実行されるBT.709からAP1への変換はこの方法で作成しています。
配布されているACESの.ocioファイルのscene_linearはACES – ACEScgとなっているため、scene_linearをBT.709に変えた.
ocioファイルを複製して管理しています。

©CAPCOM

18

19.

OpenColorIO+ACESのメリット/デメリット メリット • 様々な変換が手軽に使用/共有可能 • 適切に使用すれば変換の正しさも担保されている • アップデートが容易 • エンジン側はOpenColorIOのライブラリのアップデート • アーティストは.ocioファイルのアップデート デメリット • 小回りが利かない • ACESに起因するが、RRTとODTがセットになっているのが非常に扱いづらい OpenColorIO+ACESを用いたときのメリットとしては、エンジンプログラマーの手を借りることなく、様々な変換が手軽に 使用したり共有することができる点です。 19 一度作成した設定は他のチームにも共有できるので、DCCツールだけでなくチーム間での設定も共有が容易になります。 また変換自体の正しさも担保されており、DCCツールとの変換の差異も生じない点も魅力です。 また一度仕組みを構築してしまえば、アップデートが容易な点も挙げられます。 DCCツール側がアップデートされた際に追従する場合は、エンジン側は必要であればOpenColorIOのライブラリのアップデートを 行い、アーティスト側は.ocioファイルをアップデートするだけで済みます。 挙げられるデメリットとしては、小回りが利かない点が挙げられます。生成された変換には介入しづらく、ACESの仕組みに 起因する部分ですが、特にRRTとODTがセットになっている点は扱いづらく、 後ほど説明するGUIの問題に影響しました。 ©CAPCOM 19

20.

導入の容易化 グレーデイング前に広色域化 • 導入して色域を変えたときの影響範囲を最小化 • ライティングの広色域化対応が完全にできていないのもある… グレーディングだけの広色域化でも効果はある? • 高輝度部分が飽和しづらい効果は得られる New Pipeline BT.709 Linear HDR Scene Render HDR PostEffect OCIO GradingPass ( BT.709 AP1 ) AP1 Linear ACEScc ACEScct LUT Exposure HDR ColorGrading BT.2446 OCIO SDR OutputPass ( RRT and ODT ) UI ( sRGB ) SDR Display OCIO HDR OutputPass ( RRT and ODT ) UI ( HDR10 ) HDR Display 2つ目の方針である導入の容易化として制作中タイトルに対しても、導入のインパクトはなるべく小さくするように心がけました。 その一環として、グレーデイング区間のみ広色域化するような対応が挙げられます。 20 ライティングから広色域化するのは理想ですが、制作途中のタイトルに導入した場合にライトやテクスチャなど影響範囲が 多岐に渡ります。 グレーディング直前に色域変換するパスを設けることで、広色域レンダリングは必須とはしないようにし、導入のインパクトを 最小化できるようにしました。 これは広色域のレンダリング対応が完全じゃないのもありますが…。またグレーデイングだけの広色域化でも広色域化の恩恵は 得られます。 ©CAPCOM 20

21.

BT.709 AP1 例えば明るく照らされた部分の色が飽和しづらかったり、 21 ©CAPCOM 21

22.

BT.709 AP1 飽和していて明るさの違いが分からない部分が鮮明になる、といった効果は得られます。 22 ©CAPCOM 22

23.

HDR/SDR出力の互換を容易化 アーティストはHDRファーストでグレーディング • SDR出力では全体的に明るすぎる場面が出てくる ACESのRRT+ODTではHDR/SDRの絵の互換性は担保されない • SDR出力の互換性のために別途対応が必要だった 3つ目の方針ではアーティストがHDRファーストでグレーディングした際に、SDR出力の互換を容易に取れるようにしました。 問題になったのはHDRファーストでグレーディングした際に、SDR出力では明るすぎる場面がでてきました。 23 ACESのRRT+ODTにHDR/SDRの互換性を期待してましたが、HDR/SDRの絵の互換性は完全に担保されるわけではなかったため、 SDR出力の互換性のために別途対応が必要でした。 ©CAPCOM 23

24.

HDR/SDR出力の互換性 SDR出力向けにもグレーディングしてSDR出力用のLUTも用意する? • 管理や制作の手間が大変 もっと手軽に対応したい もちろんSDR出力用に別個グレーデイングしてLUTを用意するのが理想ですが、LUTの制作や管理が単純に倍になり 現実的ではありません。 24 ©CAPCOM 24

25.

BT.2446 Method C リニア区間+ログカーブ区間からなる Exposureのスケーリング、ログカーブ始点、強さを調整 元の実装はHLGを想定しているが、AP1+Linearでも結果は良好 Reference : Report ITU-R BT.2446-1 - Methods for conversion of high dynamic range content to standard dynamic range content and vice-versa https://www.itu.int/dms_pub/itu-r/opb/rep/R-REP-BT.2446-1-2021-PDF-E.pdf そこでBT.2446というHDRコンテンツをSDRコンテンツへ変換する、放送用に考案された変換を使用しました。 いくつか変換に種類はありますが、Method Cというものを採用しています。 25 変換はシンプルでリニア区間とログカーブ区間に分かれており、アーティストはExposureのスケーリングとログカーブの始点、 強さを調整します。 元々の実装はHLGを想定しているが、AP1+Linearでも結果は良好でした。 ©CAPCOM 25

26.

BT.2446 Method C 色相保持についてはアーティストが任意に選択できるようにした • 飽和具合も制御できるようにした • 飽和を好む絵作りもあった 色相保持 ON 色相保持 OFF BT.2446 Method Cにある色相保持機能については飽和を好むアーティストや絵作りの要望あったためオプションとし、 また色相保持機能をONにしたときの飽和具合を制御できるようにしました。 26 ©CAPCOM 26

27.

BT.2446 OFF BT.2446 ON こちらBT.2446の適用例です。 HDR出力の画像との比較はできませんが、ハイライト部分以外の印象は揃えることができました。 27 ©CAPCOM 27

28.

旧パイプライン SDR出力 最終的な新パイプラインと旧パイプラインの出力の比較です。 いくつかのシチュエーションで比較してみました。 28 ©CAPCOM 28

29.

新パイプライン SDR出力 29 ©CAPCOM 29

30.

旧パイプライン SDR出力 30 ©CAPCOM 30

31.

新パイプライン SDR出力 31 ©CAPCOM 31

32.

旧パイプライン SDR出力 32 ©CAPCOM 32

33.

新パイプライン SDR出力 33 ©CAPCOM 33

34.

GUIの対応 RRTの影響を受けないようにする為にGUIの描画順番を後ろに変更 今度はGUIとシーン画像とのブレンドが問題になる New Pipeline Old Pipeline 次に新パイプライン移行にあたってGUIで生じた変更点について説明していきます。 OpenColorIOによるSDR、HDR出力時にはACESのRRTとODTがセットで1度に処理されます。 34 RRTにはフィルムルックになるようなトーンマッピングの処理が含まれており、GUIを描画した後にRRT+ODTを適用して しまっては、GUIの明るさが変わってしまいます。 そこでGUIの描画順をRRT+ODTが終わった後に変更しました。 しかし、後ろに移動したことで、今度はGUIとシーン画像のブレンド結果に問題がでてきました。 シーン画像は既にリニアではなく、それぞれのディスプレイ空間に変換されているためです。 不透明のGUIであれば、そのままディスプレイ空間に変換してGUIを描画すれば済みますが、アルファブレンドなどシーン画像と GUIがブレンドする場合は、単純にブレンドしただけでは意図しない見た目となります。 ©CAPCOM 34

35.

旧パイプラインの見た目 こちらが旧パイプラインの見た目です。 左端に並んでるのは不透明のGUIです。 右端に並んでいるのはアルファブレンドを行うGUIです。 35 ©CAPCOM 35

36.

新パイプライン 直にブレンド こちらが新パイプラインの見た目です。 不透明GUIに差はでませんが、アルファブレンドを行っているGUIの見た目は異なっています。 36 ©CAPCOM 36

37.

GUIの対応 不透明/アルファブレンドGUIは作業用バッファにBT.709+Linearで描画 • フォーマットはAチャンネルが必要なためR8G8G8A8Unorm sRGB Compute Shaderでブレンド • 不透明:ディスプレイ空間に変換して上書き • アルファブレンド:シーン画像をLinearに戻してブレンドし再度ディスプレイ空間に戻して出力 そこで不透明/アルファブレンドのGUIは、一旦作業用バッファにBT.709+Linearで描画し、Compute Shaderを使って、 シーン画像と合成しながらディスプレイ空間に変換するようにしました。 37 不透明のGUIならばディスプレイ空間に変換して上書きします。 アルファブレンドのGUIならば、シーン画像を一旦リニアに戻してからGUIとブレンドし、ディスプレイ空間に戻して出力します。 なお不透明のGUIも作業用バッファを経由しているのは、不透明とアルファブレンドのGUI同士がブレンドしたときの結果を 正常化するためです。 ©CAPCOM 37

38.

旧パイプラインの見た目 対応の結果比較です。 こちらが旧パイプラインの見た目です。 38 ©CAPCOM 38

39.

新パイプライン 直にブレンド 対応の結果比較です。 こちらが新パイプラインで作業用バッファを経由して合成した結果 39 ©CAPCOM 39

40.

新パイプライン 対応前 40 ©CAPCOM 40

41.

加算合成は? アーティスト的にはシーン画像との合成結果はあまり重視しない 加算合成だけは直接描画 • 移行に当たって見た目の調整をしてもらった 加算合成に関しては、あくまで弊社のGUIアーティスト的にはなりますが、シーン画像との合成結果の整合性については あまり重視せず、加算合成だけは直接シーンに描画しています。 41 パイプライン移行にあたっては加算合成のGUIの見た目は調整してもらうことになりました。 ©CAPCOM 41

42.

RRT+ODTが遅い PS4+1080pで2.2ms程度 常に処理される処理のため高速化は必須 次に最適化の話に移ります。 RRT+ODTのパスに関しては、OpenColorIOから生成されたシェーダコード、およびLUTを使用した場合、PS4+1080p 42 で 2.2ms程度かかっていました。 RRT+ODTはゲーム中常に処理されるため、常に2.2msの負荷が乗ってしまうのは耐えられるものではありません。 ©CAPCOM 42

43.

LUTにランタイムベイク RRT+ODT+明るさ調整処理をベイク サイズは64x64x64 フォーマットはR10G10B10A2Unorm • RRT+ODT後は1を超えないためUnormでOK シェーパーはACESccを選択 • 目視では差が分からなかったため選択 同環境で2.2msが0.4ms程度へ短縮 • ベイクには0.12ms程度 そこでランタイムでRRT+ODT、ついでにゲーム内の明るさ調整の処理を一緒にLUTにベイクして使うことにしました。 .ociocファイルの変更や明るさ調整用パラメタの変動を検知したら、1フレームだけLUTのベイク処理が動作します。 43 LUTのサイズは64x64x64、フォーマットはR10G10B10A2 Unormです。 RRT+ODT後の値は0~1に収まっているためUnormフォーマットを使うことができます。 LUTへのシェーパーとしては目視で差が分からなかったため、ACESccを選択しました。 これでPS4+1080pの環境でRRT+ODTが2.2msかかっていたのが、0.4ms程度に短縮できました。 また変更検知して1フレームだけ処理されるベイク処理は0.12ms程度で済みます。 ©CAPCOM 43

44.

色域変換パスの削除 BT.709→AP1の変換が独立したパスとして動作していたのを削除 • Exposureやカラーグレーディング処理が動作する場合はそれらに統合 New Pipeline BT.709 Linear HDR Scene Render HDR PostEffect OCIO GradingPass ( BT.709 AP1 ) AP1 Linear ACEScc ACEScct LUT Exposure HDR ColorGrading BT.2446 OCIO SDR OutputPass ( RRT and ODT ) UI ( sRGB ) SDR Display OCIO HDR OutputPass ( RRT and ODT ) UI ( HDR10 ) HDR Display また色域変換パスはOpenColorIOから生成されたシェーダをそのまま使い、単なる色域変換だけを行うパスが独立しており、 PS4Base+1080pの環境では0.2ms程度かかっていました。 44 Exposureやカラーグレーデイング処理を行う際はそれらのパス内で色域変換を動作させることで、パスの統合を行いました。 ©CAPCOM 44

45.
[beta]
色域変換パスの削除
変換行列はOpenColorIOのライブラリから取得
• 最初は生成されたシェーダコードをパースして取得していたが、ToXYZの行列など細かい変換が欲しくなったので辞めた
//変換行列の取得
auto matList = std : : vector<OCIOMat4>();
for (int i = 0; i < transformNum; ++i)
{
const auto transformFromMetaData = groupTransform->getTransform(i);
const auto type = transformFromMetaData->getTransformType();
if (type == OCIO : : TransformType : : TRANSFORM_TYPE_MATRIX)
{
const auto transform = OCIO : : DynamicPtrCast<const OCIO : : MatrixTransform>(transformFromMetaData) ;
double m44[16] ;
transform->getMatrix(m44) ;
matList. push_back (m44) ;
}
}

FOCIOTransform
▶R0
▶R1
▶R2

{…}
{0.616116, 0.0701972, 0.0206191, 0}
{0.33951, 0.916355, 0.10958, 0}
{0.0473748, 0.0134491, 0.869801, 0}

色域変換の行列に関しては、最初は生成されたシェーダコードをパースして行列を得ていましたが、
現在のカラースペースから目的のカラースペースへ変換する行列だけでなく、XYZ空間への変換行列も必要になった
ケースがあったので、OpenColorIOライブラリのAPIを経由して取得するようにしました。
45

©CAPCOM

45

46.

LinearToACESccの分岐を削除 LUTへのシェーパー目的なら負の条件分岐は無視できる if (value <= 0 && !ignoreNegativeValue) return -0.358447; else if (value < pow(2, -15)) return 0.554795 + 0.0570776 * log2(pow(2, -16) + value / 2); else return 0.554795 + 0.0570776 * log2(value) ; 46 ©CAPCOM 46

47.

ACESccToLinearの分岐を削除 同じく負の値による条件は無視 if (value <= -0.30137 && !ignoreRestrictCondition) return pow(2, 17.52 * value – 8.72) – pow(2, -15); else if (value < 1.468 || igonoreRestrictCondition) return pow(2, 17.52 * value – 9.72); else return 65504; 47 ©CAPCOM 47

48.

アーティストのグレーディング環境 ライブグレーディング • エンジンからAP1+ACEScc /ACEScctの映像を出力しDCCツールに流す LUT作成の流れ RE ENGINE AP1 + ACEScc / ACEScct + Exposure Capture board DaVinci Resolve Grading Export LUT 最後になりますが、アーティストのグレーディング環境の紹介や今後の展望で締めたいと思います。 弊社アーティストのグレーディング環境は、エンジンの映像をDaVinci Resolveに送り、ゲームを動かしながらグレーディングを 48 行うライブグレーディングの方式をとっています。 メリットとしてはやはりゲーム動かしながら見た目の調整・確認ができるため、イテレーションに優れる点が挙げられます。 LUT作成までの流れとしては、 ライブグレーディングを行うPCにはグラフィックボードとは別に、エンジンの映像を送るために キャプチャボードを備えていて、エンジンはAP1+ACEScc /ACEScct、そしてExposureを適用した、グレーディング処理直前の 状態の映像を出力し、Davinci Resolve側はキャプチャボード経由で送られてきた映像を受け取って、その映像をソースとして グレーディングをします。 ©CAPCOM 48

49.

今後の展望 Reference Gamut Compression(RGC)の活用 • OpenColorIO 2.1.0からBuiltin Transformとして選択可能 色域外の色を色域内に圧縮 • パラメタで圧縮具合を制御できる RGC OFF RGC ON ACES Technical Documentation "ACES Reference Gamut Compression Implementation Guide" June 16, 2022 https://docs. acescentral.com/guides/rgc-implementation/#parametricversion-implementation-specifications(August 24, 2023) 今後の展望としては、ACESのReference Gamut Compressionの活用です。 Reference Gamut Compressionとは色域外の色に対しての補正機能で、元々ACESにあった色域外の補正機能である 49 Blue Light Artifact LMT(Look Modification Transform)を廃止し、置き換える目的で制作されました。 OpenColorIOでは2.1.0のバージョンから利用可能で、Builtin Transformから選択することで利用することができます。 スライド右側の画像はDaVinci Resolveの設定画面ですが、各種パラメタで圧縮の閾値や圧縮具合を制御できるようになっています。 ©CAPCOM 49

50.

今後の展望 ライティングの広色域化 • アルベドやライトの変換土台はある程度できあがあってる IBL、ライトプローブ、ローカルキューブマップなど プリベイク系のライティングアセットの扱いが未策定 • 過去タイトルとの互換性 またライティングの広色域化が挙げられます。 アルベドやライトの変換する土台は構築できていますが、IBLやライトプローブといったプリベイク系のライティングアセットの 50 扱いが未策定です。 現在稼働しているタイトルだけでなく、過去タイトルとの互換性も考慮する必要があって手が出せていませんので、 この辺りを解決してライティングの広色域化を行いたいです。 HDRGradingに関しては以上となります。ありがとうございました。 ©CAPCOM 50

51.

手軽にモフモフフサフサ! ShellFur機能紹介 本セッションは、RE ENGINEにおいて、ファー表現についてどう取り組んだかを、発表させていただきます。 ©CAPCOM 51

52.

目次 ファーの手法について ShellFurの基本コンセプト説明 高品質なファーに必要なShellFur機能紹介 ShellFur最適化手法 まとめ アジェンダです。 ファー表現の手法について説明、機能紹介、最適化事例、まとめの順番で発表します。 52 ©CAPCOM 52

53.

目次 ファーの手法について ShellFurの基本コンセプト説明 高品質なファーに必要なShellFur機能紹介 ShellFur最適化手法 まとめ 始めに、ファー表現を行うにあたって、どの手法を使ったのか、またなぜ選んだのかを説明します。 そしてShellFurの、基本的な仕様についてお話しします。 53 ©CAPCOM 53

54.

ファーの手法について ファーの要件 • 従来の制作フローではアーティストが積層 化したMeshを用意していた プログラマブルに生やしてほしい • 自動で処理コストのコントロールをしてほ しい アーティストが自前で メッシュを積層化していた • 大量に生やしたい 大量のキャラを生やしたい 従来のファー制作フローでは、アーティストが、積層化したメッシュを用意していました。 画像は、バイオハザードビレッジの主人公のジャケットと、モンスターハンターライズのポポです。 54 メッシュアセットを積層化してしまうと、メモリの増大に、処理コストのコントロールがしずらい、という状況がありました。 課されたファーの要件です。 プログラマブルに生やしてほしいことと、自動で処理コストコントロールをすること、大量に表示できること、大量のキャラに 生やせられることでした。 省メモリ、省コストな手法を選ぶ必要がありました。 ©CAPCOM 54

55.

ファーの手法について ShellFur Meshを積層させ、AlphaTestで毛を輪切りに描画しファー表現 HairCard 短冊状のポリゴンをMesh表面に生やし、AlphaTestで毛の束単位に描画しファー表現 Strand 毛を一本一本描画する方法 ( 同カンファレンス 『 BIOHAZARD RE:4の髪の毛解説』講演にて詳細) さて、リアルタイムレンダリングにおいてファー表現を行う手法は幾つかあります。 例を挙げます。 まず最初に出てくるのは、本セッションの主題でもあるシェルファーです。 メッシュを積層させ、毛を輪切りにしたように、アルファテストで抜くことでファー表現します。 55 次に挙げられるのは、ヘアカードです。主に髪の毛表現ではよく使われます。 短冊状のポリゴンを、メッシュ表面に生やし、束単位で髪の毛を描画してファー表現します。 最後にストランドです。毛を一本一本描画する方式です。 詳しくは同カンファレンスのセッション『BIOHAZARD RE:4の髪の毛解説』にて発表されますので、ここでは触れる程度にします。 ©CAPCOM 55

56.

ファーの手法について ShellFur Meshを積層させ、AlphaTestで毛を輪切りに描画しファー表現 HairCard 😄生やす面積に対して処理コストが安い 短冊状のポリゴンをMesh表面に生やし、AlphaTestで毛の束単位に描画しファー表現 😄元Meshの頂点バッファを再利用できる Strand 😞輪切り感が出ないか心配 毛を一本一本描画する方法。 ( 同カンファレンスのRE:2023 StrandLighting , StrandRasterにて詳細) 今回はShellFurを選びました。 理由としていくつか在りましたが、大きくは、元メッシュの頂点バッファを、再利用できる点です。 シーンに、大量に出したいという要望があるので、何よりもメモリにやさしい手法ということで選びました。 ©CAPCOM 56 56

57.

ファーの手法について ShellFur Meshを積層させ、AlphaTestで毛を輪切りに描画しファー表現 ShellFurの仕様をおさらいします。 仕組みはかなり簡単です。メッシュをミルフィーユのように積層して、描画します。 57 積層したメッシュは、等間隔に法線方向に押し出し、毛を輪切りにするように、AlphaTestでポリゴンを抜くことで、 ファー表現します。 画像を見てもらうとわかりますが、仕組み上横からみると輪切りが目立ちます。 これがShellFur最大の欠点でもあります。 ©CAPCOM 57

58.

ShellFurの歴史 古くはPS2時代から 次世代ハードでも採用 『3Dゲームファンのための「ワンダと巨像」グラフィックス講座』 GAME Watch 2005年12月7日 https://game.watch.impress.co.jp/docs/20051207/3dwa.htm (アクセス日 2023/7/6) 『ワンダと巨像』 ソニー・インタラクティブエンタテインメント 2005年 『『ラチェット&クランク パラレル・トラブル』開発秘話——新キャラクターや新システムはこうして 生まれた!』 PlayStation.Blog 2021年5月12日 https://blog.ja.playstation.com/2021/05/12/20210512-ratchet/ (アクセス日 2023/7/6) 『ラチェット&クランク パラレル・トラブル』 ソニー・インタラクティブエンタテインメント 2021年 ちょっとShellFurの歴史に触れます。 歴史は古く、プログラマブルシェーダが使えないハードから、実現可能なファー表現として利用されていました。 58 有名なタイトルでは『ワンダと巨像』です。当時から、画面を覆いつくすほどの巨像に、大量に生やされてました。 古くからの技術ですが、現行機ハードでも、採用例があります。右の画面は『ラチェット&クランク パラレル・トラブル』です。 ラチェットの体に生えてるファーは、ShellFurと同じ仕組みで描画されています。輪切り感が全く見えませんね。 ハードスペックの向上で積層枚数は格段に多くなっておりますが、基本コンセプトは同じです。 このクオリティを、大量のキャラクターで出すのを目指しました。 ©CAPCOM 58

59.

目次 ファーの手法について ShellFurの基本コンセプト説明 高品質なファーに必要なShellFur機能紹介 ShellFur最適化手法 まとめ 安さが売りのShellFurですが、輪切り感を出して、安っぽい見た目を出すわけには行きません。 次は、高品質にするために用意した機能を、紹介します。 59 ©CAPCOM 59

60.

ShellFur機能紹介 ・積層数の動的変化 ・どんなMeshもフサフサに ・毛並みを表現するためのグルーミング機能 ・Simulation機能 ・幅広いアート要望に応えるため、頂点シェーダに対応 RE ENGINEのShellFurの機能を、5つの項目別に紹介します。 60 ©CAPCOM 60

61.

ShellFur機能紹介 積層数の動的変化 • カメラの距離に応じて積層数を増減 • カメラアップにも耐えうる • 自動的に処理コストがスケーリングするので、 積極的にシーンに複数配置できる ShellFurを実装する上で、一番求められていたものが、この積層数の動的変化でした。 ShellFurの弱点である、輪切り感を軽減させるために、愚直に積層数を増やす方向で対処しました。 61 カメラアップ時は、最大積層数で描画し、距離が離れるにつれて、積層数を削減することで、実行処理コストの軽減を図っています。 自動的に処理のスケーリングを行うので、積極的にファーをシーンに複数配置するために、もっとも重要な機能です。 ©CAPCOM 61

62.

ShellFur機能紹介 積層数の動的変化 • 削減方法は3種類を検証 毛先から削減 根元から削減 1つ飛ばしで間引いていく 1 5 1 2 4 4 3 3 2 4 2 5 5 1 3 😄輪切り感が出ない 😄シルエットが崩れにくい 😕シルエットはある程度保つ 😞シルエットが崩れがち 😞なんか隙間見える 😕輪切り感が結構出る 実装に当たって積層の削減方法を3種類ほど検証しました。 毛先から削減タイプ、根元から削減タイプ、1つ飛ばしで間引いていくタイプです。 62 1つ飛ばしで間引いていくタイプは、奇数層の毛先から間引いていき、根元まで来たら偶数層を消していくという方法です。 実装当初はファーのシルエットを保ちつつ、極力輪切り感を無くす削減方法は、3番目の間引き方法が一番いいかなぁと 思っていました。が、結果ですが、ファー表現においては、一番目の毛先から削減、が最も見た目に違和感がありませんでした。 ShellFur手法において、チープ感が出るのは、輪切り感が一番のネックでして、シルエットに関しては、モコモコ感さえ 残っておけば問題ない、ということでした。 実装する際に参考になればと思います。 ©CAPCOM 62

63.

ShellFur機能紹介 どんなMeshもフサフサに • ShellFurはインゲームのGameObjectに 付加させるComponent機能として用意 • ShellFur機能さえ付ければ どんなものでもファー描画するように MeshAssetには特別な設定は必要なし ※画像のアセットはモンスターハンターライズで登場したアイルーを利用しています。 ファー機能を付けたアイルーは実際のゲームには登場しません。 ShellFurは極力難しい設定なく、扱えるようにを心がけました。 GameObjectに付加するComponent機能として用意していて、付け替えを容易にしています。 63 元のメッシュアセットは特に弄る必要はなく、基本的にはどんなメッシュにでも、生やせるようにしています。 画像はモンスターハンターライズで登場したアイルーに、検証でファーを付けてみたものです。 ©CAPCOM 63

64.

ShellFur機能紹介 どんなMeshもフサフサに • ShellFur機能自体は積層することのみ • AlphaTestしてファー描画するのは Shader側 単純にShellFur機能を付けただけ。 Shaderで毛を輪切りにAlphaTestしたもの。 機能の分離をしています。 メッシュを積層するのはShellFurコンポーネント側、毛を輪切りにしてAlphaTestするのはマテリアル側としました。 64 元々アーティストが自前で用意していた、積層メッシュの時のマテリアルがあったので、それらを活用できるようにしました。 ©CAPCOM 64

65.

ShellFur機能紹介 毛並みを表現するためのグルーミング機能 ただ生やすだけでは、ファー表現には程遠いです。 毛並み感を表現するために、グルーミングツールを作成し、エンジン上でペイントする機能を、実装しました。 65 ペイントツール機能の詳細は、同カンファレンス、『エンジン上でのライブペイントツールの作成とその取り組み』の セッションで発表されます。 ここでは簡単に、短い紹介動画を流します。 ©CAPCOM 65

66.

ShellFur機能紹介 グルーミングツールは毛の長さ、毛の流れをペインティング出来るツールです。 シミュレーション時の毛の動きなど、細かいファーパラメータの調整を、エンジン上で行えることが特徴です。 ©CAPCOM 66 66

67.

ShellFur機能紹介 毛並みを表現するためのグルーミング機能 • グルーミング情報はTextureに保存 R FlowX G FlowY B FurLength • 曲がり適用は2つのパラメータで制御 • 毛先にかけて曲がりやすく • 根元のみ曲がる フロー方向 フロー方向 グルーミングツールには、グルーミングテクスチャの、ペイント機能が備わっています。 テクスチャにフロー情報とファーの長さ情報を仕込みます。 頂点シェーダでグルーミングテクスチャをフェッチし、フロー方向に頂点アニメーションさせます。 67 毛の曲がり方は、毛先にかけて強く曲がる方式と、根元のみ曲がる方式の、2つを制御するパラメータを用意して、適用しています。 ©CAPCOM 67

68.

ShellFur機能紹介 Simulation機能 • モーション、重力、風などから影響を受けて Simulation • Simulationは1頂点毎に1本の毛と見立てて、 XPBDを参考に実装 [MBMJ07] Position based dynamics, Journal of Visual Communication and Image Representation, Volume 18, Issue 2, April, 2007 https://matthias-research.github.io/pages/publications/posBasedDyn.pdf [MMN16] Miles Macklin, Matthias Muller, Nuttapong Chentanez: XPBD: positionbased simulation of compliant constrained dynamics, Motion, Interaction and Games (MIG 2016) https://matthias-research.github.io/pages/publications/XPBD.pdf • 体毛用と割り切ってMesh表面、 毛同士のあたりはカット シミュレーション機能の紹介です。 モーションや重力、風などから影響を受けてシミュレーションします。こちらはオン/オフ出来るようになっています。 68 実装方法はいたってシンプルで、積層されている頂点を、一本の毛と見立てて、ストランドシミュレーションをします。 シミュレーション計算は、extended Position Based Dynamicsを参考に実装しました。 処理コストの安さを重視しているので、毛同士の当たりと、地肌との当たりは、カットして実装しました。 短い体毛向けに作られているので、こんなものでいいでしょう。 ©CAPCOM 68

69.

ShellFur機能紹介 Simulation機能 設定された毛並み 現在の速度を保持 バネ係数、減衰値に 応じて位置を修正 拘束条件 Simulationしているファー 毛は根元から単一拘束なので 根元から順番に解いて行くだけでOK Mesh表面 簡単に、どのように実装したかを説明します。 各頂点には、現在の速度を保持させます。質量は一本の毛で均等ということで、無視しています。 69 先ほどの説明した、グルーミングで設定した毛並み情報を、拘束条件としまして、設定されたバネ係数、減衰値に応じて、 最初の毛並みに位置を補正するように計算します。 グルーミングで癖毛を作るようなイメージですね。 拘束条件は、根元から毛先にかけて、単一方向にしかないので、根元から順番に解いて行くだけで、問題ないです。 ©CAPCOM 69

70.

ShellFur機能紹介 幅広いアート要望に応えるため、頂点シェーダに対応 • グルーミングテクスチャだけでは 単一方向の傾き具合しかサポートできないが、 頂点シェーダで積層単位で操作することが 出来るので表現の幅は広がる • エンジン機能のシェーダエディタ上では 頂点シェーダとして扱っているが、 実際はコンピュートシェーダで頂点変形 • 出力した位置を拘束条件として Simulationと併用可能 ファーのピクセルシェーダは、シェーダエディタで自由に、アーティストがカスタマイズできるようにしていました。 毛並みももっと自由に調整したい、という要望が出てきました。 70 用意していたグルーミング機能だけでは、一本の毛に対して、単一方向の傾き具合しかサポートできないです。 頂点シェーダに対応することで、頂点の層ごとに操作できるようになりました。 エンジンのシェーダエディタ上では、頂点シェーダとして扱っていますが、ShellFurの時だけコンピュートシェーダで、 頂点変形するようにしています。 また、その頂点シェーダで変形した位置を、拘束条件として扱い、シミュレーションを併用して扱えるようにもしました。 ©CAPCOM 70

71.

ShellFur機能紹介 結果 これら機能を活用して、アーティストに用意してもらった結果です。 積層感がなくフワフワモフモフな、高品質ファーの要望を、ある程度満たせたかなと思います。 また、これらはシーンで積極的に配置されています。 ©CAPCOM 71 71

72.

目次 ファーの手法について ShellFurの基本コンセプト説明 高品質なファーに必要なShellFur機能紹介 ShellFur最適化手法 まとめ 最適化についてお話しします。 72 ©CAPCOM 72

73.

ShellFur最適化手法 ・Instancing、MDIを利用し一括描画 ・OcclusionCulling ・メモリ削減 一括描画、オクルージョンカリング、メモリ削減の3つの項目に分けてお話しします。 73 ©CAPCOM 73

74.

ShellFur最適化手法 Instancing、MDIを利用し一括描画 • Instancing ShellFurは単純なMeshの複製 Instansingにもってこい ArgumentBufferのInstanceCountに積層枚数を設定 頂点シェーダで毛先方向にオフセット オーバードローを極力防ぐため毛先層から描画 struct DrawIndexedInstancedArguments { uint IndexCountPerInstance; uint InstanceCount; uint StartIndexLocation; uint BaseVertexLocation; uint StartInstanceLocation; }; InstanceCountのみ可変。 他パラメータは通常描画と同じに インスタンスドロー、または、マルチインダイレクトドローを利用して、一括描画します。 ShellFurは、元メッシュを毛先方向に広げて描画すればいいので、インスタンスドロー描画にもってこいです。 74 積層枚数分のインスタンスカウントを設定し、頂点シェーダで毛先方向にオフセットします。 描画順番は、極力オーバードローを防ぐために、毛先方向から描画するようにします。 ©CAPCOM 74

75.

ShellFur最適化手法 Instancing、MDIを利用し一括描画 • Instancing 😄Instancingでは元メッシュを再利用できるのでメモリには優しい 😞グルーミング計算結果をキャッシュ出来ないので頂点シェーダコストには厳しい • MDI 積層枚数分の頂点バッファを確保し、グルーミング計算結果をキャッシュする 積層毎にArgumentBufferを分けてMultiDrawで描画 😄グルーミング計算をキャッシュ出来るので、頂点シェーダコストには優しい 😞積層枚数分の頂点バッファを確保するのでメモリには厳しい 2タイプを用意して対応 インスタンスドローは、メモリを消費することなく描画出来るので、メモリには優しいです。しかし、グルーミングによる 頂点移動量を保持できず、頂点シェーダで、毎回グルーミング計算をする必要があり、頂点シェーダコストが、肥大する デメリットがあります。 75 そこで、積層枚数分頂点バッファを作成して、グルーミング計算をキャッシュすれば、頂点シェーダコストには優しくなれます。 ただ、どうしても積層枚数分の頂点バッファを、確保するので、メモリには厳しくなってしまいます。 インスタンスドローで行う、メモリにやさしいタイプと、マルチインダイレクトドローで、処理コストにやさしいタイプ、 2タイプを用意して、適時設定を、調整してもらうようにしました。 シミュレーション機能を利用している場合は、積層分頂点データを保持する必要があったので、強制的にマルチインダイレクト ドローモードで描画します。 ©CAPCOM 75

76.

ShellFur最適化手法 MDI ArgumentBufferをShellでまとめ、 DrawCall時のMaxCommandCountに描画する積層枚数を指定 通常Meshの頂点バッファレイアウト LOD0 MatA LOD1 MatB MatA LOD2 MatB MatA ‥ MatB ‥ MDIの頂点バッファレイアウト LOD0 Shell0 MatA LOD1 Shell1 MatB MatA MatB Shell2 MatA LOD0_MatA DrawArgs DrawArgs Shell0 MatB MatA MatB Shell1 MatA LOD0_MatB DrawArgs DrawArgs DrawArgs ‥ Shell2 MatB MatA MatB LOD1_MatA DrawArgs DrawArgs DrawArgs ‥ ‥ ‥ DrawArgs ‥ マルチインダイレクトドローの場合の、頂点バッファレイアウトと、アーギュメントバッファのレイアウトを説明します。 マルチインダイレクトドロータイプの、頂点バッファレイアウトの場合、LODとマテリアルの数に、それぞれ積層枚数分の 76 頂点バッファが必要になります。 真ん中のマトリックス図のような感じで頂点バッファ確保します。 一番上が、通常メッシュの頂点バッファレイアウトです。 比較するとわかりやすいですが、積層枚数分乗算で増えているのが分かります。 アーギュメントバッファを、LODとマテリアル数×積層枚数分の、配列で用意し、同じLOD,マテリアルで、積層順にまとめます。 あとは描画時に、描画したいLODとマテリアルの、アーギュメントバッファオフセットを設定し、マックスコマンドカウントに、 描画したい積層枚数を指定します。これで1ドローでShellFur描画できました。 ©CAPCOM 76

77.

ShellFur最適化手法 Instancing、MDIを利用し一括描画 Instancing MDI VRAM消費量 ( 積層16 ) 0MB 3.18MB VRAM消費量 ( 積層32 ) 0MB 7.72MB GPU負荷 ( 積層16 ) 1.2ms 1.0ms GPU負荷 ( 積層32 ) 2.5ms 2.0ms 測定条件 ・頂点数6097 ・全積層描画時測定 ・解像度1920x1080 ・測定プラットフォームPS4 タイプ別の測定結果です。 インスタンスドローは、メッシュアセットの頂点バッファを利用できるので、追加メモリはありません。 77 マルチインダイレクトドローの場合は、頂点数6000程度で、積層数16の場合、3MBのVRAMを消費してしまいます。 本来なら8MB程になるのですが、とある対応でメモリ消費を抑えています。 メモリ削減については後述します。 頂点計算をキャッシュ出来ない分、インスタンスドローは約2~2.5割増の、GPU負荷がある、という感じです。 この測定は、全ての積層が描画されている状態で、画面占有率多めで撮ったものなので、かなり重めではあります。 ©CAPCOM 77

78.

ShellFur最適化手法 OcclusionCulling • バウンディングボックスはベースMeshより毛の長さ分 だけ引き延ばす • ShellFurは特に頂点数の多さ、またAlphaTest でもあるのでOcclusionCullingの効果が大きい • Cullingついでに距離に応じた積層枚数を計算し、 CountBufferに入れる (Instansingの場合はInstanceCountに入れる) オクルージョンカリングは、ShellFurの最適化においてかなり重要です。 ShellFurは特に、頂点数が多くなりがちなのと、アルファテスト描画の塊なので、描画面積に対して、高コストになりやすいです。 78 事前に描画を無効化することは、効果が大きいです。 判定するバウンディングボックスは、ファーの最大長に伸ばしておけば、はみ出すことはありません。 オクルージョンカリング判定時に、距離に応じた積層枚数を算出しておき、その値をカウントバッファに入れることで、 GPUドリブン化出来ます。 ©CAPCOM 78

79.

ShellFur最適化手法 メモリ削減 • 愚直に積層枚数分頂点バッファを確保すると元VertexBuffer×積層枚数に… 積層枚数はカメラの距離で可変するので、LOD毎で最大積層数を最小限に LOD LOD0 積層数 8 LOD1 7 6 LOD2 5 4 3 LOD3 2 1 0 ※LOD0~1間では積層数は可変しない仕様 • Material単位で生やしたい箇所のVertexBufferのみを確保 …などを行い初期と比べて1/2以下に マルチインダイレクトドロー利用した場合は、メモリを確保するのは致し方ないことですが、 メモリダメージが大きかったので、対処する必要がありました。 79 ShellFurは、カメラ距離に応じて、積層数を可変する仕様があったので、LOD毎に必要最低限の積層数だけ、頂点バッファを 確保するようにしました。 積層数が最大で8の場合は、LOD0は8、LOD1は7、LOD2は4、といった感じです。 また、ファーは、マテリアル単位で、生え分けを判定できるので、必要なマテリアル部分の頂点にのみ、バッファ確保しました。 ほかにも細かい対応をしていって、初期に対応したころと比べて、2分の1以下にメモリ確保量を、抑えることが出来ました。 ©CAPCOM 79

80.

目次 ファーの手法について ShellFurの基本コンセプト説明 高品質なファーに必要なShellFur機能紹介 ShellFur最適化手法 まとめ ではまとめです。 80 ©CAPCOM 80

81.

まとめ 古くからある技術だが、積層数の可変、 グルーミング等で高品質なファー表現が出来た 展望 現状はファー専用機能だが、積層描画技法は苔表 現などの別表現に利用できる可能性がある ShellFurは、古くからある枯れた技術ですが、積層数の可変や、グルーミングによる毛並み感の表現、などにより高品質な ファーを表現できました。 81 展望ですが、現在はファーを作ることに、特化した機能として用意しておりますが、積層描画技法は、他にも苔表現や、 凹凸表現など、別の表現に利用できる可能性を感じました。 このセッションが何かの参考になれば幸いです。 私の発表を終わらせていただきます。 ©CAPCOM 81

82.

Signed Distance Fieldの 導入と最適化 次のトピックは、Signed Distance Fieldの導入と最適化についてです。 ©CAPCOM 82

83.

目次 Signed Distance Field (SDF)の導入理由 活用事例 データ構造 最適化 今後の展望 発表の流れは、この通りです。 最初に、Signed Distance Fieldを導入するに至った経緯をお話しします。 83 続いて、具体的な活用事例を紹介します。 その後、SDFがどのようなデータとして表現されているかについての説明と、直面した課題やそれに対する最適化について お話しします。 最後は、今後の展望についてお話しします。 ©CAPCOM 83

84.

背景 これまでのRE ENGINEでは、 光源や物体が動かない前提の, 事前ベイクのアセットを多用していた • Sparse Shadow Tree や Light Map など 時間変化のあるゲームで使用可能な新しい手段が必要になった • Ray Tracing または Signed Distance Field まず、導入に至った背景から紹介いたします。 これまでのRE ENGINE製のゲームは時間変化が無いものが多く、Sparse Shadow TreeやLight Mapなど、光源が動かないことを 84 前提とした方法が使われていました。 ところが、時間変化のあるオープンワールドのゲームを作るため、事前ベイクが不要な新しい手段を提供する必要が出てきました。 昨今では事前ベイク不要な照明の手段としてリアルタイムレイトレーシングが注目されています。 その一方で、現在普及しているハードウェアの性能ではレイトレーシングをフル活用しづらいという現実もあります。 その代わりに、Signed Distance Fieldを使った軽量な手段を開発することになりました。 ©CAPCOM 84

85.

Signed Distance Field (SDF) とは 物体までの距離が定義された場のこと 表面が近ければ 正, 裏面が近ければ 負 の値 表面(0) 外側(正の値) 内側(負の値) まず、Signed Distance Fieldについて簡単に説明します。 長いため、以降はSDFと省略します。 SDFとは、任意の座標に対して、最も近い表面までの距離が定義された場のことです。 85 物体の外側であれば正の値、内側であれば負の値、そして表面の所で丁度0になります。 ©CAPCOM 85

86.

SDFを利用したレイマーチ SDFから値を取得してその距離だけレイを進める, というシンプルな操作の繰り返し Light SDFからは物体を貫通せずに進める最大の距離を取得でき、それを用いて効率的にレイマーチを実行できます。 例えば、この矢印の先端までレイが進んでいる状態だとして、その地点でのSDFが示す可動範囲がこの円の範囲です。 86 光源に向かうレイなので、ここまでレイを進めます。次のステップでも同じように、SDFから距離を取得して、その分だけレイを 進めます。このまま、同じ操作を繰り返します。 この地点ではSDFから取り出した値が壁までの最短距離のため、そのまま進めると丁度壁に衝突しました。壁表面ではSDFの値は 0のため衝突判定になり、光源が遮られていることが分かりました。このようにシンプルな操作で効率的にレイマーチができるため、 動的な影などに利用しています。 ©CAPCOM 86

87.

SDFの活用事例 SDF Shadow SDF Ambient Occlusion その他 続いて、RE ENGINE内でのSDFの活用事例を紹介します。 87 ©CAPCOM 87

88.

SDF Shadow 遠景の影を動的に生成 範囲は4000メートル程度を想定 まず、SDF Shadowについて説明します。 SDF Shadowは、Directional Lightで使用できる、遠景用の動的シャドウという位置づけになっています。 88 エンジン利用者からの要望に応え、4000メートル程先までを処理できるような想定で設計しました。 ©CAPCOM 88

89.

SDF Shadow 3ステップのCompute Shaderで構成されている • インスタンス数に依らずドローコール数が固定 Shadow Mapを描いている裏でAsync Compute Draw Shadow Maps SDF Shadow Tile Classification Instance Culling Draw Shadow SDF Shadowは主に3つのステップで構成されています。 最初に、画面のそれぞれのタイルがSDF Shadowの適用範囲かどうかを調べます。 89 次に、そのタイルからライト方向にレイを伸ばした結果、衝突する可能性のあるSDFだけを列挙します。 最後に、それらの情報を基にSDF Shadowを描画します。 ここでは、見えているピクセルを起点にして、光源方向へSDFを手掛かりにレイマーチして遮蔽を調べます。 物量に関わらず、この3回のCompute Shaderだけなので、ドローコールが少なくてCPUに優しいです。 また、Shadow Map等を処理している裏でAsync Computeで実行されています。 そのため、処理負荷を隠蔽しやすいことも強みです。 ©CAPCOM 89

90.

SDF Shadow Cascade Shadow Map • • • • 近景で高精度 解像度をとても大きくしないと, 遠景で精度が悪い 含まれる頂点数が多すぎて, 処理が重くなりがち カメラから見えない部分が無駄になりやすい SDF Shadow • 可視ピクセル分だけ処理するので無駄が少ない • 遠景まで広げても, 極端にぼやけることが無い • SDFの精度に依存するため, 近景で粗さが目立つ 広範囲の影を表現する方法として、Cascade Shadow Mapと比較します。 Cascade Shadow Mapでは、近景の影をとても詳細に表現することができます。 90 しかし、4000メートル先までShadow Mapを適用しようとすると、遠景部分は非常にぼやけた影になってしまいます。 また、投入される頂点がとても多くなるため、処理が重くなりがちです。 一方、SDF Shadowでは見えているピクセルの分だけ実行されます。 処理するピクセルの数が少ないため、毎フレーム更新しても重くなり辛いことが強みです。 また、Shadow Mapを経由しないため、遠景でも一定の精度を保つことができます。 弱みとしては、SDFの精度に依存しているため、近景ではディティールが損なわれている印象が目立ちます。 ©CAPCOM 90

91.

SDF Shadow 近景はCascade Shadow Map, 遠景はSDF Shadow と使い分けている これらの強みと弱みを踏まえ、RE ENGINEでは二種類の影を使い分けています。 この画像の青く塗られた部分がSDF Shadowの適用範囲で、それより手前がCascade Shadowになっています。 91 SDF Shadowは遠景用の影と割り切って作っており、低精度なSDFを参照するぼんやりとした影になっています。 Soft Shadowのため遠くから見ると粗さは気になりませんが、近景には不向きです。 遠景をSDFに任せる代わりに、Cascade Shadow Mapを手前側に集中させる余地ができました。 そのため、結果的に近景の影の品質向上にもつながりました。 ©CAPCOM 91

92.

SDF Shadow SDF Shadowの描画面積は 広くても画面の半分程度 • インスタンス数1万個のシーンだと 視界が開けた箇所で2.5ms(PS4) 遠景を遮るものが多いほど高速 • 森や街の中では0.5ms以内 操作キャラクターの目線の高さで見ると、SDF Shadowの描画面積は広くても画面の約半分になります。 その時の性能に関して言及すると、SDF Shadowの処理時間はPS4で概ね2.5ms程度になりました。 92 Async Computeを切った状態の計測結果なので、実際の性能への影響はもう少し抑えられます。 また、街中や森の中など、遠景がほぼ遮蔽されている状況ではSDF Shadowの面積が減るため、処理時間は0.5ms程になります。 ©CAPCOM 92

93.

SDF Ambient Occlusion スクリーンスペースを超えたOcclusion情報を利用可能 PS4で約1ms (SSAOとの合算) • レイマーチ距離は2メートル程度 • 540p(画面解像度の縦横半分) 続いて、SDFを利用したAmbient Occlusionを紹介します。 SDFから得られる周辺環境の情報を活用して、高品質なAOを実現できました。 93 SSAOとまとめて処理しているのですが、処理負荷はPS4で丁度1ms程度。 この時、レイマーチ距離2メートル、解像度が1080pの縦横半分という条件でした。 ©CAPCOM 93

94.

SDF Ambient Occlusion オブジェクト表面から半球方向に複数レイを飛ばして遮蔽具合を判定 • 1スレッドで3本, 4x4のDeinterleave ⇒ 合計48方向 レイマーチ結果は0, 1ではなく 途中で接近した距離を加味した半影 0.5 1 0 AOでは、オブジェクトの表面から半球方向に複数のレイを飛ばし、どれだけの割合のレイが遮蔽されたかで明暗を塗分けています。 1つのスレッドで3本のレイを飛ばし、4x4のDeinterleaveで処理しています。 94 そのため、48方向分の遮蔽を調べていることになります。 少ないレイでも明暗を滑らかに表現したいため、レイマーチ結果は衝突したかどうかの0, 1ではなくレイマーチ途中で接近した 距離を加味した半影になっています。 ©CAPCOM 94

95.

SDF Ambient Occlusion 最終的にブラーがかかって明暗の諧調が滑らかになる • Temporal Blendingに頼らず, 1フレーム内で安定した画を作れるのが強み Interleave解決時点では左図のようにノイズが目立ちますが、最終的にSSAOと共にブラーが適用され、右図のような滑らかな 状態になります。 95 大量のレイが要る時、よくTemporal Blendingが用いられますが、今回はそれに頼らずに滑らかなAOを実現できました。 そのため、1フレームの間で画が完成し、常に安定した結果が得られるという強みがあります。 ©CAPCOM 95

96.

SDF Ambient Occlusion レイマーチの距離を長くする場合は, もっとサンプル方向を増やす必要がある • 性能と品質を考慮して, 現状は3メートルまでを想定 レイマーチ距離 2m レイマーチ距離 7m ただし、レイマーチ距離を長くしたときの挙動に欠点があります。 長距離を調べる際は処理時間が伸びる上、レイの本数が不足して品質にも問題が出てきます。 96 レイマーチ距離を長くした右の図では、木から離れた箇所で色むらが目立っています。 現状、レイマーチの距離は3メートル以内という、短めな条件の下で使用する想定になっています。 ©CAPCOM 96

97.

その他 Global Illuminationの光漏れ対策 RE ENGINEユーザーが独自に作成するシェーダー内での利用 その他にも、様々な用途でSDFを活用しています。 例えば、Global Illuminationの光漏れの対策として用いられることがありました。 97 エンジンユーザーが実装するシェーダー向けにもインタフェースを公開しています。 このスクリーンショットでは、波打ち際の白波の表現にSDFが活用されています。 このようにSDFは、シェーダー上で利用できる簡単な当たり判定や、距離に応じた色の塗分けなどの用途で使用できます。 ©CAPCOM 97

98.

データ構造 メッシュ毎に3DテクスチャとしてSDFを持たせている 生成に時間がかかるためRE ENGINE上で事前ベイク 3Dテクスチャなので 薄い形状や曲線は 再現しづらい 続いて、RE ENGINE内でSDFがどのようなデータとして表現されているのか説明します。 SDFは、Meshアセット毎に一つずつ、3Dテクスチャとして持たせています。 98 各ボクセルの中心からレイトレーシングで多方向にレイを飛ばし、最短でヒットしたレイの距離をそのボクセルに格納しています。 SDFの生成処理には時間がかかるため、リアルタイムではなくRE ENGINE上で事前ベイクする仕組みになっています。 右側の図は、SDFのデバッグ表示です。 視点からレイを飛ばし、表面付近までレイマーチして、収束にかかったステップ数に応じて色分けをしています。 リボンの部分のように薄くて曲線的な形状が苦手で、元の形状を上手く再現できていない様子が見えます。 ©CAPCOM 98

99.

データ構造 1000種類以上のSDFテクスチャが同時に読み込まれる 1回のシェーダー実行の中ですべてを参照したいため, Bindless化している 大きなシーンだと一度に1000個を超えるSDFのテクスチャが読み込まれることがあります。 一つのシェーダー内でそれら全てを参照したいため、Bindlessなリソースとして扱っています。 ©CAPCOM 99 99

100.

データ構造 カリングに使う情報 • 属性bit • Dynamic, 基準より小さい, 負の値を含まない, などで属性を付加 • ワールド空間のAABB テクスチャサンプルに使う情報 • ワールド座標からUVに変換する行列 • BindlessリソースのIndex • 値の範囲 各インスタンスのSDF情報にアクセスするためのデータは、二つに分かれています。 カリングのみを行うシェーダーでは、属性bitとワールド空間のAABBを参照します。 100 属性bitからは、動く物体かどうか、などの情報が得られます。 まずはビットマスクでそのインスタンスをチェックする価値があるかを判定し、その後AABBが探索範囲にあるかどうかを調べます。 テクスチャ内のSDFを利用するシェーダーでは、また別のデータを参照します。 ここには、ワールド座標を3DテクスチャのUV空間に変換する行列、BindlessリソースのIndex、SDFの値域が含まれています。 ©CAPCOM 100

101.

最適化 メモリ 処理負荷 続いて、これまでに取り組んだ最適化について、メモリと処理負荷に分けて紹介いたします。 101 ©CAPCOM 101

102.

最適化~メモリ~ 3Dテクスチャのため, VRAM使用量が増大しがち 当初は16bit Floatにしていたが、数百MBのVRAM使用量に まず、メモリについてですが、前述の通りSDFを3DTextureとして表現しています。 3次元のため、VRAM使用量が大きくなりやすいことが想像できると思います。 102 当初は16bit Floatのテクスチャを使っていました。 しかし、広いシーンでは常に数百MBのSDFが読み込まれていて、問題になりました。 ©CAPCOM 102

103.

最適化~メモリ~ 現在は、サイズの小さいフォーマットを採用 • Texture Format は R8Unorm • BC4圧縮を適用 これにより、16bitの時と比べて30%ほどまで圧縮 現在では節約のために、テクスチャフォーマットとしてR8Unormを採用し、 BC4圧縮を適用する仕様になりました。 この変更により、同じシーンでもVRAMの量は以前の30%ほどで済むようになりました。 103 UnormなのでそのままSampleすると値が0~1になってしまいます。 そのため、Sample後に元々の値の最小値と最大値を手掛かりに線形補完して、値を復元する必要があります。 ©CAPCOM 103

104.

最適化~メモリ~ LOD 0番の形状に基づいたSDFのみを持つ 描画LODが異なるとき レイマーチの開始位置が負の位置に埋まってしまうことが頻繁にある + + + - - + - - - - - + - - - - - - + - - - - - - - - - - - + + + - - + - - - - + - - - + - - - - - 異なるLODで同じSDFを使うと… また、SDFはLOD0の形状に対応したものだけ生成しています。 しかし、LOD変化などで形状が変わると、各ボクセルがどの表面に最接近していたかの対応が変化します。 104 例えば、この図の右側の〇の箇所のように、ボクセルの中心が物体の外にあるにもかかわらず値が負になってしまう状況が 頻繁に発生してしまいます。 とはいえ、LOD毎に異なるSDFを用意しているとVRAMを逼迫してしまいます。 そのため、同じSDFで全てのLODを賄うことにしました。 ©CAPCOM 104

105.

最適化~メモリ~ レイマーチ開始地点で一度SDFを取得 いきなり負の値だった場合, その値に応じてオフセット量を増やし Self Intersectionを回避可能 オフセット無し オフセット有り ベイク時と異なるLODにも同じSDFを使いまわした場合、所々でセルフインターセクションが発生してしまいます。 例えばAOでは、左側のスクリーンショットのように、黒い染みとして問題が見た目に現れてしまいました。 105 しかし、この問題は簡単な工夫で回避することができます。 右図では、レイマーチの開始地点のボクセルが負だった場合、法線方向にマイナスの値に応じてオフセット量を増やしています。 それだけでも、ほとんどの場合で問題を回避することができました。 ©CAPCOM 105

106.

最適化~処理負荷~ 処理負荷が増大してしまう主な原因 • インスタンス数が多すぎる • 影響範囲が大量にオーバーラップしている 続いて性能の最適化について紹介します。 SDFの活用が進むにつれ、主にインスタンス数が多すぎる問題と、影響範囲のオーバーラップの問題に直面することになりました。 106 ©CAPCOM 106

107.

インスタンス数の削減 インスタンスを分類 • SDFインスタンス登録時に重要度を評価して, bitを立てる • AABBの大きさ • Textureに含まれている最小の値 • 静的物体かどうか • 処理に求められている精度に応じて, 必要なbitが立っているかをチェック シーン上に5万を超えるインスタンスが存在していることがあり、単純にすべてを調べようとすると重くなってしまいます。 そこで、最初にSDFのインスタンスを登録する段階でAABBの大きさや最小値を評価し、どこまでの距離で有効なのか、 107 特定の機能に含めるかなどを表すbitを立てておくようにしました。 例えばAABBが小さいものは遠景のレイマーチ対象からは外したり、最小値がレイマーチを打ち切る閾値よりも大きければ レイマーチ対象から外すなどです。 付近のインスタンスを探索する方法については、シンプルな方法で探索対象のインスタンスを絞っています。 実装が悪かったかもしれませんが、BVHを使用すると構造の探索にコストがかかり、ユニフォームグリッドのようなシンプルな 方法と比べて低速になる傾向がありました。 ©CAPCOM 107

108.

オーバーラップの問題 最近傍の情報を持っている可能性のある候補を全て調べる必要がある この座標から見た最近傍の面は ★が持っている 続いて、インスタンスの影響範囲のオーバーラップ問題について説明します。 例えば、図の赤い点の位置から最短距離を得ようとすると、その点をテクスチャ範囲に含んでいる物体よりも、少し離れた 108 物体の方が近い表面を持っています。 AABBの中に余白が含まれていることを考慮すると、今回のように、離れた位置にあるインスタンスの方が近い表面を 含んでいることもあり得ます。 そのため、一つの地点で最短距離を得ようとするだけでも、密集地帯では大量のテクスチャを調べる必要があります。 ©CAPCOM 108

109.

オーバーラップの軽減 レイマーチの1ステップで移動できる距離を制限 • 開けた空間の探索効率は悪化 • その代わり、オーバーラップが劇的に改善 1ステップの 最大距離を制限 調べる候補を減らすために、レイマーチの1ステップで進める最大の距離を制限するという手段を用いました。 レイマーチのステップ数が増えてしまうデメリットはありますが、オーバーラップを大きく緩和することができました。 109 左側の図だと、最短距離を持っている可能性があるテクスチャを大量に調べる必要があります。 しかし、最大距離を制限した右の図では、本当の最短かは保証されないものの、たった二つ調べれば貫通しないことを保証できます。 ©CAPCOM 109

110.

オーバーラップの軽減 数枚のクリップマップにオーバーラップ解決済みのSDFを作成 • 解像度128x64x128の3Dテクスチャを最大4枚 • ランタイムで動的に合成している • 精度は低いものの, 1サンプルで最近傍の距離が分かり手軽 エンジンユーザに公開しているインタフェースや, SDF AOではクリップマップのSDFを参照 他のオーバーラップ回避の仕組みとして、数枚のクリップマップにオーバーラップ解決済みのSDFを保存しています。 クリップマップはランタイムで動的に生成しているため、シーンのレイアウトを変えてもすぐに反映されます。 110 精度は元々のテクスチャよりも下がってしまいますが、1回サンプルするだけで最近傍の距離が分かります。 エンジンユーザに提供しているSDFのインタフェースや、多方向にレイを飛ばすAOではクリップマップを参照しています。 ©CAPCOM 110

111.

オーバーラップの軽減 クリップマップは差分更新 • クリップマップをいくつかのGridに区切り, それを更新の単位とする • Grid毎にチェックサムを持ち, 変化が検出された場合に更新 • フルで更新するとPS4で20ms以上だが, 差分更新なら概ね1ms以内に収まる カメラ移動で生じた未初期化領域 追加/削除/変形が 検知された領域 クリップマップを利用することは低コストでできますが、その作成には大きなコストがかかります。 毎フレーム作り直すと、PS4で20msを超える巨大な処理負荷になってしまうため、差分更新をしています。 111 物体の追加・削除・移動が検知された時、その影響範囲と重なるグリッドのチェックサムが変化し、最小限の範囲だけ 作り直しになります。 基準位置の移動には、UVスクロールで追従します。 前フレームでも範囲にあったものはそのまま利用し続け、新しくクリップマップ範囲に含まれた領域の分だけ生成されます。 ©CAPCOM 111

112.

今後の展望 課題 • Jointには非対応 • ユニークなメッシュが多すぎるとVRAMを逼迫 新しい機能の開発 • 動的GIへの応用 現状のSDFの実装状況については以上です。 現在の主な課題としては、バリエーションが増やしづらいことが挙げられます。 112 例えば、Jointで地形に沿って変形して置かれた物体はSDFの対象外です。 ユニークなメッシュが多すぎると、VRAM使用量が多くなってしまうことも問題です。 地形に合わせて変形されたユニークで静的なメッシュをまとめ、一つのOctreeのような構造にベイクする仕組みがあれば、 利用の幅が広がるかもしれません。また、現在新しい動的Global Illuminationについて検証が行われています。 SDFそのものの最適化だけでなく、SDFを利用した新機能の開発も続けていきたいです。 SDFについての発表は以上です。 ©CAPCOM 112

113.

全体の総括 HDR Grading • OpenColorIO+ACESを使ったパイプラインへ変更 • 設定の共有、導入の容易化、HDR/SDR出力の互換性を重視 • パイプライン変更に伴いGUIの対応がいくつか必要になった Shell Fur • 軽量なファー表現手法としてエンジンに導入 • ユーザーカスタマイズ性を高くすることで高い表現幅を実現 • メモリ軽減か処理軽減タイプかをユーザー側でコントロールする必要がある Signed Distance Field • 軽量なレイマーチ手段としてエンジンに導入 • Shadow, AO, ユーザシェーダなど, 様々な場面で柔軟に活用できる • メモリや影響範囲のオーバーラップが問題になりやすく, 工夫が必要 ここまでご清聴いただき、ありがとうございました。 最後に、この発表全体のまとめを掲示して発表を終了いたします。 ©CAPCOM 113 113