『モンスターハンター ブリッジ』を支える技術~未踏の映像環境を実現したマルチモニターレンダリングの実装 [RE:2026 2026年10月2日登壇]

1.5K Views

November 13, 26

スライド概要

2026年10月にカプコンが開催した「CAPCOM オープンカンファレンス RE:2026」の講演資料です。

■ 講演映像(再生リスト)
https://www.youtube.com/watch?v=f-EHRhMMPIY&list=PLD_N6X6tKlCM

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/

シェア

またはPlayer版

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

(ダウンロード不可)

関連スライド

各ページのテキスト
1.

『モンスターハンター ブリッジ』を 支える技術 ~未踏の映像環境を実現した マルチモニターレンダリングの実装 和田 功 塚越 優治 1

2.

『モンスターハンター ブリッジ』を ⽀える技術 〜未踏の映像環境を実現した マルチモニターレンダリングの実装 和⽥ 功 塚越 優治 1 それでは、『モンスターハンター ブリッジ』を⽀える技術〜未踏の映像環境を実現したマルチモニターレンダリングの実装 の講演を開始します。よろしくお願い致します。 1

3.

22 早速ですが、まずはこちらの動画をご覧ください。 2

4.

『モンスターハンター ブリッジ』紹介動画 33 ※ 映像についてはDocswell「スライド概要」へ記載のYouTube講演映像からご確認ください。 3

5.

『モンスターハンター ブリッジ』 • ⼤阪・関⻄万博の⼤阪ヘルスケアパビリオン「XD HALL」に出展 • 「ミライのエンターテインメント」がテーマの 「モンスターハンター」シリーズの世界に没⼊できる体験 44 というわけで、改めてコンテンツについてご紹介します。 『モンスターハンター ブリッジ』は、2025年に開催された⼤阪・関⻄万博、⼤阪ヘルスケアパビリオンの⼀⾓に建てられた「XD HALL(エックスディー ホール)」にカ プコンが出展した、体験型コンテンツです。 「ミライのエンターテインメント」をテーマとしており、参加者は専⽤のARデバイスを装着して360°シアター内に⼊場し、全⽅位に映し出された映像やサウンド、床振 動、ARコンテンツなどを組み合わせて構成した「モンスターハンター」シリーズの世界への没⼊体験を楽しめます。 4

6.

本講演の構成 前半︓『モンスターハンター ブリッジ』とは 後半︓ 未踏の映像環境を実現したマルチレンダリングの実装 55 本セッションは前半と後半の2部構成となっております。 前半では『モンスターハンター ブリッジ』というコンテンツそのものの紹介や体験を向上させる⼯夫についてご紹介し、 後半では特にマルチレンダリング技術にフォーカスしてご紹介します。 5

7.

前半 『モンスターハンター ブリッジ』とは 66 では、まず前半はわたくし塚越から、『モンスターハンター ブリッジ』というコンテンツについて、 企画の経緯やコンセプトといったトピックから、徐々に技術的な内容についてもお伝えします。 6

8.

77 コンテンツの紹介に先⽴ち、まずは⼤阪・関⻄万博とカプコンのつながりについてご説明します。 7

9.

成り⽴ち カプコン 企業理念 遊⽂化をクリエイトする 感性開発企業 「モンスターハンター」シリーズ テーマ ⾃然や⽣物、 ⽣命の素晴らしさ 『モンスターハンター ブリッジ』 ⼤阪・関⻄万博 テーマ いのち輝く 未来社会のデザイン ⼤阪ヘルスケアパビリオン テーマ REBORN 88 カプコンは「遊⽂化をクリエイトする感性開発企業」という理念に基づき、ゲームという媒体を通じて⼈々を魅了する企業を⽬指しています。 その創業の地・⼤阪で開催されることとなった⼤阪・関⻄万博のテーマは「いのち輝く未来社会のデザイン」、 そこに⼤阪府と⼤阪市が出展した「⼤阪ヘルスケアパビリオン」のメインテーマは「REBORN」でした。 「いのち輝く」、「REBORN」といったワードから着想を得た我々は、「⾃然や⽣物、⽣命の素晴らしさ」を主要なテーマに掲げた「モンスターハンター」シリーズを活⽤し、 体験型コンテンツ『モンスターハンター ブリッジ』を企画するに⾄りました。 8

10.

ずばり、そのコンセプトは…… 99 ずばり、そのコンセプトは…… 9

11.

夢と現実が、ひとつになる。 10 10 「夢と現実が、ひとつになる。」です。 10

12.

コンセプト︓夢と現実が、ひとつになる。 多くのゲームは「モニターの前でコントローラーを持って遊ぶ」スタイルが主流 ▼ 「ゲームの世界やキャラクターと直接触れ合う没⼊体験」の創造に挑戦 万博という⾮⽇常空間で ✓ゲームファンだけでなくより幅広い層に ✓⽇本のユーザーだけでなく世界の⼈々に 楽しんでもらえるようなコンテンツへ 11 11 皆さんもよくご存じの通り、多くのゲームは「モニターの前に座り、コントローラーを⼿に持って遊ぶ」スタイルのものがほとんどです。 しかし、『モンスターハンター ブリッジ』ではそれらの垣根を取り払うことで、ゲームの世界やキャラクターと直接触れ合うことのできるような、特別な没⼊体験を創り出す ことに挑戦しました。 万博という最先端技術の集まる⾮⽇常空間で、従来から弊社のゲームを遊んでくださっているお客様はもちろん、「モンスターハンター」シリーズに馴染みのないお客 様、さらにはゲームそのものに関⼼のないお客様でも楽しんでもらえるようなコンテンツを。 そして、その特別な体験を⽇本のお客様だけでなく世界の⼈々ともつながって共有してほしい―「夢と現実が、ひとつになる。」のコンセプトと『ブリッジ』というタイトルに は、そのような想いが込められているのです。 11

13.

12 12 さて、『モンスターハンター ブリッジ』の成り⽴ちや、そこに込めた想いについての紹介はこれまでとして、より具体的に⽤いられている技術について説明します。 12

14.

技術仕様 – 『モンスターハンター ブリッジ』を構成する4つの要素 360°シアター ARデバイス イマーシブサウンド 床振動 13 13 『モンスターハンター ブリッジ』は⼤まかに「360°シアター」「ARデバイス」「イマーシブサウンド」そして「床振動」の4つの要素から構成されます。 冒頭の紹介動画でもお⾒せした通り、ゲストはコンテンツの説明を受けたのち、ARデバイスを装着してシアターに⼊場します。 シアター内では360°映像が映し出され、それと連動したイマーシブサウンドと床振動、そしてARデバイスに投影されるキャラクターとのインタラクションを通じて、我々 の⽬指した没⼊体験を現実にします。 では、これらの主要な要素をひとつずつ紹介していきましょう。 13

15.

技術仕様 – 360°シアター 14 14 『モンスターハンター ブリッジ』を構成する要素の中でも最も⼤規模なものが、360°を取り囲む円筒形の「360°シアター」です。 14

16.

技術仕様 – 360°シアター 床⾯はプロジェクター投影 RE ENGINEによる 全⽅位リアルタイムレンダリング 側⾯と天井⾯はシースルーLED 15 15 床⾯の直径が約12メートル、⾼さが約5mの円筒形状となっており、同時に約20⼈が⼊場できます。 側⾯と天井⾯にシースルーLEDを、床⾯にプロジェクター投影を採⽤しており、天井⾯、側⾯、そして床⾯に4K 計12枚を同時に描画し、それらをつなぎ合わせる ことで全⽅位の映像を実現しています。 また、映像はRE ENGINEによるリアルタイムレンダリングによって描画されています。プリレンダではなくリアルタイムレンダリングを採⽤することで、ゲストは⾝振り⼿振 りを⽤いて映像とのインタラクションが可能になり、より没⼊度の⾼い体験を楽しむことができます。 15

17.

技術仕様 – ARデバイス 16 16 シアターと並び、視覚的な体験を提供するのが「ARデバイス」です。 16

18.

技術仕様 – ARデバイス 新規で開発した 専⽤のARデバイス ハンドトラッキングで キャラクターとインタラクション 現実世界が⾒える光学シースルー型で 360°シアターとARコンテンツを重ねて表⽰ 17 17 没⼊体験の核となる「インタラクション性」の実現には、ARデバイスの存在が⽋かせません。 このARデバイスは「光学シースルー型」というタイプのヘッドマウントディスプレイで、ゲストの視界を完全に覆うようなVRヘッドセットと異なり、⾁眼で周囲の現実世界 を視認しながら、同時にレンズに投影された⽴体コンテンツを楽しむことが可能です。 つまり『モンスターハンター ブリッジ』は、全⽅位のシアター映像に囲まれた中で、ARデバイスに投影されたキャラクターとインタラクションが楽しめる、という作りになって います。 インタラクションには主にゲストの⼿を⽤います。デバイスに搭載されたカメラによって⼿の位置姿勢をトラッキングしコンテンツに反映することで、例えばオトモアイルーを ⼿で撫でたり、迫りくるモンスターに⽯を投げたり、という体験が可能になるのです。 17

19.

技術仕様 – イマーシブサウンド 18 18 続いて、シアターに並んで重要な役割を果たす「イマーシブサウンド」を紹介します。 18

20.

技術仕様 – イマーシブサウンド 側⾯70台、頭上19台のスピーカー 4台のサブウーファー シースルーLEDを通じて 360°シアター内にサウンドを届ける 19 19 このイマーシブサウンドシステムは、円筒形のシアターを取り囲む形で構築されています。 図に⽰しました通り、側⾯に⾼さを変えて計70台、頭上には19台、そして4台のサブウーファーが配置されており、そのチャンネル数は89.1chを誇ります。 先ほども軽く触れましたが、シアターの天井⾯と側⾯にはシースルーLEDを採⽤しています。つまりLEDパネルの表⾯に物理的な透過⽳が開いているため、その外 側に配置したスピーカーのサウンドは損なわれることなく、理想的な状態のままゲストに届けられます。 19

21.

技術仕様 – 床振動 20 20 イマーシブサウンドと関連してお話ししたいのが、4つ⽬の要素である「床振動」です。 20

22.

技術仕様 – 床振動 演出と連動した振動ユニットを 床下に設置 ゲストの⾝体に直接作⽤し 没⼊度を向上 21 21 床⾯のさらに下に設置された床振動ユニットは、これまでにご紹介したシアターの映像やイマーシブサウンドと協調して動作し、 ゲストの⾝体に直接作⽤するという重要な役割を果たします。 体験型コンテンツでは⼀般に視覚や聴覚提⽰が優先されることが多いですが、本コンテンツでは触覚提⽰もフル活⽤して⼤⾃然の厳しさを表現します。 また、いわゆるハプティックグローブのようにゲストがデバイスを直接装着する必要がないため、振動ユニットの⼤型化も容易であり、 結果としてゲストの快適さと振動のスケールを両⽴することにも成功しました。 21

