2015年10月30日

2000 ギガピクセルのテクスチャの処理

作成 Aljosha Demeulemeester

初めまして Aljosha Demeulemeester と申します。ベルギーの都市ヘントを拠点とするミドルウェア企業である Graphine の CEO であり、共同設立者でもあります。Graphine では、ビデオ ゲームと 3D ビジュアライゼーションの業界向けにビジュアル テクスチャ ストリーミングとテクスチャ圧縮技術を開発しています。 

過去 7 年間、我々は「ビデオ ゲームで膨大な量のテクスチャ データを使用するための技術的限界をどうやったら取り除くことができるか」というひとつの問題に対処することに専念してきました。当然、その目的は固有のディテールで仮想世界を満たした非常に鮮明なグラフィックスを実現することです。必ずしもすべてのゲームでこれが必要になるわけではありませんし、テクスチャを追加すればビジュアル面での限界が押し上げられるわけでもありませんが、問題の一部を解決して、適切に対処したかったのです。

テクスチャ解像度を上げたり、ゲーム内でさらに多くのテクスチャを使用したい場合は、ビデオ メモリがひとつの制約になります。グラフィック カードのベンダーは、メモリを増やし続けていますが、デベロッパー側では不足が続いています。ゲーム レベルの開始時にテクスチャをロードし、ロード終了を待つ代わりに、デベロッパーは何らかの形のテクスチャ ストリーミングを長年使用してきました。しかし、アンリアル エンジン 4 のミップマップ ストリーミングのような高度なシステムでさえ、限界があります。 

弊社の主力ミドルウェア製品である Granite SDK では、既存システムが抱える課題に対処し、非常に大きなテクスチャ (>16K) を使用するような機能の追加を始めました。 Granite の中核となるのは virtual texturing (仮想テクスチャリング) という技術であり、id Software が先駆けたメガ テクスチャ処理に弊社が取り組んだものです。Tiled Resources (DX11.2) や Partially Resident Textures (OpenGL) という言葉も耳にしたことがあるかもしれません。この 2 つはグラフィックス ハードウェアの仮想テクスチャリングを加速する技術です。ただし、これらは Granite を実行するうえで不可欠なものではありません。

弊社では、これまでにも UE4 向け SDK の統合のサンプルはありましたが、初の洗練されたユーザーフレンドリーな UE4 向け拡張である Granite for Unreal を最近ローンチしました。ハイエンドなグラフィックスを目指すならアンリアル エンジンは理想的な選択肢であり、Granite は素晴らしい組み合わせになります。さらにアンリアル エンジン用の 使用台数ベースのライセンス の提供を始めました。規模の大小にかかわらずあらゆるチームがこうした技術の恩恵を受けると信じているからです。将来詳しい情報を提供する予定ですが、インディーのライセンスにも取り組んでいます。

Granite を使う理由は?

簡単にいうと、Graphine for Unreal は、アーティファクトのポッピング、メモリ不足、長いロード時間などの限界にぶつかることなく、一般的に高い解像度テクスチャ マップや多くのテクスチャを使用するためのソリューションになります。最高 256Kx256K までのテクスチャ、UDIM テクスチャ、4K や 8K の何百もの個々のテクスチャまで使用することができます。

Granite は幅広いアプリケーションで使われてきました。Oculus、Allegorithmic、The Mill などの企業がこの技術を使って、リアルタイム グラフィックスのクオリティの限界を押し上げています。Larian Studios 制作の Dragon Commander は、ベイクした 16K のランドスケープ テクスチャにこれを使用しています。また、The Farm 51 制作の Get Even もフォトリアルな外観を実現するためのユニークな高解像度 3D スキャンに使用しています。VR 向けに、Granite は大きな超微細テクスチャをプリベイクすることで忠実度の高いグラフィックを生み出す支援をし、ソリッドな 90FPS でレンダリングする場合であっても、うまく処理します。 

GetEven  
Environment in Get Even、制作 The Farm 51

 

この記事では、Granite を使用してアンリアル エンジンで大きなテクスチャの解像度を使用する方法を説明します。次のセクションではテクスチャ ストリーミングに関する技術情報をご紹介します。Granite の使用方法だけを知りたい場合は技術情報のセクションをスキップすることもできます。 

すぐに Granite を試すにはここからまたは ここからビデオリンクをご覧ください。 

テクスチャ ストリーミング

