5.7K Views
August 26, 19
スライド概要
CEDEC2019の講演資料となります。
https://cedec.cesa.or.jp/2019/session/detail/s5c9c2e29b4f46.html
2019年発売の"プロ野球スピリッツ2019" PS4版のグラフィックス開発サポートとして
最大16灯影付きライト+影無し多光源+フルHD(or 4K)+60FPS+HDRを実現しました。
このゴールに至るまでのチーム目標の設定、初期段階での検証風景や最適化事例を紹介いたします。
株式会社ヘキサドライブの資料共有用アカウントです。 公式ブログ:https://hexadrive.jp/hexablog/ note :https://note.com/hexadrive
The graphic of "プロ野球スピリッツ2019" for PS4 ~PS4で最大16灯影付きライティング+フルHD(or 4K) +60FPS+HDRを実現するまで~ 株式会社ヘキサドライブ 開発部 山口裕也
アウトライン • タイトル紹介 • 開発体制とビジョン • ライティング検証 • 描画ブレイクダウン • 影描画 • シェーダー最適化
タイトル紹介
タイトル紹介 プロ野球スピリッツ2019 プラットフォーム PlayStation4 PlayStation Vita 今回はPlayStation4のお話
タイトル紹介 主な描画スペック 1920x1080(PS4) 3840x2160(PS4Pro) プレイアブル箇所は60FPS デモシーンは30FPS可変フレームレート GPU由来の処理落ち時は動的な解像度変更
開発体制とビジョン
開発体制と初期ゴール 開発体制 • プログラマーは役割毎に3つのチーム分け – システム モデル描画等の基幹部分の作成を主に担当 – パイプライン モデル変換等のデーター加工を主に担当 – ライティング ライティングやポストエフェクト等の見た目を主に担当 従来は個人毎に作業割り振りされる傾向にあった
開発体制と初期ゴール 開発体制 • 個人タスクではなくなることで、従来ならチャ レンジを見送るような事に取り組めた
開発体制と初期ゴール 初期ビジョン(ライティングチーム) • 背景人物共に同じライティングを使用する (ライティングを一番大事にする) • 影キャストするライトの最大数は太陽光+6灯の スポットライト(ナイトゲーム用) • ドームはSHをベースにしたライティング • ポストエフェクトは中継カメラをイメージ • HDR対応したい
開発体制と初期ゴール 中期ビジョン(初期ビジョン達成後) • ドームは影キャストするライトを16灯のスポッ トライトにする ※SHベースでは品質に問題あり • 4K対応したい
開発体制と初期ゴール ビジョン • 目標がある事で目指す品質やパフォーマンスが 明確になり、無駄を削る等の判断が行いやすく なる • プロジェクトの中間地点で大きな目標引き上げ をするととても苦しくなる
ライティング検証
ライティング検証 プロジェクト開始直後はシステム構築中 ライティングチームは基礎調査 • ライト強度の計測 • ライティング関数の検証
ライティング検証 125cdのLEDを 地面から1m位置に設置 地面で125luxの照度を確認 照度計とグレーカードを 入れ替えた後に写真撮影
ライティング検証 撮影した写真の平均ピクセル値 から照度がカメラの画素の 輝度になる為の係数を逆算 (素材は完全なランバートモデルとした) 今回のカメラではグレーカードは 画素 = lux × およそ2 × 正規化ランバート × アルベド
ライティング検証 太陽光の強度計測 謎の自作測定ツールを写真撮影 太陽の直接光=明-影(間接光) になるハズ 同時に照度計の計測結果も記録
ライティング検証 各時間帯の輝度を計測 大阪から見える太陽の傾斜と 大気散乱の値から 太陽光シミュレーション機能を作成 ※但し天候等により数値にブレ幅がある為 正確性には欠ける
ライティング検証 検証にはヘキサドライブ内製システムとMaya (Arnold)を使用
ライティング検証 リファレンス素材の撮影と IBL用の素材を撮影 同時に撮影時間の他 絞りの値も記録 ※レンズによってはexifに記録されない
ライティング検証 社内にphotogrammetry環境を作成 検証用のモデルとテクスチャを作成
ライティング検証 ステップ1 MayaでIBLのみでリファレンスを再現 IBLの輝度補正値の整合性を確認 ※機材的に太陽輝度は正常に撮影出来ない為、 1/100000NDフィルターを使った別撮り素材から底上げして作成
ライティング検証 ステップ2 Mayaで太陽を除いたIBLと並行光源でリファレン スを再現 IBLと並行光源の輝度の整合性を確認
ライティング検証 ステップ3 内製のシステムでMayaの結果になる様に シェーダーを作成 高品質なライティングが出来る環境の確立
ライティング検証 ライティング関数 Cook-Torranceモデル D項...GGX G項...smith F項...Schlick でArnoldに近い結果を得られる
ライティング検証 調査結果 • 365日任意の時間の太陽光を扱える • 照明は規格品を参考にcdやlmで調整出来る • ライティングの計算に対する信頼 =明るすぎる、暗すぎる時は露出を疑える
ライティング検証 ライティング時のピクセル値からLuxに逆変換 Luxの可視化で 直感には頼らない配光 色分けは以下の通りになります。 シアン...4500Lux以上 黄色...3000Lux以上 赤...2000Lux以上 紫...2000Luxより暗い
ライティング検証 最終的に使用する明るさのレンジを考慮し、 内部的にEV10を打ち消した状態(1/1024)で計算
描画ブレイクダウン
描画ブレイクダウン レンダリング構成 • Deferred Renderingベース 半透明は使えずアニメーションディザーで表現 • 眼鏡や窓ガラス等の屈折も特殊なDeferred Renderingで処理 • 一部Foword+ (雨やボールの残像)
描画ブレイクダウン レンダリング構成 • 動的な時間変化をリアルタイムに再計算出来る 独自のGIシステム[sawano19]を作成 • 肌は特殊なライティングとSSSSSを併用
描画ブレイクダウン G-Buffers Opaque R8G8B8A8 UNORM srgb R:アルベドR G:アルベドG B:アルベドB R32 UINT 10bit:NormalX 10bit:NormalY R32 UINT 11bit:VelocityX 11bit:VelocityY D32 float S8 A:AO 4bit: Metalic 8bit: Roughness 10bit:Emissive Stencil: 肌等のマテリアルマスク Refraction R16G16B16A16 UINT D32 float S8 8bit:アルベドR 8bit:アルベドG 8bit:アルベドB 8bit:透過率 10bit:NormalX 10bit:NormalY 5bit:refraction Stencil: 屈折描画マスク 読み込み枚数を少なく利用頻度毎に纏めた フィルタリング出来ないが任意のビット幅が使える 7:Roughness
描画ブレイクダウン ライトクラスター クラスター uint クラスター内のライト総数 uint パティング uint スクリーンZ方向へのビットマスク uint ライトのID uint マスク...※繰り返し uint ID...※繰り返し 16pix 16pix 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 ライティングするピクセルのZがこの範囲なら計算対象 ポイントライト half R half G half B half 半径 half 位置X half 位置Y half 位置Z half 影響範囲の逆数 スポットライト(追加情報) float 方向X float 方向Y float 方向Z half コーン角度 half コーン減衰 1つのライトを処理するのに最大3回のロードが必要
描画ブレイクダウン ライトクラスター 不要な領域 必要な領域 実際 の 影響範囲 レイトレースでタイトに切り抜き 利点 ボトルネックのメモリ負荷大幅削減 欠点 位置とサイズで時々判定に失敗する 対策 交差判定中のみ形状サイズを補正
描画ブレイクダウン 雲
描画ブレイクダウン 雲 • Horizon Zero Dawnのスライドを参考にした高 速なプロシージャル雲[Schneider15], [Schneider17] 平均1ms(Z-Preパス中に非同期実行) • 曇りの日はこの雲をレイマーチして作成した影 を利用して表現[yamaguchi19]
描画ブレイクダウン フォグ 2種類のフォグソースを距離を基準に合成 計算タイミングはポストエフェクトの前で実質ラ イティングの一部として計上
描画ブレイクダウン 大気散乱ベースの天球からフォグテクスチャを作 成して距離ベースで吸収と散乱を意識して合成 Uncharted4のmip fogを参考[brinck&maximov16] • 高速でフォグの明るさの破綻が起きにくい • 色を調整する事は出来ない(彩度を除く) 12px 一部を切り抜く 4px
描画ブレイクダウン ナイトゲームでは高さフォグをベースにした周辺 の照明が散乱する効果を作成 フォグの高さは照明の明るさを入力して逆算 高さフォグ無し 高さフォグ有り 高さフォグもライトの明るさ単位を基準に する事で自然になじませる事が可能
描画ブレイクダウン ポストエフェクト • バジェットは2.5ms程 • 当初から派手な効果は入れない予定 • 中継カメラで起こりうる要素を考え必要最小限 • PS4 Proではチェッカーボードのまま全て計算
描画ブレイクダウン ポストエフェクト • ブルーム • DOF ガウスブラーをベース比較的高速 • レンズディストーション • 色収差
描画ブレイクダウン HDR ノウハウが無かった為手探り 出力自体の実装は非常に簡単だった アンチエイリアシングや色の飽和等に苦戦
描画ブレイクダウン HDRの飽和問題 エミッシブはアルベド×輝度で加算 255,20,20の様な素材を高輝度出力した場合に白 になってしまう OK NG 最大出力nitに対して 飽和しない輝度にスケール 約5000nitの電光掲示板 トーンマップタイミングで色が白くなる スケールする事でブルームと引き換えに色味を保持
描画ブレイクダウン HDRの処理負荷問題 HUDの加算描画に対応する為に トーンマップ後もR11G11B10 FLOATを使用 最後にR10G10B10A2にPQカーブ変換 4Kでは0.7msのコストになる 加算が無ければトーンマップと同時にPQカーブ化
描画ブレイクダウン トーンマップ GTトーンマップ[Uchimura17]を3DLUT化 HDRとSDR同じ係数、出力輝度を変更して使用 350~1000nitまでの出力を検証
描画ブレイクダウン アンチエイリアシング PS4 ProはAA無し PS4ではTAA トーンマップ前各種ポストプロセス前に実行 残像とチラつきが厳しい TAAのサブピクセル出力を工夫する事で対応 [yamaguchi19]
描画ブレイクダウン デイゲーム
描画ブレイクダウン デイゲーム(PS4 HDR出力) UI描画 HDR PQカーブ変換 ブルーム トーンマッピング レンズ効果(歪みと収差とビネッティング) 雲リプロジェクションアップサンプリング 雲と大気散乱合成 屈折描画前処理 屈折ライティング DOF用縮小バッファ作成 3DUI用のZバッファ作成 TAA フォグ ライティング 必要最低限のバッファクリア SSAO SSAOブラー 縮小深度計算 (DOFや 影領域最適化) PreSkining 前フレーム露出計算 SSAOとGBuffer-AO合成 ShadowMap用DepthTargetのHTile解除待ち 簡易PCSM用 ブロッカー 作成 影メッシュ描画 メッシュ描画 PreZ描 画
描画ブレイクダウン デイゲーム(PS4 Pro HDR出力) HDR PQカーブ変換 UI描画 ブルーム 屈折ライティング DOF用縮小バッファ作成 屈折描画前処理 フォグ 前フレーム露出計算 SSAOとGBuffer-AO合成 SSAOブラー 雲と大気散乱合成 雲リプロジェクションアップサンプリング 簡易PCSM用ブロッカー作成 PreSkining 必要最低限のバッファクリア SSAO 縮小深度計算 (DOFや 影領域最適化) ライティング 3DUI用のZバッファ作成 トーンマッピング 4K レンズ効果(歪みと収差とビネッティング) リプロジェクション 影メッシュ描画 メッシュ描画 PreZ描画
描画ブレイクダウン ナイトゲーム雨天(画像は晴天です)
描画ブレイクダウン ナイトゲーム雨天(PS4 HDR出力) UI描画 HDR PQカーブ変換 ブルーム トーンマッピング レンズ効果(歪みと収差とビネッティング) 3DUI用のZバッファ作成 TAA 雲と大気散乱合成 フォグ 屈折描画前処理 DOF用縮小バッファ作成 雨 点光源 クラスタ 作成 メッシュ描画 雲計算 SSAOブラー 前フレーム露出計算 SSAO PreSkining 必要最低限のバッファクリア PreZ描画 縮小深度計算 (DOFや 影領域最適化) 影メッシュ描画 SSAOとGBuffer-AO合成 ShadowMap用DepthTargetのHTile解除待ち 雲リプロジェクションアップサンプリング ライティング 雲計算
描画ブレイクダウン ナイトゲーム雨天(PS4 Pro HDR出力) HDR PQカーブ変換 UI描画 トーンマッピング 4K ブルーム フォグ PreSkining 必要最低限のバッファクリア SSAO SSAOブラー 縮小深度計算 (DOFや 影領域最適化) 点光源 クラスタ 作成 前フレーム露出計算 SSAOとGBuffer-AO合成 雲リプロジェクションアップサンプリング 雲と大気散乱合成 屈折描画前処理 DOF用縮小バッファ作成 3DUI用のZバッファ作成 レンズ効果(歪みと収差とビネッティング) リプロジェクション 雨 影メッシュ描画 メッシュ描画 雲計算 ライティング PreZ描画
描画ブレイクダウン ドーム
描画ブレイクダウン ドーム(PS4 HDR出力) UI描画 HDR PQカーブ変換 トーンマッピング ブルーム レンズ効果(歪みと収差とビネッティング) PreSkining 縮小深度計算 必要最低限のバッファクリア 点光源 クラスタ 作成 SSAO SSAOブラー 前フレーム露出計算 SSAOとGBuffer-AO合成 ShadowMap用DepthTargetのHTile解除待ち ライティング フォグ 屈折描画前処理 3DUI用のZバッファ作成 DOF用縮小バッファ作成 TAA 影メッシュ描画 メッシュ描画 PreZ描画
描画ブレイクダウン ドーム(PS4 Pro HDR出力) HDR PQカーブ変換 UI描画 3DUI用のZバッファ作成 トーンマッピング 4K DOF用縮小バッファ作成 屈折描画前処理 PreSkining SSAO SSAOブラー 前フレーム露出計算 SSAOとGBuffer-AO合成 フォグ ライティング 点光源 クラスタ 作成 必要最低限のバッファクリア 縮小深度計算 (DOF用) ブルーム レンズ効果(歪みと収差とビネッティング) リプロジェクション 影メッシュ描画 メッシュ描画 PreZ描画
影描画
影描画 今回の拘りポイントはライティング ライトは常に影と一心同体 少しでも影を多く高解像度で描画したい
影描画 人影と背景影 ゲーム全般で非常に豊富な画角とカメラワーク 画角2度で手前と奥の人物が写る事も 手前と遠くの人物が巨大に映る事もあり 弊社の従来のノウハウでは解像度確保が困難 人物の領域にフィットしたシャドウマップを背景 とは別に用意する必要があった
影描画 背景影 デイゲーム 太陽光影を5段カスケード(深度を基に分割位置を 動的変更)≠SDSM ナイトゲーム 太陽光は3段カスケード+スポットライトはESM ドーム ESMのみ
影描画 人影 画角によって遠くまで大きく映る 実は 約20m カメラはもっと遠い
影描画 人影 普通にカスケードしたら低解像度
影描画 人影 画面内の人物だけのバウンディングを作成 最初の人物+5m以内の人物をカスケード0として 残った人物のバウンディングを分割
影描画 人影 さらにカスケード内の人物のバウンディングボッ クスで影キャスター行列をフィッティング
影描画 シャドウマップ 共通PCF 2048x16384(D32Float) ナイトゲームESM 3072x1536(R32Float)x6 ドームESM 1536x768(R32Float)x16
影描画 巨大シャドウマップの内訳 環境毎にレイアウト スポットライトの 人影のカスケード化 はキャッシュの恩恵 を受ける可能性UP! デ イゲーム 背景影+観客 カスケード0 ナイトゲーム ドーム 背景影(並行光源) カスケード0 人影0 カスケード0 背景影(並行光源) カスケード1 人影1 カスケード0 背景影(並行光源) カスケード2 人影2 カスケード0 人影(並行光源) カスケード0 人影(並行光源) カスケード1 人影3 カスケード0 人影(スポット0) カスケード0 人影4 カスケード0 人影(スポット1) カスケード0 人影5 カスケード0 人影(スポット2) カスケード0 人影6 カスケード0 背景影+観客 カスケード2 人影(スポット3) カスケード0 人影7 カスケード0 人影(スポット4) カスケード0 人影8 カスケード0 背景影+観客 カスケード3 人影(スポット5) カスケード0 人影9 カスケード0 人影(スポット0) 人影(スポット0) カスケード1 カスケード2 人影10 カスケード0 人影(スポット1) 人影(スポット1) カスケード1 カスケード2 人影11 カスケード0 人影(スポット2) 人影(スポット2) カスケード1 カスケード2 人影12 カスケード0 人影(スポット3) 人影(スポット3) カスケード1 カスケード2 人影13 カスケード0 人影(スポット4) 人影(スポット4) カスケード1 カスケード2 人影14 カスケード0 人影(スポット5) 人影(スポット5) カスケード1 カスケード2 人影15 カスケード0 背景影+観客 カスケード1 人物影 カスケード0 人物影 カスケード1 人物影 カスケード2 人影0 カスケード1 人影1 カスケード1 人影2 カスケード1 人影3 カスケード1 人影4 カスケード1 人影5 カスケード1 人影6 カスケード1 人影7 カスケード1 人影8 カスケード1 人影9 カスケード1 人影10 カスケード1 人影11 カスケード1 人影12 カスケード1 人影13 カスケード1 人影14 カスケード1 人影15 カスケード1 人影0 カスケード2 人影1 カスケード2 人影2 カスケード2 人影3 カスケード2 人影4 カスケード2 人影5 カスケード2 人影6 カスケード2 人影7 カスケード2 人影8 カスケード2 人影9 カスケード2 人影10 カスケード2 人影11 カスケード2 人影12 カスケード2 人影13 カスケード2 人影14 カスケード2 人影15 カスケード2
影描画 48ヵ所への描画コストが非常に高い マルチビューポート+インスタンシング 1~3回のドローコールに纏まった PS4は頂点シェーダーだけで最大16ビューポート 使用できる とても高速化された ※間違ってもジオメトリシェーダーを使ってはいけない
影描画 16回以上のスキニング計算のコストも高い ※主にスキン行列のロードコストが高い コンピュートシェーダーでプレスキニング 10%程度高速化
影描画 非同期コンピュートシェーダー 影描画中はCUに空きが多い メモリアクセスの多い処理 SSAOや露出計算も行える 全体的なCUの稼働状態を見て 埋める様に配置 (HTile圧縮解除隠蔽できず)
シェーダー最適化
シェーダー最適化 行えた最適化は極わずか • アルゴリズムの変更 • コンパイラに祈る
シェーダー最適化 アルゴリズム変更 ハイライト計算のアルゴリズムを変更 D項 Trowbridge-Reitz G項 Modified-Kelemen F項 Schlick(一部計算の省略) G項の計算の殆どが視線と法線に依存する計算にな り、準事前計算可能な変数としてライト間で共有 する事で計算コストが削減可能
シェーダー最適化 アルゴリズム変更 ライト毎に必要な計算は以下にまで削減(距離減衰等除く) float distribution = NoH2 * NDFPreComputeAlpha_1 + 1.0; float NDF = NDFPreComputeAlphaDividedPI; float GSF = saturate(GSFPreCompute * NoL); float VoHCoefficient = pow(1.0 - VoH, 5.0); float F = f0 + VoHCoefficient - f0 * VoHCoefficient; float specularReflection = (NDF * GSF * F) / (CookTorrancePreCompute * max(NoL, NLOffset) * distribution * distribution); 負荷の大半が影とライトデーター読み込みに変化
シェーダー最適化 アルゴリズム変更 失敗事例 ドームのライト負荷があまりに高いので 3ピクセルに1ピクセル計算を省いて 周辺ピクセルで埋める試み CSでライティングしているので 穴あき計算のスレッドスケジューリングのロスは0
シェーダー最適化 アルゴリズム変更 失敗事例 高速にはなったが4Kチェッカーボードでは 輪郭がガタガタになってしまった TAAが使用出来れば計算スキップ箇所をフレーム 毎に変更する事で改善されます 失敗例:選手の脚付近のアップ(毛羽立って見えます)
シェーダー最適化 コンパイラへの祈り 2つのpragma命令を使用 スケジューリング戦略 #pragma argument(scheduler=strategy) 目標CU数 #pragma argument(targetoccupancy_atallcosts=<n>) 高負荷箇所ではCU数の一段引き上げと全戦略の組み合 わせをチェック シェーダーコンパイラのバージョンアップ時は要再 チェック
シェーダー最適化 コンパイラへの祈り PS4 Proでのhalf型 PS4 Proはhalf型のまま計算が出来る命令が追加さ れている 展開コスト無しでレジスタ消費を抑えられる 成功するとCU占有率が上がる 失敗してもlatency隠蔽効率が向上
シェーダー最適化 コンパイラへの祈り 戦略的なシェーダーバリエーション コンパイラは賢く分岐コストも低いが 分岐が無ければより最適なコードを生成出来る ライティングのみ10以上のバリエーション デモ プレイアブル バリエーション例 デイゲーム(不透明) ナイトゲーム(不透明) ドーム(不透明) 通常 通常 通常 SSSSS無効 SSSSS無効 SSSSS無効 観客影有効 SSSSS無効観客影有 観客影有効 観客影有効
シェーダー最適化 少しでも人手を増やすために 社内でシェーダー最適化の勉強会を開催 (主にSIMTの仕組みとダイバージェントについて) 意識してシェーダーを書いてもらえたと思います
総括 • 目標となるビジョンは大事 “ライト大事に” • ビジョンに基づいたビジュアル戦略 “多光源影付きライティング” • 最適化はとても大変 諦めずに積み重ねる事が成果につながる
参考文献 [Schneider15]The real-time volumetric cloudscapes of Horizon Zero Dawn http://killzone.dl.playstation.net/killzone/horizonzerodawn/presentations/Siggraph15_Schneider_Real-Time_Volumetric_Cloudscapes_of_Horizon_Zero_Dawn.pdf [Schneider17]Nubis - Authoring Realtime Volumetric Cloudscapes with the Decima Engine http://advances.realtimerendering.com/s2017/Nubis%20%20Authoring%20Realtime%20Volumetric%20Cloudscapes%20with%20the%20Decima%20Engine%20-%20Final%20.pdf [sawano19]リアルタイムGI採用事例 https://hexadrive.jp/lab/30145/ [yamaguchi19]曇りとTAAへのアプローチ https://hexadrive.jp/lab/30146/ [brinck&maximov16]The Technical Art of Uncharted4 http://advances.realtimerendering.com/other/2016/naughty_dog/NaughtyDog_TechArt_Final.pdf [Uchimura17]HDR 理論と実践 https://www.slideshare.net/nikuque/hdr-theory-and-practicce-jp
謝辞 本セッション実現の為 株式会社コナミデジタルエンタテインメント様 他各種関係者様には多大なご協力を頂きました、 この場を借りて御礼申し上げます。