23.

技術仕様 – 『モンスターハンター ブリッジ』を構成する4つの要素(おさらい) 360°シアター ARデバイス イマーシブサウンド 床振動 22 22 以上が『モンスターハンター ブリッジ』を構成する4つの主要な要素の紹介でした。 「360°シアター」「ARデバイス」「イマーシブサウンド」そして「床振動」。いずれも本コンテンツのために最新技術を惜しみなく注ぎました。 22

24.

23 23 しかし「夢と現実が、ひとつになる。」体験の実現には、これらの要素をただ並べるだけではなく、効果的に組み合わせることが不可⽋です。 本セッションでは、視覚的な体験の質を⼤きく左右する「シアターとARデバイスの組み合わせ」にフォーカスし、具体的にどのような⼯夫を施したのか、その⼀部をご紹 介することにします。 23

25.

最⼤の課題は「境界」を感じさせないこと 360°シアター映像 • 空間全体を包み込む • ⾼品質でスケールのある表現が得意 ARコンテンツ • ⽬の前に存在するように⾒える • インタラクションが可能 課題 • 単に重ねるだけでは両者は別々の映像に⾒えてしまう 24 24 シアター映像は、ゲストの周囲360°を取り囲み、巨⼤なモンスターや⾃然環境のスケール感を表現できます。 ⼀⽅でARコンテンツは、ゲストの⽬の前にキャラクターやオブジェクトが存在しているように⾒せられ、⼿を使ったインタラクションも可能です。 しかし、この2つは表⽰される場所も性質も⼤きく異なるため、単にそれらを重ねるだけでは、ゲストには「シアターの映像」と「ARの映像」が別々のものとして⾒えてし まいます。 「夢と現実が、ひとつになる。」体験の実現のためには、この境界をいかに感じさせないかが⼤きな課題でした。 24

26.

「境界を消す」ために⾏ったこと 360°シアターとARの境界を消す • 同じ存在として⾒せる • ⾏動の結果を世界に返す • 空間の質感を揃える • 明るさを設計する ゲスト間の境界を消す • 共有体験を提供する 25 25 そこで我々は、シアターとARの境界を感じさせないための様々な⼯夫を施しました。 本セッションではその中から、5つの事例を紹介します。 25

27.

360°シアターとARの境界を消す – 同じ存在として⾒せる 例︓⽕⼭エリアのリオレウス • まずはARで登場 ⇒ ゲストが⽯を投げてインタラクション • 途中で360°シアター表現に移⾏ ⇒ ラージャンとの縄張り争いを⼤スケールで表現 ARで登場するリオレウス ねらい • 表⽰媒体が変わっても 同じキャラクターとして認識させる 360°シアターで登場するリオレウスとラージャン 26 26 ⽕⼭エリアに登場する⼤型モンスター、リオレウスを例にしてひとつ⽬の事例を紹介します。 リオレウスは最初、ARコンテンツとして登場します。 ゲストは⽯を投げて応戦できるため、ここでは「⾃分が関われる存在」としてリオレウスを感じてもらいます。 その後、リオレウスはシアター側の表現に移⾏し、ラージャンとの縄張り争いを展開します。 ここではRE ENGINEによるシアター映像や床振動を活かし、⼤型モンスター同⼠のスケール感を表現しています。 重要なのは、ARとシアターで表⽰媒体が変わっても、ゲストには「同じリオレウスがそこにいる」と感じてもらうことです。 26

28.

360°シアターとARの境界を消す – ⾏動の結果を世界に返す 例︓船上エリアのラージャン • AR側 ⇒ ゲストが砲弾を投げる • 360°シアター側 ⇒ 着弾位置に爆⾵を描画 ねらい • ⾃分がこの世界に影響を与えたと感じさせる AR砲弾の爆⾵が多数360°シアターに描画されている 27 27 次の事例は、船上エリアのラージャンです。 このシーンでは、ゲストがARデバイス上に表⽰された砲弾を投げて応戦する遊びを⽤意しました。 砲弾そのものはARで表現していますが、着弾時に⽣じる爆⾵はシアター側に描画しています。 これによって、ゲストの⾏動がARデバイスの中だけで完結せず、シアター全体の世界に影響したように⾒え、 ゲストに対して「⾃分がこの世界に影響を与えた」という感覚を与えています。 27

29.

360°シアターとARの境界を消す – 空間の質感を揃える 例︓船上エリア ラギアクルス登場 • 360°シアター側 ⇒ ラギアクルスの周りに⽔しぶき • AR側 ⇒ ゲストの近くにも同様の⽔しぶきパーティクルを配置 ねらい • 360°シアターの質感とARの質感を揃え、空間の境界をぼかす 360°シアター(ラギアクルス+⽔しぶき) AR(⽔しぶき) タイミングを合わせて両⽅を再⽣ 28 28 3つ⽬は、より繊細な⼯夫です。 ラギアクルスというモンスターの登場シーンを⾒てみましょう。 シアター側で海中から現れるラギアクルスの周りには⽔しぶきが表現されています。 それに合わせて、AR側にも同様の⾒た⽬をした⽔しぶきのパーティクルを配置しました。 シアターだけに⽔しぶきがあると、それは「スクリーンの向こうの⾵景」に⾒えてしまいます。 しかし、AR側にも⽴体的なパーティクルを配置することで、ゲストの近くまで登場の余波が流れ込んできたように感じられます。 これによって、シアターとARの境界をさらに曖昧にしています。 28

30.

360°シアターとARの境界を消す – 輝度の壁 ARコンテンツ • 半透明で表⽰される シアターLED • ⾼輝度で空間を包み込む 課題 • 360°シアターが明るすぎると、ARキャラクターが⾒えづらくなる ARコンテンツ シアターLED 重ね合わせで⾒えづらく 29 29 実際にシアターとARコンテンツの重ね合わせを成⽴させるうえでは、⼤きな壁がありました。それがARデバイスに搭載されたディスプレイとシアターLEDの輝度差です。 ARデバイスに表⽰されるコンテンツは半透明になるため、⾼輝度のシアター映像と重なると⾒えづらくなってしまいます。 つまり、シアターの表現を強化すればするほど、AR側の体験を損なう可能性がありました。 29

31.

360°シアターとARの境界を消す – 明るさを設計する 例︓草原エリア • 床付近を少し暗くする ⇒ ARオトモアイルーの視認性を確保 30 30 そこで、シアター側の輝度を演出に合わせてコントロールしました。 例えば草原エリアでは、床に近い部分をわずかに暗くすることで、地⾯に⽴っているARのオトモアイルーが⾒えづらくならないようにしています。 30

32.

360°シアターとARの境界を消す – 明るさを設計する 例︓⽕⼭エリア • はじめは溶岩も明るく発光している ⇒ 360°シアターの⾵景を重視 • 途中から溶岩の発光がおさまる ⇒ ARリオレウスの視認性を確保 ねらい • その瞬間に⾒てほしいものを際⽴たせる 31 31 また、⽕⼭エリアでは、序盤は溶岩を明るく⾒せて、まずはシアターの⾵景を印象づけます。 その後、ARリオレウスとのインタラクションが始まるタイミングでは、溶岩の発光を抑えています。 つまり、常にすべてを⽬⽴たせようとするのではなく、その瞬間にゲストに⾒てほしいものが最もよく⾒えるように、シアターとARの明るさのバランスには特に気を配って 体験を設計しました。 31

33.

ゲスト間の境界を消す – 共有体験を提供する 例︓⽕⼭エリアのリオレウス • ARリオレウスの位置を同期 ⇒ どのゲストから⾒ても同じ場所に存在 • 投げた⽯も同期 ⇒ 他のゲストの⾏動も反映される ねらい • 360°シアター内の全員が • 1体の強⼤なモンスターに • 共に⽴ち向かっているという感覚を届ける ARで登場するリオレウスと、それに⽴ち向かうゲスト 32 32 ここまでの⼯夫は、シアターとARをひとつの世界として⾒せるためのものでした。 さらに『モンスターハンター ブリッジ』では、その世界をゲスト全員で共有することも重視しました。 例えば⽕⼭エリアのリオレウスは、どのゲストから⾒ても同じ位置にいるように同期しています。 また、あるゲストが投げた⽯は、他のゲストからも⾒えるようにしています。 これによって、各⾃がARデバイスで個別に体験しているのではなく、「シアター内の全員が」「同じ1体の強⼤なモンスターに」共に⽴ち向かっている、という感覚を作っ ています。 32

34.

技術統合=体験をひとつにすること 360°シアターとARをつなぐための様々な⼯夫 1. 同じ存在として⾒せる 2. ⾏動の結果を世界に返す 3. 空間の質感を揃える 4. 明るさを設計する 5. 共有体験を提供する これらの積み重ねで「夢と現実が、ひとつになる。」体験を⽬指した 33 33 シアターとARデバイスの統合とは、単に2つの表⽰装置を同時に動かすことではありませんでした。 キャラクターを同じ存在として⾒せる。 ゲストの⾏動をシアター側の世界に返す。 空間の質感を揃える。 さらに、ARとシアターのどちらも損なわないように、世界の明るさにも気を配って設計する。 そして、その体験をゲスト全員で共有できるようにする。 こうした⼯夫の積み重ねによって、「夢と現実が、ひとつになる。」というコンセプトを体験として成⽴させたのでした。 33

35.

前半のまとめ 『モンスターハンター ブリッジ』は4つの要素から構成 360°シアター ARデバイス イマーシブサウンド 床振動 それらを統合し「夢と現実が、ひとつになる。」のコンセプトのもと 「ミライのエンターテインメント」を実現 後半では、360°シアターを実現したマルチレンダリング技術にフォーカスして紹介 34 34 さて、前半はここまでとなります。 『モンスターハンター ブリッジ』を構成する4つの要素やそれらの統合に関する⼯夫の紹介を通じ、 「夢と現実が、ひとつになる。」のコンセプトのもと「ミライのエンターテインメント」をいかにして実現したのか、その⼀端でも伝わったのであれば幸いです。 後半では和⽥より、360°シアターの実現を⽀えたマルチレンダリング技術にフォーカスしてご紹介します。 34

36.

未踏の映像環境を実現した マルチレンダリングの実装 35 35 塚越さん、コンテンツのご解説ありがとうございました。 ここからは私、和⽥に代わりましてレンダリングについてのお話をさせて頂きます。 35

37.

はじめに 360°に広がるゲーム世界との境界をなくす没⼊空間 36 36 今回お話をさせて頂く内容は、XD HALL内、360°シアターの話です。 後ろの範囲全般、シームレスに広がるパノラマ空間ですが 壁も床も含めたリアルタイムでのレンダリングを⾏っております。 ARデバイスとの組み合わせでまさに境界が無く、ゲームの世界そのものにいるような ⾼い没⼊体験を提供できているかと思います。 36