テクスチャ ストリーミングはゲームのプレイ中にバックグラウンドでディスクからテクスチャ データをロードするプロセスです。ワールド内のテクスチャの小さなサブセットだけが実際にはメモリに保存されます。ストリーミング システムが、ディスクから特定のテクスチャをいつロードするか、またはプログラマが明示的にロードするテクスチャを要求する時に自動的に決定します。またはこの 2 つの方法を組み合わせます。 

アンリアル エンジンには、独自のテクスチャ ストリーミング システムがあり、数多くのパラメータに基づきテクスチャを自動的にロードします。その際、最も重要なファクタは、カメラからの距離になります。アンリアル エンジンでは、カメラがテクスチャから一定距離内に入ると、テクスチャの新しいミップマップを読み込みます。こうしたシステムによって大きなオープン ワールドのゲームが実現します。ただし、密度の高いシーンは対処が難しくなります。密度が高いということは、多くのオブジェクトが接近して配置されていたり、ひとつのオブジェクトに対して多くのテクスチャがあることを意味します。ワールドのひとつの特定エリアに過剰な数のテクスチャを使用すると、こうしたテクスチャのすべてが特定の時間にカメラに近くなり、ストリーミング システムによってロードされる必要が生じます。その結果、ポッピングやブラーなどの視覚的なアーティファクトが生じてしまいます。メモリのキャッシュ サイズを大きく設定することはできますが、こうした対処では明らかに限界があります。 

Granite SDK で、こうした課題に対するソリューションの開発を目指しました。Granite SDK は、タイルベースのテクスチャ ストリーミング、仮想テクスチャリングのシェーダー ライブラリ、様々なテクスチャ圧縮フォーマット、テクスチャ トランスコーダ、予測システム、キャッシュ管理システムなどの技術を備えています。 技術的な詳細に立ち入りすぎないように説明すると、Granite はすべてのテクスチャのミップマップを小さなテクスチャ タイル、通常は 128x128 ピクセルに分割します。ゲーム実行中、Granite はどのタイルがカメラから実際に可視であるかを自動的に把握し、可視のタイルだけをロードします。ほとんどの場合、テクスチャのミップマップの一部だけが可視であるからです。例えば、以下の画像では飛行機の翼の上部しか見えていません。通常のストリーミング エンジンでは飛行機のすべてのテクスチャがロードされます (8K ディフューズ、8K 法線、8K スペキュラ)。一方、Granite では実際に必要とされるタイルだけをロードします。その結果、ロードされるデータははるかに少なくなり、使用するテクスチャ メモリも少なくてすむため、高いテクスチャ有効解像度を実現します。

GRAPH_1 Graph_2

仮想テクスチャリングを使用する主なメリットは、最高 256Kx256K でも可能なかなり大きなテクスチャを使用できることです。こうしたサイズのテクスチャが DXT1 で圧縮されるとメモリの 32GB を占めるため、ロードに数分かかることになります。Granite を使用すると、こうしたテクスチャの場合、VRAM の 32MB だけしか必要とせず、ロード時間もほとんど気にならないレベルです。 

ひとつ考慮すべきなのは、仮想テクスチャ サンプリング (Virtual Texture sampling) は通常のテクスチャ サンプリングに比べて若干のパフォーマンスの負荷が加えられるということです。そのため、VT テクスチャの量をひとつのマテリアルにつき16 までに制限し、こうしたテクスチャをサンプリングするための UV 座標は最高 4 種類までにしました。こうすることで、VT サンプリングのパフォーマンス上の影響が、ほとんどの実践シナリオ (例、ゲームや VR 体験) では測定できないレベルになるようにしました。

Granite for Unreal のワークフロー

テクスチャをインポートするワークフローは、Granite を使用する場合は若干異なります。以下でその手順を説明します。 

  1. 弊社のツールのひとつを用いて(以下参照)、テクスチャを Tile Set にインポートします。Tile Set とはディスクから効率的にストリーミングするためのタイル化されたフォーマットでテクスチャを保存するためのコンテナです。Tile Set はテクスチャのデータベースまたは最高 256K までの非常に大きなテクスチャ アトラスとして考えることができます。
  2. 他のアセットで行うのと同じように、.GTS Tile Set ファイルをアンリアル エンジンにインポートします。これで、Tile Set にインポートしたすべてのテクスチャに対して、アンリアル エンジンで ‘Granite Texture’ オブジェクトが自動的に作成されます。こうしたオブジェクトは標準のアンリアル テクスチャと類似しています。 
  3. Granite Material Node で Granite Textureを使用します。こうしたマテリアル ノードでは、マテリアルで Granite Textures をサンプリングすることができます。

Graph_3

