Saturday, August 25, 2018

[Unreal Summit 2018] Fortniteモバイル版のオクルージョンカリングについて

前回前々回に引き続きUnreal Summit 2018の話題です。

韓国がモバイルゲーム開発においてのUE4採用の最前線になっているためか、Unreal Summitはモバイル向けの話題が多めです。その中から今回はEpic Games KoreaのDmitriy Dyominさんによる、ソフトウェアオクルージョンカリングのセッションを読んでみました。モバイル版のオクルージョンカリングはPC版とは異なる手法で実装されており、このテーマ1つでなかなかの分量です。題名にモバイルとありますが、PC版の実装にも触れています。


残念ながら動画の音質が非常に悪く字幕も生成されていないので、以下のスライドをおすすめします。
https://replay.unrealsummit.co.kr/data2018/usm2018_44.pdf 

要約

  • モバイル版のためにSoftware occlusion culling実装(今回の主題)
  • PC版やコンソール版ではHardware occlusion queries、HiZ occlusionというGPUを活用した手法を使う
  • モバイル版(OpenGL ES)でもHiZ occlusionを実装したが採用せず、エンジンにも組み込まなかった
  • iOSではSoftware occlusion cullingはうまくいかず、Hardware occlusion queriesを使うことに
  • UE4.20からモバイルでSoftware occlusion cullingとHardware occlusion queriesが使えるように

要求仕様

  • PCやコンソールとのクロスプラットフォーム対戦可能
  • モバイルのスペックが足りないからと言って視距離を制限するなどゲームプレイ上不利になる事はできない
  • terrain以外は破壊可能なので、precomputed visibilityはつかえない

Hardware occlusion queries

  • OpenGL ES3以降
  • bounding boxを頂点シェーダのみ、ピクセルシェーダ抜きで描画してクエリ
  • PCやコンソールではdepth pre-passの後にクエリを投げ、1フレーム待機で結果を得られる
  • モバイルではdepth pre-passがない、最低2フレームかかるがFortniteでは3フレーム待つ
  • 平均50%くらいドローコールを削れる
  • UE4.20で、r.AllowOcclusionQueries=1 がモバイルでサポート

Hardware occlusion queriesの問題点

  • 結果を得るまで3フレームの遅延
  • クエリ1回当たり追加でドローコール1回。FORTNITEは150ドローコール増加。
  • Adrenoは512クエリの制限

Software occlusion cullingを実装してみる

  • メインメモリにデプスバッファを作る
  • SIMDで頂点変換
  • CPUでラスタライズ、クリッピング、カリング
  • 重い! ~1100 オブジェクト、~60万ポリゴン

Software occlusion cullingの高速化

  • 良いoccluderをアセット単位でアーティストが手動で選別(悪いoccluderとされたらバッファに描画しない)
  • 描画に使うLODもアーティストが指定
  • 良いoccluderもそのフレームでoccluderとして使う価値があるかはヒューリスティックに判断(カメラから近い程良い)
  • 1フレームあたり200個ぐらいまでが適切

Occludeeの最適化

  • 二次元Bounding Boxでまず判定
  • 三次元Bounding Boxを三角形に分解してデプステスト

デプスバッファの最適化

  • デプスはいらない、1ピクセル1ビットで十分、以下occlusion bufferと呼ぶ
  • occluderとoccludeeの三角形を全てデプスでソートして手前から処理
  • occluderは三頂点の最も奥のZを採用
  • occludeeは三頂点の最も手前のZを採用

occlusion bufferのレイアウト

  • 384x256ピクセル
  • 6x4の 'bin'という単位に分ける。binは64x64ピクセル
  • bin1つは uint64 Bin[64]
  • 描画とテストはビット演算
  • binごとに別スレッドで処理させることもできる

結果

  • 一万個の三角形を 5-8msで処理(Galaxy S8)
  • 30-50%のオブジェクトをカリング
  • 1フレームのレイテンシ