38.

はじめに 通常のゲーム開発との⽐較 通常のゲーム 『モンスターハンター ブリッジ』 GPU 1つ 4つを同期 出⼒ 4K × 1〜2 巨⼤なパネル + プロジェクターの4K × 12 環境 PC1台の中だけ 360°シアター + ARコンテンツ + イマーシブサウンド + 床振動 すべて連動するリアルタイム処理 • モニターの前だけで完結するのではなく、巨⼤な空間の • 描画負荷12倍を想定 + リアルタイムレンダリング ⇒ 通常のゲームの前提が通⽤しない 37 37 さてこの構成は、通常のゲーム開発と⽐較すると 想定されていない内容とスケールであることがわかります。 使⽤するGPUは4つ 出⼒先は4K × 12 さらに、AR、サウンド、床振動、これらともリアルタイムに連携します。 通常のゲームの前提が通⽤しない、まさに未踏の試みと⾔えます。 37

39.

はじめに 特異な構成に対して3つの取り組みで実現 ① 4つのGPUを並列に⽤いたレンダリング ② GPU間で同期されたリアルタイムキューブマップ ③ 円柱上への12ディスプレイへの出⼒ 既存のRE ENGINEには存在しない機能であり 他での前例も少ない GPU並列レンダリング GPU間での同期 想定していなかった特有の問題が、様々な観点から発⽣ ⇒ レンダリングの設計から実現までの解説 12ディスプレイ出⼒ 38 38 そのような特異な構成に対して、我々はレンダリング処理として 4つのGPUを並列に⽤いて GPU間でのキューブマップの同期 そして円柱上への複数ディスプレイへの出⼒ これらを実装することで実現致しました。 既存のRE ENGINEの機能では存在せず、参考となる前例も少ない内容です。 思いもよらなかった特有の問題も、複数の⾓度から発⽣しました。 今回はそれらについてお話しさせて頂きます。 38

40.

1.360°シアターの構成 360°シアターの詳細な仕様とPC構成など、経緯を追った説明 2.実現に向けたレンダリングの実装 実装されたマルチレンダリングに関する、技術的な解説 3.開発が進むと⾒えてくる問題 RE ENGINE上での開発環境や マルチレンダリング以外で必要になった機能や改善 4.現地で出てきた問題 XD HALLが出来上がったあと、現地で⽣じた問題と対応 5.まとめ 39 39 本内容につきましては 360°シアターの構成 実現に向けたレンダリングの実装 開発が進むと⾒えてくる問題 現地で出てきた問題 そしてまとめ このように進めさせて頂きますので、よろしくお願い致します。 39

41.

40 40 では、まずは360°シアターの構成 そしてその経緯についてお話致します。 40

42.

360°シアターの構成 XD HALLの構成案と成り⽴ち • 「ミライのエンターテインメント」として 360°シアター + ARデバイス の没⼊空間体験 • コンテンツ内容と共に360°シアター形状の議論 ⽅式 ⇒ プロジェクター投影 形状 ⇒ ボックス 半球 全⾯LED 等 円柱 RE ENGINEはこの検証としても使⽤された • 結果下記は⾮採⽤ ボックス ⇒ 壁や天井の⾓が⽬⽴つ 半球 ⇒ 壁に近いと空が迫る 41 41 「ミライのエンターテインメント」として 360°シアターの中でARデバイスを使⽤し、没⼊空間への体験を提供する。 このプロジェクトの⽬指すものは、そう定義されていました。 その中で提供されるコンテンツと、それに適したXD HALL⾃体の議論もありました。 ⽅式としてはプロジェクター投影や、全⾯LEDなどの案があり、 そして形状として、ボックスや半球という案も出ました。 また、RE ENGINEはXD HALL⾃体の検証としても活⽤されました。 41

43.

360°シアターの検証 42 42 こちらは案があった形状に対して、パノラマ動画をあてはめているものとなります。 ご覧の通り、半球では壁に近づいた時の天井が気になります。 また、ボックスではやはり⾓が⽬⽴ちます。 そして円柱であれば、⼀番違和感の出ない形状として提供できそうに⾒えます。 ※ 映像についてはDocswell「スライド概要」へ記載のYouTube講演映像からご確認ください。 42

44.

360°シアターの構成 円柱型決定後の構成 • 床⾯ ︓天井からのプロジェクター投影 (床振動のため) • 天井と壁︓シースルーLED(イマーシブサウンド⽤) 最終的な360°シアターの仕様 • 壁⾯︓シースルーLED 4つ • 天井︓シースルーLED 2つ • 床⾯︓プロジェクター投影 6つ 出⼒先4K x 12枚 ⇒ 通常のゲームの12倍のレンダリング負荷 43 43 結果としてXD HALLの形状は、円柱に決まりました。 また、床は振動を使⽤するため物理的なディスプレイは使⽤せず 天井からのプロジェクター投影に。 天井と壁はイマーシブサウンドも考慮して シースルーLEDを使⽤することに決定しました。 XD HALL内は巨⼤な空間です。 そのため解像度も⾼くしなければならず ディスプレイ出⼒は4Kを基本として構成され、出⼒先は12枚となりました。 単純計算でも通常のゲームの12倍のレンダリング負荷となりそうな規模となったのです。 43

45.

360°シアターの構成 構成に対しての問題点 File Stream? • 単⼀GPUではレンダリングが間に合わない CubeMap File? CubeMap File? CubeMap File? CubeMap CubeMapFile? File? • キューブマップならリアルタイムレンダリング可能 ⇒ ディスプレイごとに直接ではなく 360°を⼀度だけレンダリングして共有可能 それでも2Kが限界で品質不⾜ 動画ストリーミングにするしかなくなる︖ • ディスプレイ出⼒を同期させるための仕組みも必要 • 複数台PCを使⽤する構成 ⇒ AR + イマーシブサウンド + 床振動の連携 体験時の運営、開発も考えると難しい PCの構成は1台に集約せざるを得ない Display A Display B Display C Floor AR 1App Sound Rendering 44 44 もちろん単⼀GPUではレンダリングが間に合わないことが予想されます。 通常のゲームでは最適化しても4Kは1枚か2枚で限界です。 例えば、直接ディスプレイごとにレンダリングするのではなくキューブマップから切り出す⽅法であれば、360°にリアルタイムレンダリングできそうです。 また⼀度のレンダリングで複数ディスプレイに共有もできるため、重複する描画のコストも抑えられそうです。 しかし⾼性能のGPUでも、2Kサイズのキューブマップが限界です。 それ以上の解像度とすると、動画ファイルでのストリーミングにするしかないレンダリング負荷です。 さらに全ディスプレイ同⼠、同期させるための仕組みも必要です。そうすると、複数台のPC構成にて構築することも難しく思えます。 当然ARもイマーシブサウンドも床振動も、すべてを連携させなければならず、もちろん体験型コンテンツである以上、 運営のオペレーションの簡易さも考慮する必要があります。 ⼀台に集約せざるを得ません。 44

46.

360°シアターの構成 専⽤の「モンスターPC」を構築 CPU︓Intel Xeon Gold 5415+(8コア 16スレッド)x 2 GPU︓NVIDIA RTX 6000 Ada × 4 91.1 TFLOPS VRAM48GB MemBW 960 GB/s PCIe 4.0 NVIDIA Quadro Sync II にて同期 過去タイトルや性能から計算すると 理論上ではRE ENGINE 4Kのキューブマップ + 4Kを12枚出⼒可能 ⇒ 必要なのは マルチGPUとマルチディスプレイへのレンダリング 45 45 そこで専⽤PCが構築されました。 モンスターPCと名付けられた本プロジェクト専⽤の構成です。 CPU2つを搭載しており、Quadro Sync II でのGPUとディスプレイ同期機構もあり、それに対応した⾼性能のGPUが4つも搭載されています。 まさにモンスター級です。 4Kのキューブマップを作成し、そのまま4Kの12枚ディスプレイ出⼒もできると⾒積もられた構成です。 後はマルチGPUとマルチディスプレイへのマルチレンダリング この実装がなされれば達成となります。 45

47.

360°シアターの構成 360°シアターの構成と要件が決定 レンダリングは リアルタイムに4Kの キューブマップ 円柱上に12枚の ディスプレイへの出⼒ 他要素との リアルタイム連携のため、 1台のモンスターPCに集約 AR Floor Sound Rendering 4つのGPUを使⽤して マルチレンダリング ⇒ ⼤まかな仕様が決まり、具体的な実装へ 46 46 ここまでが今回の対応が必要となった経緯となります。 12枚のマルチディスプレイへの出⼒。 4Kキューブマップへのリアルタイムレンダリング。 それらを単⼀のPCの単⼀のアプリケーションにて、 4つのGPUを使⽤したマルチレンダリングの実装を⾏うということです。 これで仕様や要件が決まりましたのでここからは具体的な実装に⼊っていきます。 46

48.

360°シアターの構成 構成の構築はカプコンだけでは実現できませんでした。 ヒビノ株式会社様 LED及びパネルやプロジェクターのご⽤意、建設を含み ティフォン株式会社様 モンスターPCの構築や、ディスプレイ転送構築 NVIDIA Corporation様 RTX 6000 Adaの⼿配や、技術サポート この場でお礼を申し上げます。 47 47 実装の話の前に謝辞を述べさせて頂きます。 この構成はカプコンのみでは構築することはできませんでした。 関連した会社の皆様、改めてお礼を申し上げます。 47

49.

48 48 では、具体的なレンダリング実装をお話していきます。 48

50.

実現に向けたレンダリングの実装 設計の基盤 どのように実現していくか︖ 通常の12倍負荷のレンダリング構成 4Kキューブマップ + リアルタイムレンダリング ⇒ 4つのGPUに分散することが必要︖ ⇒ 1つのアプリケーションでマルチレンダリング︖ 切り⼝は何か︖ 49 49 さて、どのように実現していくかを考えます。 通常の12倍の描画負荷ともなるレンダリング構成です。 4つのGPUに分散させて使⽤させる必要があります。 そのうえ4Kキューブマップをリアルタイムでレンダリング、 それを1つのアプリケーション内で実装する必要があります。 ではその切り⼝はどう考えられるでしょうか︖ 49

51.