これだけです。本当に簡単です。Granite Texture ノードをマテリアル グラフで従来のテクスチャ ノードと同じように使用可能であり、すべての Granite テクスチャはバックグラウンドで Granite によってストリーミングされます。 

Granite テクスチャ ノードは標準のアンリアル テクスチャと結合することができます。どのテクスチャを Granite でストリーミングしますか?一般的に、Granite の使用は、特定のオブジェクトやエリアに固有の大きなテクスチャ (>1K) の場合に意味があります。小さなテクスチャ、異なる UV で複数回サンプリングされるテクスチャ、ほとんどの時間に可視状態であるテクスチャは、アンリアルのストリーミング システムの方がうまく処理するか、または全くストリーミングされません。

テクスチャのインポート

Tile Sets (.GTS files) を作成し、テクスチャの画像ファイルをこのフォーマットにインポートするために、Tile Set Studio と呼ばれるハンディなツールを用意しています。Tile Set Studio は、.jpg、 .png、 .exr、 .tga などのほとんどの一般的な画像フォーマットをサポートしています。

Graph_4

大きなテクスチャのインポート

Tile Set Studio は最高 32Kx32K までの個々の画像ファイルをインポートすることができます。その素晴らしい機能のひとつとして、ディスク上に画像ファイルのグリッドとして保存されるテクスチャをサポートします。大きな画像ファイルを扱うほとんどのツールでは、このようなファイルを画像セットとしてエクスポートすることができます。こうしたファイルのグリッドをインポートするには、グリッド内での位置を示す文字や数を使用して命名する必要があります。例えば、‘landscape_02_06.jpg’ や “satellite-A-3.png” などが考えられます。こうした画像のひとつを選択するだけで、Tile Set studio はその画像が画像セットの一部であることを自動的にを検出します。こうしたタイル化された画像の解像度は合わせて最高 256Kx256K まで可能です。

VFX クオリティの UDIM のインポート

Tile Set Studio は、UDIM テクスチャも簡単にインポートすることができます。例えば、‘robot_1016.exr’ など、UDIM パッチのひとつを選択します。または、MARI から直接エクスポーターを使用することもできます。すべての UDIM パッチは、その Tile Set をインポートするとアンリアル エンジンではひとつの Granite Texture になります。Granite では、メッシュを変更する必要がないように UDIM UV 座標を処理して、これらを直接アンリアル エンジンで使用することができます。 

もうひとつの重要な要素として、Granite では VFX クオリティの UDIM テクスチャでは一般的な膨大な量のテクスチャを処理できるということがあります。例えば、Nurulize 制作のRobot in the Rise のデモ (画像参照) では、700 の 4K マップがあります。Granite では、実際には一定時間しか見えない UDIM パッチのサブパートだけをロードします。こうすることで、問題が生じることな最高品質のテクスチャを表示させることができます。 

Graph_5

数百のテクスチャのインポート

最後になりますが、面倒なタスクを避けるために Tile Set Studio では、ワイルド カードとバッチ インポートをサポートしています。こうした機能によって、フォルダ全体や ‘plane_diffuse.jpg’、 ‘robot_diffuse.jpg’ などの一貫性のある名前を付けたファイル一式を一回の操作でインポートすることができます。この例では、‘*_diffuse.jpg’ を使用してフォルダ内にあるすべてのディフューズ テクスチャをインポートします。アンリアルの Granite テクスチャ (インポート後) は、ファイル名の固有部分を用いて命名されます(‘plane’、 ‘robot’ など)。 

その他の注目機能

ライトマップのストリーミング

 

Graph_6

アンリアルの Lightmass システムを使用すると、Granite を使用してライトマップを簡単にストリーミングすることができます。以下のように選択ボックスにチェックを入れると設定できます。Granite では、わずか 64MB のビデオメモリだけを使用して数百ギガバイトのライトマップを処理できるので、ライトマップの解像度をご自由に増やしてください。

Graph_7

キューブマップのストリーミング

Granite では、他のテクスチャと同じようにキューブマップを扱うことができます。.DDS ファイルを選択して、Tile Set Studio のキューブマップ ボックスにチェックを入れてください。Tile Set をアンリアルにインポートすると、Granite は、GraniteTextureCube を自動的に作成します。こうしたストリーミングされたキューブマップは通常のキューブマップと同じように使用することができます。

テクスチャの圧縮