Software occlusion cullingについて

  • UE4.20で、r.Mobile.AllowSoftwareOcclusion=1 で使える
  • iOSでは採用せず。オープンワールドではうまく機能しなかったため、3フレームのレイテンシを我慢してHardware occlusion cullingを採用

インテルのソフトウェアオクルージョンの紹介

HiZ occlusion - PC版の実装

  • デプスバッファのMip Chainを作る
  • 複数のOccludeeのBBoxをテクスチャに書き込んでピクセルシェーダから参照
  • Render Targetの1ピクセルは1Occludeeに対応していて、隠蔽されたかどうかが書き込まれる
  • 次のフレームで結果を利用
  • occludeeが増えてもコストはほぼ変わらないメリット

HiZ occlusion - OpenGL ESの実装

  • PC版の実装のようにRender TargetをCPUから参照しようとするとすごく待たされた
  • ピクセルシェーダの代わりに頂点シェーダ+Transform Feedbackで処理した
  • 3フレームレイテンシで結果を取れた
  • Occlusion queryのほうが結果が良かった
  • 不採用、エンジンにも反映せず


モバイルGPUのオクルージョンクエリは待たされる等の制限があるとのことで、代わりにCPUでラスタライザを実装、更にそれを実用レベルにしてしまうのは驚きでした。

Galaxy S8基準でソフトウェアカリングに5~8msかかるとはいえ、バックグラウンドスレッドで動くのでゲームスレッドやレンダリングスレッドの仕事を増やしているわけではないと想像します。

余談ですが、Samsungは仕向地などによって同じブランドでもSoCが違うことがあります。Galaxy S8の場合、日本やアメリカはSnapdragonですが、韓国ではExynos+Maliの構成です。Snapdragonのほうがゲーム向けで、Exynosは相対的にグラフィック性能が落ちる代わりにCPU性能は高いです。スライド上のGalaxy S8は韓国モデルと思われますが、もしかするとゲームでCPUが遊びがちなExynos向けの実装を試みた結果だったかもしれません。

Sunday, August 12, 2018

[Unreal Summit 2018/GDC 2018] FORTNITEのリアルタイムライティング技術について

前回に続き、Unreal Summit 2018の動画とスライドを見ていきます。
動画とスライドは https://replay.unrealsummit.co.kr/ にあります。

Epic GamesのZak Parrishさんによるセッション(原題:Fortnite’s Real-Time Lighting Techniques and Tools)で、FORTNITEのライティングについて具体的な手法が解説されています。

GDC 2018でもほぼ同じ内容で講演されていますが、Unreal Summitの講演にはVolumetric LightingやTime of Dayの実演や質疑応答が追加で含まれています。


要約
  • 事前計算の影は使わず、影はリアルタイムに計算している
  • レベルに配置されたStatic MeshからMesh Distance Fieldが生成されている
  • Mesh Distance Fieldにより、ソフトシャドウ、アンビエントオクルージョン、パーティクルコリジョンを実現
  • スケルタルメッシュの影生成は影生成専用のカプセルで構成されたモデルが使われている
  • Time of Dayを実現。24時間どの時間にも設定可能で、太陽と月が時間に追従して動く。これはFORTNITE専用に組まれた機能だが、エンジンレベルで事前計算の影が使われていないことを示している




MESH DISTANCE FIELDについて
  • FORTNITEでは様々なオブジェクトを壊せるので事前計算した影は使えないが、リアルな影を使いたい
  • Mesh Distance Fieldをレイトレースすることでソフトシャドウを実現
  • 3Dテクスチャに最も近いメッシュの面までの距離を格納している。プラスならメッシュの外、マイナスならメッシュの中(Signed Distance Field、SDFとも)
  • 3Dテクスチャはエディタで事前計算される