実現に向けたレンダリングの実装 設計の基盤 考えられる要素と切り⼝ 1.キューブマップ各⾯をGPUに分散︖ 2.各⾯を送受信してキューブマップとして同期︖ 3.各ディスプレイに切り出して出⼒︖ Display × 12 ⇒ RE ENGINEは中間描画命令をCPUで作成し、GPU⽤のネイティブ命令に変換 [出典1] 分散や同期の⽅法によっては、GPUもCPUも負荷が増加してしまう 50 50 まずは要素を整理してみます。 1つはキューブマップの各⾯を、各GPUに分散するということです。 そしてそのキューブマップをGPU間で、送受信して同期する必要がありそうです。 最後に各ディスプレイに対しても、GPUが分散して出⼒する必要があります。 RE ENGINEは中間描画命令をCPUで作成し GPU⽤のネイティブ描画命令に変換して実⾏する、レンダリングパイプラインとなっています。 ここで問題になるのは キューブマップとディスプレイの分散やGPU間の同期が、 実装⽅法によってはGPUに対してもCPUに対しても負荷の増加の要因となってしまうということです。 50

52.

実現に向けたレンダリングの実装 設計の基盤 検討例 Cloud • 各キューブマップのカメラ範囲だけ カリングなどで切り分け Load&Draw • ロードや描画も必要なGPUのみ Monster Cloud Ground Grass • しかし 途中のレンダリング結果の共有など、GPU間の同期連動が細かく必要 • カメラ毎に異なる中間命令作成となり、CPUの負荷も上昇 ⇒ 不採⽤ Monster Motion Record Draw Command (CPU) NG Temporal Cloud Sync… Draw Monster Motion Temporal Cloud Ground Grass Wind… 51 51 では、分散⽅法を検討してみましょう。 例えば各キューブマップのカメラ範囲だけを切り分け、ロードや描画も必要なGPUに対して振り分ければ効率は良く無駄も無いように思えます。 しかし、空の雲がテンポラルな蓄積で動作していたとしたら︖ モーションや揺れ物はどうなるでしょうか︖ この⽅法ではそれらのレンダリング途中の情報を細かくGPU間で同期する必要が出てしまいます。 また、カメラ毎に異なる中間命令の作成をGPUごとにバラバラに構築するために、CPUの負荷も⾼くなることが予想されます。 そのためこれは採⽤できません。 51

53.

実現に向けたレンダリングの実装 設計の基盤 RE ENGINEでの設計 • リソースをすべてのGPUに読み込み • 中間命令の作成も同⼀のものを使⽤させる Cloud Ground Monster Grass Load&Draw • 同期はレンダリング済みのキューブマップのみに抑える OK Record Draw Command (CPU) Monster Motion Temporal Cloud Ground Grass Wind Draw GPUの同期も最⼩ + CPUでの中間命令の負荷も1つで済む 52 52 そこで我々は別のアプローチを選択しました。 同⼀のリソースをすべてのGPUに読み込ませ、 中間命令の作成も、同⼀で1つのものを全てのGPUに使⽤させました。 同期はレンダリング済みのキューブマップのみに抑えております。 これによってGPUの同期も最⼩に抑えられ CPUでの中間命令も、GPUごとにバラバラに作成する必要もありません。 52

54.

実現に向けたレンダリングの実装 設計の基盤 同⼀のリソースと同じ中間命令の設計にする意味 • GPU計算やシミュレーションが同期不要でズレない ⇒ パーティクルやCloth、フレーム蓄積する雲、⾵など • 1つの中間命令のため、デバッグも容易 デメリット • VRAM容量は効率的ではない ⇒ しかし48GBと潤沢 • ロード時間は短縮されない ⇒ ただし増加もしない+ 体験⼊れ替え時間もある カプコンは過去NVIDIA SLI対応やNintendo 3DSでの⽴体視を経験している 基盤はそれらを参考にしつつ、独⾃に実装 53 53 中間命令が同⼀でリソースも同⼀ならば GPU計算での揺れ物やパーティクルなどのシミュレーション系統や蓄積型の雲なども 同期不要でズレないというメリットも⽣まれます。 そしてデバッグも容易であることも挙げられます。 デメリットはありますが、VRAMは潤沢で ロード時間についても体験の⼊れ替え時間を考慮すると問題ありません。 過去似たような構成として、カプコンでは SLIや3DSの⽴体視のための描画を経験しています。 考えの基盤はそれらを参考にしつつ独⾃の実装として考慮致しました。 53

55.

実現に向けたレンダリングの実装 設計の基盤から具体的な課題へ ①GPUの役割分担をどうするか 分担をどのように⾏わせるのか ⇒ ここが基点 ②GPU同期した転送を実現する 実際にキューブマップを同期させる ⇒ ⼀番コアとなる難しい実装 ③マルチディスプレイへの出⼒ 仕上げとした出⼒ ⇒ ここまで解決するとシステムが形になったことが⾒える 54 54 さて、設計の基盤はまとまりました。 具体的な課題がこちらとなります。 この3つが実装の⼤きな核となりますので順にお話していきます。 54

56.

実現に向けたレンダリングの実装 設計の基盤から具体的な課題へ ①GPUの役割分担をどうするか 分担をどのように⾏わせるのか ⇒ ここが基点 ②GPU同期した転送を実現する 実際にキューブマップを同期させる ⇒ ⼀番コアとなる難しい実装 ③マルチディスプレイへの出⼒ 仕上げとした出⼒ ⇒ ここまで解決するとシステムが形になったことが⾒える 55 55 まずは、基点となるGPUの役割分担についてです。 55

57.

実現に向けたレンダリングの実装 ①GPUの役割分担をどうするか 中間命令はそのまま同⼀ではない、3つの対応 1.GPUごとに番号を振り分け、それぞれをデバイスインスタンスとする 2.ExecMaskを定義し、中間命令に設定 ⇒ どのGPUが実⾏するかを切り替え可に ExecMask : 1101 GPU0︓0001 ExecMaskは実⾏するGPUを 選択するためのBitマスク GPU Command … DrawInstance() ExecMask : 0xD = b1101 GPU Command … • キューブマップ⾯の担当GPUの振り分けが可能に GPU1︓0010 GPU2︓0100 GPU3︓1000 • ディスプレイ出⼒に対応した SwapChainの保持や出⼒もGPU振り分け 56 56 リソースも中間命令もすべてが同⼀と説明しましたが 完全に同⼀ではありません。 まず、GPUごとに番号を振り分けたうえで それぞれデバイス層の実装のインスタンスとして保有します。 そのうえで、どのGPU番号に実⾏するのかを指定するBitマスクのExecMaskを定義し 中間命令に設定します。 これによるBitマスクの判定によって どのGPUがキューブマップのどの⾯をレンダリングするのかを振り分けます。 またディスプレイに対応したSwapChainの保持と出⼒のGPU振り分けもできます。 56

58.

実現に向けたレンダリングの実装 ①GPUの役割分担をどうするか 3.別GPUのデバイスもTextureリソースも1つに抽象化 Texture A : For GPU0 Texture A : For GPU1 • レンダリング機能も既存のコードのまま扱える CreateTexture() MultiTexture A : For All GPUs • 抽象化リソースはそのまま使⽤できない ⇒ デバイスに渡すとき、コピーしながら 各GPUデバイス⽤の実体リソースに差し替える • 新規実装も少ない GPU Command … DrawInstance() MultiTexture A Copy & Replace • 実装期間も短い • CPU負荷も⼗分に少なく済む GPU Command … GPU Command … DrawInstance() Texture A : For GPU0 DrawInstance() Texture A : For GPU1 ExecuteDevice : GPU0 ExecuteDevice : GPU1 57 57 そして、デバイスもTextureリソースも抽象化します。 GPUが別々であっても、1つのインスタンスとしてみなせるため、既存コードへの変更も不要となります。 ただし、抽象化されているリソースはそのまま使⽤できません。 あくまで実体は各独⽴したGPUのデバイスに対して存在し、異なるGPUデバイスからは参照できないためです。 そのため中間命令をGPUデバイスに渡すとき、各GPU向けにコピーしながら、抽象化リソースをGPU⽤の実体へと差し替えております。 結果として実装⾃体も期間も短く、そして、CPU負荷も⼗分に少なく済む⽅法となりました。 57

59.

実現に向けたレンダリングの実装 ①GPUの役割分担をどうするか 分散実装のまとめ 1.GPUに役割⽤の番号を割り当て 2.1つの中間命令を、ExecMaskにてGPU毎に切り替え 3.デバイスやTextureリソースの抽象化 GPU0︓0001 GPU1︓0010 GPU Command … Texture A : For GPU0 Texture A : For GPU1 DrawInstance() ExecMask : 0xD = b1101 GPU Command … MultiTexture A : For All GPUs 58 58 ここまでで GPU番号とExecMask、デバイスやリソースの抽象化 これらによって役割を割り振ることができました。 58

60.

実現に向けたレンダリングの実装 設計の基盤から具体的な課題へ ①GPUの役割分担をどうするか 分担をどのように⾏わせるのか ⇒ ここが基点 ②GPU同期した転送を実現する 実際にキューブマップを同期させる ⇒ ⼀番コアとなる難しい実装 ③マルチディスプレイへの出⼒ 仕上げとした出⼒ ⇒ ここまで解決するとシステムが形になったことが⾒える 59 59 次は同期と転送に取り組んでいきます。 ⼀番難しい箇所になります。 59

61.

実現に向けたレンダリングの実装 ②GPU同期した転送を実現する 達成したい流れ GPU間で直接メモリを共有できるHeap 各GPU担当の レンダリング⾯ Shared Heaps で共有 実際の対応 Shared Heapsで転送の実装 同期の問題と対処 転送負荷の問題と対処 YUV圧縮で 転送量の削減 SendTexture と ReceiveTexture を作成 ダブルバッファにして フレームのズレを防⽌ 1⾯のペアとして仮想化 並列処理で 転送待ちの隠ぺい マルチレンダリングの リアルタイム キューブマップの共有︕ 60 60 ここは情報も多いため、まずは⼤枠をお⾒せ致します。 やりたいことは各GPUのレンダリング結果を他のGPUに転送同期し マルチレンダリングでのキューブマップを作製するだけです。 しかし実装は多くの段階があり、そして多くの問題も出てきました。 それでは、それぞれの対応説明を進めさせて頂きます。 60

62.

実現に向けたレンダリングの実装 ②GPU同期した転送を実現する GPU同期とは︖そして何が必要︖ • 各GPUで分散して4Kテクスチャにレンダリング • キューブマップの6⾯の1⾯としてテクスチャを使⽤する • GPUを跨いで1つの4Kキューブマップを完成させる All GPU Shared 4K Cube Map!! 61 61 同期するとはどのようなことでしょうか。 各GPUが分散してレンダリングしたキューブマップのうちの各⾯、 それらを複数のGPUを跨いで6⾯に結合させること。 これを同期するということと定義し、 これが出来れば共有された4Kのキューブマップが完成することとなります。 61

63.