Granite には、DXT1、 BC5、 BC7 などのブロック ベースのフォーマットと比較するとテクスチャを 60% 以上圧縮できる独自の圧縮コーデックがあります。圧縮スキームもスケーラブルであり、テクスチャ マップ毎にクオリティ レベルを設定することができます (low、medium、high、lossless)。‘Low’ と ‘Medium’ のクオリティでは、ディスク上のサイズは非常に小さくなり、ストリーミングのパフォーマンスは向上します。‘High’ クオリティ設定では、テクスチャを平均で 60% で圧縮しながら良好なクオリティも保ちます。結果として、効率的なストリーミングをしながら、ディスクの使用量も減らします。

詳細なパフォーマンス制御

3D エンジンのコンポーネントでよく見られるように、Granite はローエンドからハイエンドのマシンまでうまくスケーリングするように設計されています。典型的なシナリオでは、1080p でレンダリングする場合、Granite では約 512 MB のビデオ メモリを必要とします。キャッシュ サイズを高く設定することで、Granite が不可視のデータをより多くキャッシュする支援をします。キャッシングを増やすと、メモリ使用が増えるのと引き換えに、システムの作業負荷を減らすことができます。ただし、これはレベルに膨大な量のテクスチャを追加したとしても不要です。例えば、ローエンドのマシンで 256MB しか使えない場合、Granite では自動的にテクスチャ解像度をスケールバックし、パフォーマンスを安定させるようします。テクスチャ設定を手動で微調整する必要はありません。 

同じスケーリング システムを制御して、ストリーミングするデータを一時的に少なくすることもできます。例えば、カメラが速く移動している場合にモーション ブラーを加える場合、ディテールは再びブラーされてしまうため、最も詳細なミップマップからタイルをストリーミングする必要はありません。この設定により、上記の例ではレンダリング クオリティに影響を及ぼすことなく高速移動するカメラのエフェクトを無効にし、 4 倍または 16 倍少なくストリーミングします。

他の設定では、Granite が 1 フレームあたり、どれくらいストリーミングできるかを制御します。これは、高いフレームレートをターゲットにしているか、ゲームの他のサブシステムのために余裕を残したい場合に特に便利です。こうした設定を低くすることで、Granite が 1 フレームあたりで使用するリソースが少なくなり、実質上はより多くのフレームで使用するリソースが少なくなります。デメリットとしては、ピーク時にすべての必要なテクスチャ タイルがロードされるまで遅延が長くなります。

まとめ

テクスチャ ストリーミングについて言及すると、直観的にオープン ワールドを想定する方が多いと思います。もちろん Granite はオープン ワールドに適したソリューションですが、アンリアル エンジン単体でもそれに十分対処できます。Granite がその存在価値を放つのは、固有のテクスチャが多数ある密度の高いシーンの場合です。ほとんどの場合、各オブジェクトの一部だけが可視状態であり、Granite はこうした見えるテクスチャ部分だけをロードすることを利用しています。こうした手法から、 Granite は次のような場合に優れたソリューションになります。大きなプリベイクされたランドスケープ テクスチャや衛星画像、多くのパッチがある UDIM テクスチャ、大きなマテリアル マスク、高解像度ライトマップ、フォトグラメトリ スキャンを使用したい場合があります。また、ポッピングの問題やギガバイト単位の VRAM を必要とせずにオブジェクトやキャラクターのテクスチャの解像度を 4K や 8K に増やす支援もします。 

Granite 側の大部分の作業は、使用するリソースの量を可能な限り少なくすることに費やされます。さらに、パフォーマンス、メモリやディスクの使用量、レンダリングのクオリティの間のトレードオフを微調整できるように多数のパラメータを用意しました。こうすることで、アプリケーションのリソースの割当量を抑えながら最高のクオリティを実現することができます。これは仮想現実の場合に特に重要になります。仮想現実では、良好な体験を実現するためにソリッドな 90FPS は不可欠だからです。Granite が VR 向けにどのように使われるか今から楽しみです。グラフィック カードで帯域幅の制限がなければ、フレームレートに影響を与えることなくビジュアルのディテールを加えるために、テクスチャ解像度を上げることは優れた方法です。

Granite for Unreal をリリースする度に、アンリアル向け Granite SDK でさらに多くの機能を公開しています。例えば、将来のリリースではパフォーマンスの制御をさらに強化する予定です。既に Granite をアンリアル エンジンのライトマップ システムと接続し、アンリアルのテレイン システムを調整しています。Granite for Unreal では高さマップ、ディスプレースメント マップを既にサポートしており、近い将来、自動テレイン サポートを追加するかもしれません。 

私どもはカスタマーの要求に応じて絶えず新機能を追加してきました。皆さんのご意見をお寄せください。コミュニティからのフィードバックを楽しみにしています。まだ Granite をご利用になっていない場合は、ここから  試してください。