DISTANCE FIELDの影の作り方(実演あり)
  • Mesh Distance Fieldはプロジェクト設定によって有効化しなければいけない
  • Mesh Distance Fieldのビジュアライズ機能で可視化して確認できる
  • ダイナミックライトを使ってもソフトシャドウが出来る。(Spot LightアクタのRay Traced Distance Shadowsにチェック)
  • Static Meshをエディタで開き、Distance Field Resolution Scaleで解像度を調節
  • Static MeshのDistance Field Replacement Meshはレンダリング用のメッシュとDistance Field生成用のメッシュを別にしたいときに使う。
  • Distance Field Replacement Meshを指定する副次的メリットとして、LODをビルボードにしているときにもボリューメトリックシャドウを描ける。
パフォーマンスや制限など
  • DFはCascade Shadow Mapに比べ30%から50%程軽量
  • 近景はCascade Shadow Map、遠景はDistance Field Shadowにすることでパフォーマンスとクオリティを両立。境界近くではブレンドも行う
  • DFはGPUにおいて数ミリセカンド節約になる
DISTANCE FIELD AMBIENT OCCLUSIONについて
  • Visualize機能で DFAOを可視化できる
  • SkyLightをMovableに設定し、スカイライトで設定値を変更する。(ただし、FORTNITEではWorld Settingの中にライティング設定値をもたせているので、実演ではWorld Settingで)
  • Occlusion Max Distanceを大きくすると暗くなる。他のオブジェクトに到達しやすくなるため。ただし、大きくすると重くなる
  • Occlusion ContrastでAOの強度設定
  • Occlusion ExponentでAOの"fall-off"を調整

GLOBAL DISTANCE FIELDについて
  • 全てのメッシュにDFをもたせる必要はなく、Global Distance Fieldが存在する。これはカメラの移動に伴い計算が実行される
  • DFAOの他、パーティクルコリジョンにも使う
  • プレイヤーがテレポートするとGlobal DFが全計算され、一瞬重くなる

MESH DISTANCE FIELDの制限と考慮点
  • DX11以上のみ
  • メッシュの変形が反映されないという欠点がある(ゆれる木等)
  • 軸ごとのスケール値が異なる不均等スケールに対応できない(多少の不均等は許容できる場合も)
  • 大きなメッシュはディテールを損なわれる傾向。小さいメッシュに向いている。FORTNITEは小さなメッシュの組み合わせで大きな建物を構成
  • 解像度は慎重に設定すべき

MESH DISTANCE FIELDの最適化について
  • r.AOListMeshDistanceFields でDFに使われているメモリをダンプ
  • プロジェクト設定でMesh Distance Fieldを圧縮できる。メモリを節約できるが、レベルのストリーミングで解凍処理が走りヒッチ(Hitch=瞬間的な負荷でフレームレートが落ちること)が発生するかもしれない
  • プロジェクト設定で8-bit Mesh Distance Fieldにできる(デフォルトは16-bit) 品質は落ちるが、FORTNITEでは8-bitでも悪くなかった。
キャラクタのカプセルシャドウ
  • 軽い、ソフトシャドウもできる
  • SkeletalMeshActorのCapsule Direct Shadowをチェックすることで有効化
  • shadow physics assetを用意しなければいけない。キャラクタを構成する剛体の形状はカプセルだけが許されている(ソフトシャドウの計算に向いている)
  • 仕組み上、影が壁や床を突き抜けて生成されることも
ダイナミックライトの距離カリング
  • ポイントライトなどに個別に設定
  • 見えなくて気づかないかもしれないが、距離内にあると計算が発生していることに注意
  • パフォーマンスのために必ず忘れずに設定するように!(アーティストがいつも設定し忘れるそうです)
DYNAMIC SHADOW CACHING
  • 動いていないライトと動いていないオブジェクトがあったら影計算結果を再利用
  • 初回フレームはキャッシュしない場合と同様の負荷がかかる
  • 何も設定しなくてもいい!デフォルトで有効になっている
  • ただし条件あり。プリミティブはStaticかStationary、ライトはMovable