実現に向けたレンダリングの実装 ②GPU同期した転送を実現する 具体的な実装とAPI • Multi-adapter systems [出典2] によって複数のGPUに分担や命令発⾏が可能となる • Shared Heaps [出典3] は複数のGPU間で直接メモリを共有できるHeap • GPU間を跨いで、テクスチャの送受信と同期が可能になる Send Receive Shared Heaps Shared Heaps 62 62 では、具体的な実装を説明していきます。 Multi-adapter systemsというDirectX 12の機能は 複数のGPUに分担や命令発⾏が可能となるものです。 その機能の1つであるShared Heapsを利⽤します。 本来異なるGPU同⼠はメモリの共有は出来ず、CPUを中継した転送は負荷が⾼すぎますが、 こちらは複数のアダプター間、つまりGPU間で直接メモリを共有できるHeapです。 これでGPU間でテクスチャの送受信が可能になりますので設計を進めます。 62

64.

実現に向けたレンダリングの実装 ②GPU同期した転送を実現する 送信⽤テクスチャの SendTexture を作成 • Shared Heapsのフラグを指定してHeapとFenceを作成し、共有⽤のハンドルを作成 • Heap内に1つだけコピー先Textureを作成 • ⾯へのレンダリングを担当する、送る側のGPUが保持 レンダリング & 送信するGPU Copy Shared Heaps Heap Handle レンダリング後の⾯ SendTexture CreateSharedHandle() Handle Fence 受信先GPUへ送信 受信するGPUで使⽤ 63 63 APIを交えた具体的な実装はこの場では控えさせていただきますが、 Shared Heapsのフラグを指定してHeapとFenceを作成し そこから他のGPUで使⽤する、共有⽤ハンドルを作成しておきます。 そしてHeap内に1つだけコピー先Textureを作成します。 これを送信⽤テクスチャである SendTexture と定義しますが ⾯へのレンダリングを担当する、送る側のGPUだけが保持するTextureです。 63

65.

実現に向けたレンダリングの実装 ②GPU同期した転送を実現する 受信⽤テクスチャの ReceiveTexture を作成 • SendTextureのハンドルから、受信⽤のHeapとFenceを作成 • こちらもHeapに1つだけ、コピー元としてのTextureを作成 • 受け取る側のGPU3つが、レンダリングを担当しない⾯として保持 受信側GPU 送信GPUのHandleから作成 Shared Heaps Heap Handle 送信GPUから受信 SendTexture OpenSharedHandle() Handle 受け取った キューブマップの⾯ Fence Copy 64 64 そしてSendTextureのハンドルを使⽤して、受信⽤のHeapとFenceを作成します。 こちらのHeapにも、同じように1つだけTextureを作成します。 こちらは受信⽤テクスチャとして ReceiveTexture と定義します。 これをレンダリングを担当しない⾯の、受け取る側の他GPU3つにそれぞれ保持させます。 64

66.

実現に向けたレンダリングの実装 ②GPU同期した転送を実現する キューブマップの1⾯の構成 • 1⾯毎に仮想化された1つのテクスチャとして扱う、それを6⾯⽤意 • ExecMaskを、SendTextureとReceiveTextureの切り替えにも使⽤ • レンダリング結果のRender Target Texture(RT Texture)から、Copyすると転送される Render Target Texture (RT Texture) MultiTexture FaceN ExecMask: b0010 CopyTexture キューブマップの1⾯は 1つのGPUではSendTextureとする 他の3つではReceiveTextureとする ⾯ごとにSendTextureを 担当するGPUは異なる CubeMap Face N SendTexture GPU1:0010 ReceiveTexture GPU0:0001 ReceiveTexture GPU2:0100 ReceiveTexture GPU3:1000 65 65 そして SendTexture と ReceiveTexture の組み合わせを キューブマップに合わせて6⾯作成します。 ExecMaskをここでも使⽤して、どの⾯がどのGPUに対してSendTextureとなるかを指定します。 送信側GPUではSendTexture 受信側GPUではReceiveTextureと、保持している形態は異なりますが ここも上位レイヤーからは、抽象化された1つのTextureとして扱わせます。 また、SendTextureに対して、レンダリング結果から CopyTexture を⾏うと 共有のための転送がなされます。 65

67.

実現に向けたレンダリングの実装 ②GPU同期した転送を実現する GPU0 実際の転送まで Shared Heapsの特徴 • 直接RT Texture等としては扱えない • 専⽤のCopyQueueだけで完結 専⽤コマンドで転送実⾏ 1. 各⾯ごとにGPUの送受信をセットで実⾏ Render Draw ExecMask : 0x1 = b0001 GPU Command … RT Texture Draw Complete Face N Copy MemoryTransfer() MultiTexture Face N SendTexture GPU Command … 2. RT TextureをSendTextureにコピー 3. その後ReceiveTextureからキューブマップにコピー Send/Receive Copy Queue GPU1 4. コピー後にレンダリングにて使⽤可能 ⇒ キューブマップ1⾯の共有が実現 ReceiveTexture Copy Texture 66 66 Shared Heapsは他のGPUとの共有⽤途のみに制限されております。 レンダリング先のRender Target Textureとしても使⽤できませんし、Copy以外の操作やサンプリングもできません。 レンダリング結果をCopyで受け取って送信するか、または受信した結果を別のTextureにCopyするのみです。 中間コマンドも含めた流れを整理しますと、キューブマップの1⾯へのレンダリングまで終えた後、 最後に送信と受信両⽅を意味するメモリ転送のコマンドを実⾏させます。 それで送信側はレンダリングの結果をSendTextureにコピーし、受信側はReceiveTextureから通常Textureに受信した結果をコピーさせることになります。 これで各GPUに同じキューブマップの1⾯が共有されます。 66

68.

実現に向けたレンダリングの実装 ②GPU同期した転送を実現する 送受信の実装が完成 • レンダリングを⾏った⾯はSendTextureで送信 • レンダリングしていない⾯はReceiveTextureで受信 • 各GPU内で6⾯結合し共有キューブマップが完成 GPU毎の⾯の割り振り All GPU Shared 4K Cube Map!! GPU SendTexture ReceiveTexture ReceiveTexture SendTexture SendTexture ReceiveTexture GPU0 GPU1 GPU2 GPU3 67 67 これで送受信が実装できました。 各GPU内でレンダリングを⾏った⾯はSendTextureで送信する。 レンダリングしていない⾯はReceiveTextureで受信する。 6⾯分⾏い結合することで4Kのリアルタイムのキューブマップが各GPU内で共有されました。 67

69.

実現に向けたレンダリングの実装 ②GPU同期した転送を実現する しかし、キューブマップ間のフレームのズレが⽣じる キューブマップの⾯で使われるフレームが異なる 68 68 しかし単純にはいかずズレが発⽣しました。 図の通りキューブマップの境界に対してのずれですが、お分かり頂けますでしょうか。 68

70.

実現に向けたレンダリングの実装 ②GPU同期した転送を実現する 各GPUだけのタイミングで送受信するとずれてしまう ⇒ 描画処理のタイミングがバラバラで 送受信のタイミングがズレるため SendTextureが送信する前に ReceiveTextureが受け取り処理をしてしまう ⇒ ⾯ごとにフレームがバラバラとなる GPU0 GPU1 GPU Execute GPU Execute Not Yet… MemoryTransfer() Receive Draw Complete Face N Rendering MemoryTransfer() Send 送信まで待たせるとGPUの待ち時間が問題に Already… Wait Begin Send︖ MemoryTransfer() Send NG MemoryTransfer() Receive 69 69 原因はGPUごとの実⾏のズレで、送受信のタイミングもズレてしまったためであります。 1つのGPU中で送信する前に 別のGPUが受け取り処理をしてしまうと ⾯ごとにフレームがバラバラとなるために問題は発⽣します。 仮にReceiveTextureを、SendTextureの送信まで待たせることにすると GPUの待ち時間が多くなりその場合も問題となります。 69

71.

実現に向けたレンダリングの実装 ②GPU同期した転送を実現する 受信を1フレーム遅らせて 確実に送信完了したデータを使う ダブルバッファに考え⽅を変える 共有テクスチャを2つ持たせ、受信を遅らせることで安定化 • 今回のフレームのレンダリング結果は送受信のみ、フレームごとに格納先を⼊れ替え • 次のフレームで⼊れ替わった前回のものを、キューブマップとして使いディスプレイ出⼒ SendTexture GPU Frame N RT Texture Frame N Frame N+1 RT Texture Frame N+1 ReceiveTexture GPU Frame N Frame N+1 Double Buffer BufferB Frame N-1 BufferA Frame N Double Buffer BufferA Frame N CubeMap Texture Frame N Display Frame N Send&Receive BufferB Frame N-1 BufferA Frame N Double Buffer Display Frame N-1 Swap BufferB Frame N+1 Double Buffer CubeMap Texture Frame N-1 CubeMap Texture Frame N-1 Display Frame N-1 Swap BufferB Frame N+1 BufferA Frame N CubeMap Texture Frame N Display Frame N 70 70 そこで、正攻法での同期待ちから考え⽅を変え、 共有テクスチャはダブルバッファとすることにしました。 SendTextureもReceiveTextureも、内部的には2つ持たせます。 送信タイミングは今まで通りですが、受信タイミングはフレームの最後にします。 そして両テクスチャともに毎フレーム、送受信⽤とディスプレイ出⼒⽤を⼊れ替えをさせることで 確実に送受信が完了したキューブマップの⾯をディスプレイ出⼒に使⽤できます。 これであればGPUがバラバラに動作した送信であっても 受け取りを遅らせることで安定化させることができます。 70

72.

実現に向けたレンダリングの実装 ②GPU同期した転送を実現する 1フレームレンダリングが遅延する しかし確実に送信が終わった次のフレームで受信するため安定する 実装も仮想テクスチャ内で完結させている Output Frame N-1 MultiTexture Face0 Double Buffer MultiTexture Face1 Double Buffer MultiTexture Face2 Double Buffer ⇒ 注意点も増えるが、キューブマップのズレの問題は解決 71 71 ただし、これは必ず1フレームの遅延が発⽣する⼿法となります。 あるフレームでレンダリングしたキューブマップが、実際にディスプレイに表⽰されるのは次のフレームとなるということです。 しかし待ち時間などの余計なGPU待ちも⽣じず、確実に安定する⽅法です。 実装⾃体も仮想テクスチャやデバイス内の下位レイヤーのみで完結しております。 サウンドなどのタイミングには注意が必要となりますが GPUを含めて全体の処理時間が削減できる妥当な⼿段であり、これでズレの問題は解決となりました。 71

73.

実現に向けたレンダリングの実装 ②GPU同期した転送を実現する デバッグが⾮常に困難 ⇒ PIX on Windowsによるフレームキャプチャーも使⽤できない NVIDIA Nsight Systemsが唯⼀複数GPUでの確認⼿段 ⇒ 確認したことで新たな問題 ・転送時のGPU負荷がかかっている ・Shared Heapsの並列化対応の必要性 ⇒ さらに⾒つかった問題への対処へ 72 72 このズレの問題は発覚してから解決するまで難航しました。 GPUの数やAPIが特殊であるからか、PIXによるフレームキャプチャーも正しく動作しません。 つまりデバッグを⾏うことすら困難な問題です。 しかしNsight Systemsが唯⼀、複数GPUにまたがって稼働の内訳を時間軸で確認することができ それによって、原因を特定できたことで解決へとつながりました。 それと同時に、転送時のGPU負荷がかかっていること、 Shared Heaps処理の並列化対応の必要性が明らかになりました。 72

74.

実現に向けたレンダリングの実装 ②GPU同期した転送を実現する GPUの転送待ちがフレーム遅延の要因に ⇒ 32Bitフォーマットの4Kを転送することは重たい PCIeでの転送にて 10.8ms も待たされる 73 73 ⾒つかった問題の1つとして 4Kの32Bitフォーマットを転送することはPCI Expressへの負荷となるということです。 10.8msと⼤きなネックとなっていることが挙げられます。 73

75.

実現に向けたレンダリングの実装 ②GPU同期した転送を実現する 転送量と負荷の整理 GPU0 • 各GPUは6⾯分の送受信 • ⼀⾯あたり 4096 × 4096 × 4Byte = 64MiB ⇒ 64MiB × 6⾯ ≒ 384MiB/frame の送受信量︕ Send x1 Face Receive x5 Faces GPU1 • GPUに対してのPCIeは4.0 の 双⽅向64GiB/s Send x2 Faces Receive x4 Faces • しかし理論値とはならず10msの待ちに ⇒ このままではリアルタイムとして成り⽴たない 64MiB 64 × 6 = 384MiB! 74 74 各GPU6⾯分の送受信を⾏います。 1⾯あたり64MiBとなるため、毎フレーム384MiBもの送受信となります︕ PCI Expressは4.0、スペック的には間に合いそうにも思えます。 しかし実際には理論性能通りにはならず 何らかのオーバーヘッドが発⽣したことによって10ms程度は待ちとなっていました。 このままではリアルタイムとして成り⽴ちません。 74

76.

実現に向けたレンダリングの実装 ②GPU同期した転送を実現する YUV[出典4] を⽤いて2 x 2のブロックで圧縮 YUV422 YUV420 • リアルタイムで変換可能 • 結果半分の16Bit相当に • フォーマットはICtCp(⾼輝度も扱える) ⇒ 画質は低下するが 転送にかかるコストを⼤幅に削減できると判断 75 75 そこでYUVにて圧縮することとします。 ピクセルをブロックに分割して、輝度はピクセルごとに残しますが、⾊成分を削減する⼿法です。 BC圧縮などとは異なり、リアルタイムでエンコードとデコードが可能であり GPU処理としても軽量で削減効果が⾼いものです。 ⾼輝度成分も使いたかったため最終的なフォーマットはICtCpとしましたが、 結果として半分の16Bit相当まで下げることができました。 ⾊成分が少なくなるため画質は低下しますが、 それでも転送にかかるコストを⼤幅に削減できるとの判断のもと導⼊を致しました。 75

77.

実現に向けたレンダリングの実装 ②GPU同期した転送を実現する 半分の5msに削減成功 ⇒ 変換の負荷も低い 圧縮後は 10.8ms > 5.14ms に 圧縮後 圧縮前 転送時間 5.14ms 10.8ms bpp 16Bit 32Bit 転送量 192MiB/frame 384MiB/frame 76 76 結果10msかかっていた負荷を、予想値と同等の半分の5msまで削減できました。 RGBからYUVへのエンコード、またその逆のデコード それらも⼤した負荷とならず、直結した削減効果を得ることができました。 76

78.

実現に向けたレンダリングの実装 ②GPU同期した転送を実現する Shared Heapsの並列化対応 ⇒ レンダリング処理の裏で送受信し、PCIeでの転送待ちを⼤きく削減 受け取りの転送が 他GPU処理中にも動作する レンダリングのためのGPU処理 77 77 そしてさらにShared Heapsの転送をレンダリングの裏で⾏うようにしました。 これにより、PCI Express転送による待ち時間の隠ぺいができ、 全体の処理時間の⼤幅な削減が達成できました。 そしてリアルタイムでの4Kキューブマップレンダリングが現実的になりました。 77

79.

実現に向けたレンダリングの実装 ②GPU同期した転送を実現する GPU同期の実現までのまとめ • Shared Heapsでの送受信テクスチャを作成 • レンダリング後のキューブマップをコピーで送受信 • ダブルバッファにて送受信の安定化 • テクスチャの圧縮と並列化で転送効率の改善 4つのGPUを使⽤したリアルタイム + マルチレンダリングまでは完成 78 78 GPU同期のまとめです。 タイミングや転送コストなどの問題も⽣じましたが Shared Heapsを使⽤したうえで、各対処を⾏うことで形にすることができました。 これで4つのGPUを使⽤したリアルタイムでのマルチレンダリングまでは実装できたと⾔えます。 78

80.

実現に向けたレンダリングの実装 設計の基盤から具体的な課題へ ①GPUの役割分担をどうするか 分担をどのように⾏わせるのか ⇒ ここが基点 ②GPU同期した転送を実現する 実際にキューブマップを同期させる ⇒ ⼀番コアとなる難しい実装 ③マルチディスプレイへの出⼒ 仕上げとした出⼒ ⇒ ここまで解決するとシステムが形になったことが⾒える 79 79 最後は同期されたキューブマップを各ディスプレイに切り出すのみです。 79

81.

実現に向けたレンダリングの実装 ③マルチディスプレイへの出⼒ マルチディスプレイへの出⼒⽅法 • マルチディスプレイに対しての出⼒はExecMaskにて振り分け可能 GPU Command … GPU0 Draw CubeMap to Display ExecMask : 0x1 = b0001 Draw CubeMap to Display ExecMask : 0x4 = b0100 GPU2 GPU Command … • ディスプレイへの描画は単純にViewPort切り抜き︖ ⇒ 円柱形状に合わせた別の⽅法 NG 80 80 マルチディスプレイに対しての出⼒は「GPUの役割分担」にて説明したように ExecMaskを⽤いることでどのGPUが⾏うかを振り分け可能です。 そのうえで単純にViewPortとして切り抜くだけで良いのでしょうか︖ そうではありません。 80

82.

実現に向けたレンダリングの実装 ③マルチディスプレイへの出⼒ 投影として出⼒する必要がある • 円柱のどのディスプレイに対してかを指定 • 投影先を計算してキューブマップからのサンプルを⾏う Projection CubeMap Sample Display Output 投影のイメージ 81 81 円柱に対しては単純な切り抜きではありません。 プロジェクションのように投影して出⼒する必要があります。 具体的にお話します。 まずは仮想的に設定した視点の⾼さを基準に 円柱上の物理的なディスプレイやプロジェクターの投影位置を求めます。 そして、その投影位置に対応するキューブマップのサンプル⽅向を計算します。 そうしてキューブマップからサンプルした結果をRender Target Textureに描きだし それをディスプレイに出⼒させます。 81

83.

実現に向けたレンダリングの実装 ③マルチディスプレイへの出⼒ トーンマップも組み込む • キューブマップはリニアな輝度であるため • OCIOも使⽤している Projection CubeMap Sample Tonemap トーンマップ前 トーンマップ後 Display Output 82 82 またキューブマップの時点ではライティング直後の輝度そのものです。 トーンマップも必要になります。 そのため出⼒時にOCIOを使⽤したトーンマップも組み込んでいます。 82

84.

12枚ディスプレイへの出⼒ 83 83 ここまでの実装の結果をご覧ください。 12枚のディスプレイに対してリアルタイムの4Kキューブマップから投影出⼒されていることが確認できます。 ※ 映像についてはDocswell「スライド概要」へ記載のYouTube講演映像からご確認ください。 83

85.

実現に向けたレンダリングの実装 ディスプレイの出⼒のまとめ • ExecMaskで出⼒するGPUを決定 • 円柱上への投影出⼒ • 出⼒時にトーンマップ ⇒ マルチGPUを⽤いたマルチディスプレイへのレンダリングは完成 しかし主要な機能1つだけでは実現には⾜りない ⇒ エンジン側だけでなく タイトル側も並⾏して開発を進めることで発⽣する別の問題もあった 84 84 ディスプレイ出⼒の処理のまとめです。 ExecMaskで出⼒するGPUを決定し 円柱上への投影出⼒ そして出⼒時のトーンマップ これでようやく、マルチGPUを⽤いたマルチディスプレイに対してのレンダリング、その機能は実装できました。 しかし機能1つだけでは実現には⾜りません。 エンジン側だけではなく、タイトル側も⼀緒に開発しているからこそ出てくる、別の問題も発⽣します。 84

86.

85 85 今度はタイトル側、開発環境などを含めてお話していきます。 85

87.

開発が進むと⾒えてくる問題 模擬会場について • エンジン側の実装に先⾏して RE ENGINEのエディター上で作成された • 既存のRE ENGINEの機能で作成 • 模擬会場内で実コンテンツの制作が進められた ⇒ ここまでは想定通り 86 86 エンジンチームでのマルチレンダリングが⽤意できるまでの間、 タイトルチームは既存のRE ENGINEの機能を使⽤して 1台のPCでも確認できる、模擬会場を作成しました。 そのうえで実コンテンツの制作も並⾏して進められておりました。 86

88.

模擬会場 87 87 この段階になりますとシアターの構造も決まっており、コンテンツの開発も進められています。 しかし、いくつかの問題も⾒えてきます。 何かの境界に対して、切れ⽬が⽣じていたり、ねじれや不⼀致が⽣じていることが分かりますでしょうか。 ※ 映像についてはDocswell「スライド概要」へ記載のYouTube講演映像からご確認ください。 87

89.

開発が進むと⾒えてくる問題 通常のゲーム前提では想定しない問題が発⽣ ① ビルボードがつながらない ② GUIが意図しない⾒た⽬になる ③ ポストプロセスに切れ⽬が発⽣ ⇒ キューブマップをそのまま出⼒に使⽤しているための問題 88 88 輝度のままであるキューブマップを、そのまま出⼒に使⽤しているため 通常のゲームでは想定していない様々な問題が発⽣します。 ビルボード、GUI、ポストプロセスに対して問題が発⽣しました。 それぞれ具体的に⾒ていきます。 88

90.

開発が進むと⾒えてくる問題 ①ビルボードがつながらない キューブマップの境界で、ビルボードに折れやズレが発⽣ 折れやズレが発⽣ 89 89 ⼤きい問題としてVFXなどで使⽤されているビルボードが挙げられました。 画⾯中央がキューブマップごとの⾯同⼠の接合部分です。 折り⽬のようになっていることが分かりますでしょうか︖ 89