VOLUMETRIC LIGHTING
  • 最近Volumetric Fogが実装された
  • Volumetric FogはExponential Height Fog Actorの設定項目になっている
  • スライドによると、Volumetric LightingのGDCセッションがある (これかと思います  https://www.youtube.com/watch?v=Xd7-rTzfmCo
VOLUMETRIC FOGの実演デモ(以下の項目それぞれFORTNITEを使って値を変えて実演)
  • Density - 霧の濃さ
  • Scattering Distribution - フォグが指向性をもつか
  • Albedo フォグがどれだけ光を反射させるか(色で指定)
  • Extinction Scale Controls  - フォグのfalloffの調整 ライトが霧に隠れる程度の調整
  • View Distance - Volumetric FogとExponential Height Fogとの切り替え地点の調整
  • ポイントライトアクタに Cast Volumetric Shadowにチェックを入れることで霧の中にライトを遮蔽した影を入れることができる。Volumetric Scattering Intensityでその程度を調整できる

FORTNITEのTime of Day(TOD)
  • 以下はFORTNITEに特化した実装の話
  • TOD機能が実装され、World Settingから朝、昼、夕、夜(又はスライダから24時間中のどんな時間でも)を選ぶだけで太陽、月、Exponential Height Fog、スカイライト、atmosphericsが設定される
  • 上の環境設定は全てのレベルで一律であり、エンジニアがC++で実装した。アーティストはレベル毎に個別に設定する必要がない
  • (質疑応答時間の回答にて)リリースされているUE4にはこの機能は無いが、望むならあなたが同じようなものを作ればいい。ただし、もしかすると後日サンプルを公開するかも?
    (追記 2019/04/06 UE4.21で Sun Position Calculator pluginとして提供されています!)


Time of Dayを実装したゲームエンジンとしてCRYENGINEがありましたが、Mesh/Global Distance FieldはそれらをUE4で実装するのに使えそうです。

UE4上でTODを実現するためには必要な機能をプログラマが組む必要があり、手法の検証にコストがかかりそうな印象でした。これもFORTNITEにより手法が提示されたことでハードルが下がったと感じます。後日TODの機能またはサンプルがEpic Gamesから提供されれば、更にオープンワールドの様なゲームの開発がはかどりそうです。

Monday, August 6, 2018

[Unreal Summit 2018] Material Layering Systemの概要

韓国で開催されたUnreal Summit 2018のスライドや動画が上がっています。
https://replay.unrealsummit.co.kr/

今回はその中からEpic GamesのAlan WillardさんによるMaterial Layering Systemに関する動画を見てみました。


  • 新しいアセットの名前は"Material Layer Blend"
  • 複雑なマテリアルをシンプルに定義するための機能である(Photoshopのレイヤーのような用途と理解すればよい)
  • 開発中の機能であり、現時点でプロダクトでの使用は勧めない(将来のバージョンアップで編集内容が壊れる可能性がある)
  • レイヤー機能を使っても使わなくても出来上がるシェーダは全く同じものになる。編集の利便性のための機能にすぎない
  • PC、モバイルなどプラットフォームに関係なく利用できる。
  • ブレンドのウェイト値としてテクスチャを使うこともできるし、頂点カラーを使うこともできる
  • マテリアルインスタンス側で特定レイヤーを省くという編集も可能

今現在、"マテリアル レイヤー UE4"などで検索すると出てくるページは以下のようなものですが、これは今回のUnreal Summit 2018で紹介された機能ではありません。
http://api.unrealengine.com/INT/Engine/Rendering/Materials/HowTo/CreatingLayeredMaterials/index.html
既存の機能で作るいわゆるLayered MaterialはMaterial Functionを駆使して作られていましたが、"Material Layer Blend"はより幾重にも折り重なったレイヤーを直感的かつ機能的に扱うことができそうです。

Unreal Summit 2018の続き