91.

開発が進むと⾒えてくる問題 ①ビルボードがつながらない キューブマップに対するビルボードの問題整理 • キューブマップは、⾯ごとにカメラの向きを90°ずつ合わせてレンダリング • ビルボードはカメラ⾯に正対させてメッシュ構築 • キューブマップ⾯の境⽬、つまり異なるカメラ間で折れやズレにつながる • Z⽅向の回転や前後関係の順番も問題につながる ビルボードは各カメラに正対 カメラ毎に ビルボードの⾓度も変わる 回転の値が同じでも ズレや折れにつながる 90 90 キューブマップは6⾯それぞれに対して正対した、画⾓90°のカメラでレンダリングします。 ビルボードは通常それらのカメラに正対してメッシュを構築します。 そうすると各⾯の画⾯端を跨ぐビルボードは、 各⾯ごとに向きが変わってしまい、⾯を跨いでズレたり折れ曲がったような⾒た⽬になります。 90

92.

開発が進むと⾒えてくる問題 ①ビルボードがつながらない ビルボード問題の解決⼿段 • カメラの⾯ではなく、カメラの位置に対して正対させた • 描画順のソートをスクリーン深度ではなく、キューブマップ中⼼との距離に カメラの⾯に正対 カメラの位置に正対 つなぎ⽬でも違和感がない 91 91 そこでカメラの⾯ではなく、カメラの位置に対して正対させ、 描画順もスクリーン深度ではなく、キューブマップ中⼼との距離にてソートさせるように変更しました。 これでキューブマップのつなぎ⽬でも違和感なく接合されるビルボードとなります。 91

93.

開発が進むと⾒えてくる問題 ②GUIが意図しない⾒た⽬になる ロゴ表⽰に対してのGUI問題 • 通常はカメラに紐づいたGUI描画で問題ない • GUI描画先がキューブマップであるためゆがみが発⽣ • さらにリニア輝度であるため意図しない⾊味や混ざりが⽣じる 意図しない⾊とゆがみ リニア輝度のキューブマップに描画されるため 92 92 次にGUIの問題となります。 体験内でロゴを表⽰したいという話が出ました。 しかしレンダリングターゲットが輝度そのままであるキューブマップです。 通常のGUI描画を⾏うと、⽩⾶びなどしたり、円柱への投影によってゆがみが⽣じてしまう結果になります。 92

94.

開発が進むと⾒えてくる問題 ②GUIが意図しない⾒た⽬になる GUI問題の解決⼿段 • GUI⽤のテクスチャに描画を⾏う • 出⼒時のトーンマップ後、円柱への投影として合成 Projection CubeMap Sample Tonemap GUI 最終的な体験中の表⽰ Display Output 93 93 そのためGUI⽤のテクスチャに描画を⾏ったものをディスプレイ出⼒時のトーンマップ後に合成させる、 専⽤処理を追加することで対応致しました。 93

95.

開発が進むと⾒えてくる問題 ③ポストプロセスに切れ⽬が発⽣ ポストプロセス処理問題 • UVをずらしてサンプルするようなものは控えて頂く • ブルームのみ対応することに ⾯ごとのポストプロセスは 他の⾯を考慮しないため つなぎ⽬がおかしくなる NG 太陽のブルームがキューブの端で崩れる 各⾯にぼかしを加えた、キューブマップの例 94 94 ポストプロセス処理も問題となります。 UVをずらす処理は控えて頂きましたが、全般的な汎⽤性を考慮してブルームのみ対応することにしました。 左側が実際に問題が⽣じた時のものですが キューブマップのつなぎ⽬に、太陽のブルームが崩れることが確認できるかと思います。 これはキューブマップの各⾯単位でブルームがなされるから⽣じるものです。 右側の例のようにキューブマップを⾯ごとにぼかしてみると確認できます。 94

96.

開発が進むと⾒えてくる問題 ③ポストプロセスに切れ⽬が発⽣ ブルームの解決⼿段 • キューブマップ上で周辺⽅向複数にサンプルしつつ、ダウンサンプル • ダウンサンプル後のキューブマップ複数枚をマージさせる(KawaseBloom[出典5]と近い) ピクセル⽅向 + ⾓度を変えた周辺⽅向で 重みを含めてサンプル それをダウンサンプルしつつ結合 周辺サンプルとダウンサンプルのイメージ 結合後 95 95 対応の詳細となります。 仕組みとしては KawaseBloom等と考え⽅は近く、よくある軽量な⽅式です。 周辺のピクセルをサンプルしつつ、キューブマップをダウンサンプルしていきます。 最後にそれらを結合することでブルームとするものです。 これであれば、⾯を跨いだピクセルもサンプルされるため切れ⽬は⽣じません。 95

97.

開発が進むと⾒えてくる問題 ③ポストプロセスに切れ⽬が発⽣ その他ポストプロセスに関連する話 • SSAOはそのまま使⽤ ⇒ ⾒た⽬ではキューブマップ境界の違和感は出ていないため • VFXでもブラーやDistortionなど、画⾯をゆがめる処理は使⽤しない すべてを完璧に技術的に対応するわけではなく コストやリスクも考慮して、制約や落としどころを正しく選択する ゲーム開発者としても重要な考え⽅ 96 96 余談ではありますが、実はキューブマップへのレンダリングでもSSAOなどは使⽤されております。 ただ、⾒た⽬ではキューブマップ境界の違和感は出ていないためそのままとしています。 またVFXでも⼀部処理は使⽤しないなどの⽅針を決めております。 すべてを技術で対応するわけではなく、コストやリスクも考えて、制約や落としどころを正しく選択する。 それはゲーム開発者としても重要な考え⽅であると思っております。 96

98.

開発が進むと⾒えてくる問題 これでレンダリング機能の実装はすべて完了︖ ⇒ そうではありません。 97 97 さて、これで実装がすべて完了しました。 本当にそう⾔えるのでしょうか︖ 97

99.

98 98 「ミライのエンターテインメント」としての未踏の試みは 未踏ならではの不具合を引き起こします。 ここまではカプコン社内、開発PC内のみの話でありました。 ここからはXD HALLが竣⼯し、理論上だけではなく現実空間で発⽣した問題の話となります。 98

100.

現地で出てきた問題 現地で未踏ならではの不具合が確認される ⇒ 主に想定外のディスプレイ出⼒の問題によるもの ① 切り出しが合わない ② シースルーであるため側⾯から天井が透ける ③ カラーシフト問題 ④ 同期が合わない 99 99 模擬ではない現地夢洲に、シアターが出来上がり確認が始まりました。 そうすると、切り出しの問題や天井が透ける問題、カラーシフトや同期等、 ディスプレイに関わる想定外の問題が発覚してきました。 99

101.

現地で出てきた問題 ①切り出しが合わない ディスプレイへの切り出し設定が想定と合致しない • 現地でなければ確認できない • 移動に⽚道1時間はかかる • ネットワークでのやり取りにも限界がある 切り出しが合わず、天井と壁⾯がズレてしまう 100 100 ⼀つはディスプレイへの切り出し設定が、想定と合致しない問題です。 事前に細かくすり合わせをしても、⼤規模になると起こるべくして発⽣します。 調整が必要になります。 しかし修正したのでパッケージを確認してください、という通常の開発フローでは問題があります。 現地にもっていかなければ確認できないということになりますが、 その移動に⽚道1時間はかかります。 そしてネットワークのやり取りでも解決しきれません。 100

102.

現地で出てきた問題 ①切り出しが合わない 現地での調整への対策 1.パッケージだけでなく 協⼒会社様向けのRE ENGINEをSSDに⼊れて持ち込み 2.起動時に調整設定ファイルを読み込む機能を追加 ⇒ XD HALL内での調整が可能に 3.ディスプレイチェックのデバッグ機能を多数⽤意 • キューブマップのつながり • ディスプレイの発⾊チェック • 同期のためのスキャンライン ⇒ 現地にて調整できる⼟台が整った 101 101 まずはライセンスなどの問題もあるため、協⼒会社様向けのRE ENGINEをSSDに⼊れ それをポータブルREとして持ち込むようにしました。 そして実装として、起動時に調整が反映されるように設定ファイルを⽤意致しました。 これによって調整後の状態を即時パッケージ反映させることも可能になります。 さらにディスプレイチェック⽤のデバッグ機能を多数⽤意致しました。 何があるかもわからないため、思いつく限り実装した記憶があります。 これで調整できる⼟台は整いました。 101

103.

XD HALLでのデバッグ 102 102 こちらが360°シアター内でのデバッグの様⼦です。 機材というよりも、もはや建築物であり、最終的な⾒え⽅は現地でしか確認できません。 実際、私は数回しか⾜を運べておりませんが、現地だからこそ得られた情報や考えもあります。 このプロジェクトだからこそ得られた経験です。 ※ 映像についてはDocswell「スライド概要」へ記載のYouTube講演映像からご確認ください。 102

104.

現地で出てきた問題 ②シースルーであるため側⾯から天井が透ける シースルーLEDは壁⾯が透過する • 天井LEDの円の外の領域が、壁⾯から⾒えてしまう • そのため円状にくりぬいて⿊塗りする処理を、天井のディスプレイ出⼒に追加 LEDから天井が透ける 透過して天井が⾒えるイメージ 出⼒時に塗りつぶし ⇒ 透過して⾒えていた天井部分が⽬⽴たなくなった 103 103 さて、イマーシブサウンドシステムを活⽤するために、壁⾯と天井にはシースルーLEDが採⽤されています。 シースルーLEDで⾯は遮蔽されていません。 したがって、壁⾯を通して天井のLEDが⾒えるもので、そこから円の外の領域も⾒えてしまいました。 そのため、天井は円状にくりぬいて⿊塗りする処理をディスプレイ出⼒に追加しております。 103

105.

現地で出てきた問題 ③カラーシフト問題 天井の前⽅は⻘い カラーシフト問題が発⽣ • 同じ⾊で出⼒しても場所ごとに 天井や壁の⾊が変化する • 通常のゲーム開発では全く 想定されていない聞いたことも無い問題 原因は完全に解明できていない 天井の後⽅は⾚い 壁⾯も⾓度で若⼲変化する ⽩でも前後で⾊が異なるパノラマ写真 ⇒ おそらくLED同⼠の発光の⼲渉と LEDと⽬の⾓度によって⽣じるものと推測 ⇒ ⽴ち位置によっても⾒え⽅が変化する 完全な解決は不可能 素⼦のずれや⼲渉は推測 104 104 そして同じ⾊でLEDに出⼒しても、天井や壁の⾊が変化してしまうカラーシフトが⼤きい問題となりました。 通常のゲーム開発では全く想定されていない、聞いたことも無い問題です。 LEDの⼲渉や素⼦のずれなどいくつかの推測は⽴てられましたが、原因は解明できておりません。 また、完全解決は不可能と⾒られます。 104

106.

現地で出てきた問題 ③カラーシフト問題 カラーシフト問題の解決策 • 壁や天井に対してある程度の傾向が⾒られる • 技術的な解決から考えを切り替える • 補正⾊を天井の⽅向や壁の上下に対してかけられるように追加 • 現地にて⽬で⾒て⽬⽴たないように調整 調整中 調整後は⽬⽴たなく ⇒ ⽬⽴たないレベルまで抑えることができた 105 105 しかしながら、壁や天井に対してある程度の傾向が⾒られました。 そのため技術的な解決から考えを切り替えました。 天井の⽅向や壁の上下に対して補正⾊をかけられるように追加し それを現地にて、⽬⽴たないように調整を頂くことで解決としました。 105

107.

現地で出てきた問題 ④同期が合わない LED出⼒の同期がまれにズレる問題 • GPU間やキューブマップ同期のズレではない • Quadro Sync IIを使⽤しているが発⽣ LED A LED B LEDの境⽬が、同期ズレによって⽬⽴つ 106 106 そして最後まで最も問題となったのは ディスプレイ出⼒の同期がまれにズレることがあるということでした。 GPU間のキューブマップ同期のズレではなく、出⼒先ディスプレイ同⼠の同期ズレです。 Quadro Sync IIを使⽤しているにも関わらず発⽣します。 106

108.

現地で出てきた問題 ④同期が合わない 出⼒ズレに対しての考慮や検証 • NVIDIAのMosaic構成 ⇒ 機材構成的にも使⽤できなかったため未検証 • 単純な同期チェックアプリではズレは⽣じない • 最終盤で発覚した問題であり期⽇も迫る • プログラムのみでは解決⼿段もなく対応不可 • 最後の候補としてNVIDIA社にご協⼒を仰ぎ、NvAPIのPresentBarrier[出典6]を検証 ⇒ 本件の要件とは適合しないことが確認された ⇒ 判断を切り替える必要がある 107 107 この問題の対応策はNVIDIAのMosaic構成が考えられますが モンスターPC構成時に問題があったため使⽤されなかった経緯があります。 そこで、NVIDIA社とも相談させて頂きながらNvAPIのPresentBarrierも検証致しました。 しかし期待するように同期がなされず、こちらも断念せざるを得ませんでした。 単純なディスプレイ同期チェックアプリであればズレは⽣じません。 しかしプログラムのみでは解決⼿段もなく対応不可とも⾒れました。 そして最終盤で発覚した問題であり、期⽇も迫っています。 ここでも判断を切り替える必要がありました。 107

109.

現地で出てきた問題 ④同期が合わない 天井と壁⾯ならズレは気にならない そのため同じGPUに担当させたほうが良い 出⼒ズレ解決のための施策 • 1つのGPUの出⼒のグループであれば ズレが発⽣しないことを確認 • 壁⾯や天井⾯同⼠でズレなければ違和感もない • そこが解決すれば問題ないと判断を切り替え • ディスプレイ出⼒の GPU分散の設定を切り替えることで回避 正しい解決への推測 • Quadro Sync IIとHouse Sync Generatorでの Genlock構成が必要であった︖ GPU0 Wall1 Floor1 Ceiling1 GPU1 Wall2 Floor2 Floor3 GPU2 Wall3 Floor4 Floor5 GPU3 Wall4 Floor6 Ceiling2 GPU0 Floor1 Floor2 Floor3 GPU1 Ceiling1 Ceiling2 GPU2 Floor4 Floor5 Floor6 GPU3 Wall1 Wall2 Wall3 Wall4 • ディスプレイとも直接同期をするようにすることで対応できた︖ • 新規機材も⽤意できるタイミングではなかったため未検証 1つのGPUグループとして 壁⾯全てを設定してズレを防⽌ 108 108 1つのGPUからの出⼒のグループであればズレが発⽣しないことは確認できていました。 そのため壁⾯や天井⾯同⼠でズレが無ければ違和感もない、そこだけが解決できていれば問題ないと、判断を切り替えました。 そして、GPU分散のディスプレイ出⼒先設定を切り替えることで回避としました。 もしかしますとQuadro Sync IIに対してHouse Sync Generatorを導⼊すると改善できた可能性はあります。 しかし、すでに新規機材も⽤意できるタイミングではなかったため、こちらも検証することはできておりません。 個⼈的にもこの問題に関して解法がお分かりの⽅がおりましたら、是⾮ともご解説を頂けますと幸いと思っております。 108

110.

現地で出てきた問題 現地問題のまとめ • 現地で⾒つかった問題に対して対応が出来なかったものは反省点 ⇒ しかし着地点としての機能を提供できた • 技術的に挑戦はするが、それ以外の⾯で解決を進めることも重要 • 最終的な調整を頂いたタイトルの⽅々 ご相談に応じて頂けたNVIDIA Corporation様に感謝 109 109 現地で⾒つかった問題に対して正確に対応が出来なかったものは多々あり反省点としたいですが、 何とか着地点としての機能を提供できたことは安⼼しました。 技術的には挑戦はすることは前提としても、問題に対して、それ以外の⾯から⾒て解決を進める。 改めてそれもエンジニアとして重要であることを実感できました。 また実際に現地で最終的な調整を頂いたタイトルの⽅々。 相談に応じて頂いたNVIDIA社にもここで改めて感謝を述べたいと思います。 109

111.

110 110 最後にまとめとなります。 110

112.

まとめ • 通常のゲームの前提が通じないタイトルだが、仕組みを完成させることができた ⇒ マルチGPU +マルチディスプレイ のレンダリングの実装と それを前提とした環境も設計も重要であった • 想定していない問題も多々⽣じるが、多⾓的な視点で解決を考えることは重要 • 改善可能な余地はあるため、機会があればさらに良くしたい • マルチGPUレンダリング、もしくはマルチディスプレイレンダリング 別の視点や構想で、あるいは未来で応⽤できれば望ましい • 過去事例も、実践する機会も少ない事例ですが このような取り組みに挑戦される際のご参考になれば幸いです。 111 111 未踏の構成であり、通常の前提が通じないものではありましたが何とか達成することができました。 やはり技術も⼤切ですが、それ以外の視点も持つことは重要であると感じています。 またこれはあくまで私個⼈の考えですが、 今回の技術は他の分野にも応⽤できる可能性があると感じています。 そのため、本件のみにとどまらず、今後の取り組みにつながっていけば嬉しいと思っていますし 過去事例も、実践する機会も少ない事例ですが、このような取り組みに挑戦される際のご参考になれば幸いです。 111

113.

参考 参考出典 1 / 2 1. GPU駆動レンダリングへの取り組み https://www.docswell.com/s/CAPCOM_RandD/Z2GP4Z-2022-07-15-121419 2. Multi-adapter systems – Win32 apps https://learn.microsoft.com/en-us/windows/win32/direct3d12/multi-engine 3. Shared Heaps – Win32 apps https://learn.microsoft.com/en-us/windows/win32/direct3d12/shared-heaps 112 112 こちら出典元となります。 112

114.

参考 参考出典 2 / 2 4. ITU-R BT.2100 https://www.itu.int/rec/R-REC-BT.2100 5. Masaki Kawase GDC2003 http://www.daionet.gr.jp/~masa/archives/GDC2003_DSTEAL.ppt 6. Synchronizing Present Calls Between Applications on Distributed Systems with DirectX 12 https://developer.nvidia.com/blog/synchronizing-present-calls-between-applications-on-distributedsystems-with-directx-12/ 113 113 では、本講演は以上となります。ご清聴ありがとうございました。 113

115.

付録 Shared Heapsの実装 // 送信側の作成実装 // D3D12_HEAP_FLAG_SHARED | D3D12_HEAP_FLAG_SHARED_CROSS_ADAPTER をともに指定する // Shared Heaps として Heap作成 CD3DX12_HEAP_DESC heapDesc( total_bytes, D3D12_HEAP_TYPE_DEFAULT, 0, D3D12_HEAP_FLAG_SHARED | D3D12_HEAP_FLAG_SHARED_CROSS_ADAPTER); ComPtr<ID3D12Heap>crossAdapter; device->CreateHeap(&heapDesc, IID_PPV_ARGS(&crossAdapter)); // Shared Heaps として Fence作成 ComPtr<ID3D12Fence>fence; device->CreateFence( 0, D3D12_FENCE_FLAG_SHARED | D3D12_FENCE_FLAG_SHARED_CROSS_ADAPTER, IID_PPV_ARGS(&fence)); 114 114 114

116.
[beta]
付録

Shared Heapsの実装

// Heap内に1つだけコピー受け取り⽤のTextureを作成する。これは操作もサンプリングもできない
// 送信元であるので混乱するが
// コピー先としてCopyTexture() を⾏うことで送信処理が⾏われる
auto crossAdapterDesc = CD3DX12_RESOURCE_DESC::Buffer(total_bytes,
D3D12_RESOURCE_FLAG_ALLOW_CROSS_ADAPTER);
ComPtr<ID3D12Resource>sendTexture;
device->CreatePlacedResource(
crossAdapter.Get(), 0, &crossAdapterDesc,
D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&sendTexture));

115
115

115

117.

付録 Shared Heapsの実装 // 送信側からHandleを作成 HANDLE heapHandle = nullptr; device->CreateSharedHandle( crossAdapter.Get(), nullptr, GENERIC_ALL, nullptr, &heapHandle); HANDLE fenceHandle = nullptr; device->CreateSharedHandle( fence.Get(), nullptr, GENERIC_ALL, nullptr, &fenceHandle); // 受信側は heapHandle と fenceHandle から OpenSharedHandle()を使⽤してHeap と Fence を⽣成 ComPtr<ID3D12Heap>crossAdapter; device->OpenSharedHandle(heapHandle, IID_PPV_ARGS(&crossAdapter)); ComPtr<ID3D12Fence>crossFence; device->OpenSharedHandle(fenceHandle, IID_PPV_ARGS(&crossFence)); 116 116 116

118.
[beta]
付録

Shared Heapsの実装

// Heap内に1つだけコピー元としてTextureを作成する
// 受信先ではあるが
// 実際にレンダリングで使⽤するときはCopyTexture()にて別のTextureに取り出すため
auto crossAdapterDesc = CD3DX12_RESOURCE_DESC::Buffer(total_bytes,
D3D12_RESOURCE_FLAG_ALLOW_CROSS_ADAPTER);
ComPtr<ID3D12Resource>receiveTexture;
device->CreatePlacedResource(
crossAdapter.Get(), 0, &crossAdapterDesc,
D3D12_RESOURCE_STATE_COPY_SOURCE, nullptr, IID_PPV_ARGS(&receiveTexture));

117
117

117