カテゴリー別アーカイブ: Tools

オープンソースのメッシュ最適化ライブラリmeshoptimizerとメッシュ最適化の話題

はじめに

AMD Compressonator 3.0のリリースの際に,メッシュ最適化や圧縮機能が加わりました.

Compressonator V3.0 Release Brings Powerful New 3D Model Features
https://gpuopen.com/compressonator-v3-0-release-brings-powerful-new-3d-model-features/

メッシュの圧縮にはGoogleのDracoが入ったのですが,最適化はどういったライブラリをベースにしているのか気になって調べてみました.AMDであればTootleが長らく使われていたのですが,GPUOpenのスクリーンショットでTootleではなさそうで,自分が触ったことがあるライブラリの用語が出てきているので最適化部分のソースを見てみました.

https://github.com/GPUOpen-Tools/Compressonator/tree/master/Compressonator/Source/CMP_MeshOptimizer

どうやらCompressonatorではTootleを採用せずにmeshoptimizerを使用しているようですね.今回はmeshoptimizerを紹介しつつもう一度メッシュの最適化とは何かを簡単に復習したいと思います.

meshoptimizer
https://github.com/zeux/meshoptimizer

meshoptimizerについて

meshoptimizerはGPUで描画する3Dの三角形ポリゴンの最適化のためのライブラリですね.特に頂点とインデックスを処理するものになります.こうしたライブラリはAMDであればTootleなどがあります.使用して見た印象ではtootleに使い勝手が近く,すでにTootleを使用しているところは移行がしやすいと思います.

meshoptimizerの機能

meshoptimizerの最適化に関連する機能としては以下です.

  • Indexing
    • インデックスのない頂点データのインデックス化
  • Vertex cache optimization
    • 頂点キャッシュの最適化
  • Overdraw optimization
    • オーバードローの最適化
  • Vertex fetch optimization
    • 頂点フェッチ最適化
  • Vertex quantization
    • 頂点の量子化
  • (optional) Vertex/index buffer compression
    • 頂点,インデックスバッファの圧縮

このほかに三角形リストをストリップ化する機能もあります.現在は,インデックス付き三角形リストがGPUでレンダリングする上では効率的といわれています.meshoptimizerのページでは,ストリップはリストと比較して50%から60%程度インデックスを多く持ち,リスト(三角形当たり1.5から1.8のインデックスを持つケース)が最適化指標のACMR(後述)において~5%程度不利になるということが書かれています.

上記の最適化機能のうち,AMDのTootleではVertex cache optimization, Overdraw optimization, Vertex prefetch cache optimizationの3つがサポートされています.

さらに頂点について最適化度を評価する分析関数があります.この関数を最適化前と後にかけることで,どれだけ変わったかの比較ができます.なんとなく最適化ツールにかけておけばよいだろと思ったときに評価するものがないと実は元データはそれなりに最適化されていてやった意味がないわけですね.

  • meshopt_analyzeVertexCache
    • 頂点キャッシュの分析
  • meshopt_analyzeVertexFetch
    • 頂点フェッチの分析
  • meshopt_analyzeOverdraw
    • オーバードローの分析

meshoptimizerのサポートする最適化

ここからは各機能について解説をしていきます.

Indexing

meshoptimizerでは基本的にインデックスがあるものを最適化するのですが,元データがインデックスがない場合にはインデックスを生成して重複頂点を削除する関数があります.

Vertex cache optimization

頂点キャッシュの最適化は,インデックスを頂点キャッシュを効果的に使うように並べ替えます.この時,頂点データの方は並べ替えはしません.

GPUは,ベンダーごとに16~64頂点の単位で頂点を処理します.この時に,1つの単位で頂点キャッシュが効くので複数の三角形で共有する頂点がある場合には,キャッシュの恩恵を受けます.この最適化はmeshopt_optimizeVertexCache関数に並び替え前のインデックスとインデックスカウント,頂点を入れると並び替えたインデックスを返してくれます.

Overdraw optimization

オーバードローに対する最適化です.オーバードローは,1つのピクセルがカメラから見て対して三角形が重なりあった場合にピクセルシェーダが複数回呼び出されるオーバードロー状態になります.深深度テストが適切に行われる構造であればオーバードローが抑制できますが,適切に行われないデータの場合,この最適化が有効です.

この最適化はピクセルシェーダの負荷が高いケースで,シェーダの呼び出しを抑制することで負荷を軽くすることを目的に行います.複雑なシェーダを適用するものに効果が高いと思います.

オーバードローの最適化を行うにはインデックスのほかに頂点座標を渡す必要があります.この最適化アルゴリズムは頂点キャッシュの効率とのバランスをとるための係数を与えることができます.

Vertex fetch optimization

頂点フェッチの最適化は,頂点バッファを並び替えてメモリアクセスの効率化を行います.GPUは頂点シェーダを実行する前に頂点バッファから頂点属性をフェッチしますが,その際のメモリアクセスの最適化をします.

最適な頂点データの配置はインデックスをもとに決めるためある最適化されたインデックスバッファにて行うとよいようです.

この最適化の注意は,頂点データの方の並び替えが発生する点にあります.たとえば,BlendShapeなどを使う場合,頂点データの並びが変わるとモーフターゲットとベースメッシュの頂点のインデックスがマッチしなくなるかもしれません.

Vertex quantization

頂点の量子化は頂点データのメモリの帯域幅を削減する最適化です.頂点データに必要なメモリを削減する効果もあります.

この最適化は,頂点データの中の座標や法線などを小さいサイズにします.例えば,頂点法線は一般的にXYZの3Dのベクトルで持ちますが,XYZの各要素はfloatで持つことがあると思います.量子化ではこれを10bitにエンコードしてしまうことで10:10:10:2の32bitをに入れてしまいます.こうすることで96bit(float x 3)だったものが32bitになります.

法線の精度が下がるとシェーディングの落ちるケースがありますが,モバイルでは精度よりパフォーマンスを取りたいというケースがありますので有効なことがあるかと思います.

他に量子化が可能な頂点要素だと頂点座標ですが,これは各要素を32bit floatから16bit shortにしてしまうということもありうるかと思います.

量子化はモバイルで有利と書きましたが,通信でデータを取得してブラウザでレンダリングをするWebGLなどでもありがたいかもしれませんね.

(optional) Vertex/index buffer compression

この最適化は,頂点バッファとインデックスバッファ自体を圧縮することでデータを小さくします.これはGPU上での最適化というよりはストレージサイズやローディングなどのケースで有効なものかと思います.

この圧縮はoptionになっていますが,使用するにはいくつか条件があるようです.頂点に関しては,頂点バッファが頂点フェッチ最適化がされ,頂点データが量子化されていることが条件のようです.インデックスに関しては,頂点/インデックスバッファが頂点キャッシュおよび頂点フェッチの最適化がされている必要があり,そうでないケースは圧縮率が下がるようです.

なお,この圧縮に加えてzstdなどでさらに圧縮ということも有効なようです.冗長性を考慮している分,圧縮前のデータからかけるよりも有効に機能するようです.

デコード機能は,1~2GB/s程度で動作し,16bitインデックスバッファであれば5~6倍程度は圧縮できるそうです.これにさらに汎用的な圧縮アルゴリズムを適用することで圧縮率を高められるようです.

圧縮といえばGoogleのDracoがありますが,このことについても触れれています.Dracoでは自分たち独自の量子化などを行った頂点データの圧縮などは不向きなようで,Dracoで圧縮したものを展開してから量子化では処理時間がかかるので,meshoptimizerでの量子化を行うケースではこの圧縮が相性がいいようです.

最適化の分析関数

つづいて最適化の分析関数について見ていきます.最適化の分析関数は,最適化前と後のインデックスにかけてみることでmeshoptimizerの最適化が効果あったか比較するのに使えます.

meshopt_analyzeVertexCache

頂点キャッシュの最適化具合を測ります.キャッシュの最適化はACMRとATVR2つの指標があります.

ACMRは,Average cache miss ratioということで平均キャッシュミス率ということでワーストケースでは3という数字になり,0.5に近いほど良いケースということだそうです.インデックスバッファから三角形を呼び出す際に,各頂点がキャッシュからどれだけ呼び出せるかが,3頂点ともキャッシュにないケースが非効率なケースですね.だいたい,0.5 – 1.5の範囲に収まるのが一般的なケースのようですね.

ATVRCは,Average transformed vertex rationになり総頂点に対してどれだけ頂点シェーダが呼び出されるかの比率になります.1.0が最良のケースだそうです.1つの頂点が頂点シェーダから複数呼ばれるケースというのはインデックスで同じ頂点が何度もあるケースですね.

meshopt_analyzeVertexFetch

頂点フェッチの統計を返す関数です.最善のケースだと1.0を返し,大きくなるほど効率が悪いといえます.この統計は,頂点バッファから読み込んだバイト数と頂点バッファの合計サイズの比ということになります.

meshopt_analyzeOverdraw

オーバードローの統計を取る関数です.この分析は正射影でいくつかの視点で描画します.その際に実際にピクセルシェーダが呼び出される数の比率です.1.0が最善のケースで数値が大きいほどオーバードローが多いということになります.

おわりに

meshoptimizerの機能を見ていくことで頂点データを最適化するアプローチというものが見えてきたかと思います.

今回取り扱った話題の多くは,Xbox 360やPlayStation 3など本格的にGPUを使った開発をする時代にはよく知られていた最適化の基本であったのですが,最近はこうした初歩的な最適化の知識は開発者にとって当たり前のものということなのか読める資料が少なくなってきました.一方で,若い開発者はそうした知識を学ぶための資料がないことで学ぶのが難しくなりました.そういう点では今回は頂点データの最適化の基礎を復習するにはちょうど良い題材でした.

 

実践に関しては,meshoptimizerは比較的組み込みやすいライブラリではありますが,AMDのCompressonatorは分析して表示する機能もありますので,そこから使用してみるとわかりやすいと思います.

 

AMD Compressonator 3.0リリース

AMD Compressonatorの3.0がリリースになっています.

Compressonator V3.0 Release Brings Powerful New 3D Model Features

https://gpuopen.com/compressonator-v3-0-release-brings-powerful-new-3d-model-features/

今回のバージョンからテクスチャの圧縮機能に加えてメッシュの最適化やメッシュの圧縮などが入ってきています.メッシュの圧縮にはGoogleのDracoに対応したようです.

AllegorithmicのPBR GUIDE の2018年版が公開に

AllegorithmicのPBR GUIDE の2018年版が公開になっています.

THE PBR GUIDE – 2018 EDITION
https://www.allegorithmic.com/pbr-guide

このガイドではライトやシェーディングを扱うパートとテクスチャ作成の2つのパートに分かれています.

  1. Light and Matter : The theory of Physically-Based Rendering and Shading
  2. Practical Guidelines For Creating PBR Textures

Light and Matter : The theory of Physically-Based Rendering and Shading
https://academy.allegorithmic.com/courses/b6377358ad36c444f45e2deaa0626e65

Practical Guidelines For Creating PBR Textures
https://academy.allegorithmic.com/courses/05171e19aa8dc19421385fd9bb9e016e

GAPID:GoogleのOpenGL ES, VulkanのグラフィックスAPIデバッガ

GoogleがOpenGL ES, VulkanのグラフィックスAPIデバッガ GAPIDを公開しています.

このツールは,Android,Windows, Linux,OS XでOpenGL ES, Vulkan上でグラフィックスAPIの呼び出しをデバッグできるツールです.

Save development time with our new 3D debugging tool
https://www.blog.google/products/google-vr/save-development-time-our-new-3d-debugging-tool/

ツール概要
https://developers.google.com/vr/develop/android/gapid

ソース
https://github.com/google/gapid

OSごとに取得できるものは違います(OS XはVulkanがいけない)が,PC上でも取れるので実機に行く前にPC環境で動作を調べたりなどに便利そうですね.

Android Windows macOS Linux
OpenGL ES Trace
OpenGL ES Replay
Vulkan Trace
Vulkan Replay
(Must be performed on the same device used to trace)

Draco : Googleによるオープンソースの3Dデータ圧縮ライブラリ

Googleが3Dデータ向けの圧縮のためのオープンソースライブラリDracoを公開していました.

Draco
https://google.github.io/draco/

リポジトリ
https://github.com/google/draco

3DグラフィックスAPI向けにデータを流しやすくということのようですね.通信がありブラウザで使われるWebGL(Three.jsで対応)やglTF, WebVRなどの分野では圧縮は意義がありそうですね.

Dracoについては,glTF 2.0の圧縮形式としてKHR_draco_geometry_compression拡張が提案されているようですね.

Comment period for Draco extension
https://github.com/KhronosGroup/glTF/issues/1114

SIGGRAPH 2017 Open Problems in Real-Time Renderingのコース資料

Open Problems in Real-Time Renderingのコース資料が徐々に公開されています.

Open Problems in Real-Time Rendering
http://openproblems.realtimerendering.com/s2017/index.html

“Real-Time Rendering”ということで,ゲームやゲームエンジンの開発にかかわるような人が抱える問題や課題,将来予測などの4つのセッションがあります.

特に今回はPBR, GI, Compute, Deep Learningの活用というテーマに分かれています.

  • Physically-Based Materials: Where Are We? by Sébastien Lagarde (Unity Technologies)
  • A Certain Slant of Light: Past, Present and Future Challenges of Global Illumination in Games by Colin Barré-Brisebois (Electronic Arts SEED)
  • Future Directions for Compute-for-Graphics by Andrew Lauritzen (Electronic Arts SEED)
  • Deep Learning: The Future of Real-Time Rendering? by Marco Salvi (NVIDIA)

SIGGRAPH 2017コース Physically Based Shading in Theory and Practiceの資料が公開開始

SIGGRAPH 2017コース Physically Based Shading in Theory and Practiceの資料が公開開始になっています(この記事執筆時点ではすべてが公開されているわけではありません).

SIGGRAPH 2017 Course: Physically Based Shading in Theory and Practice
http://blog.selfshadow.com/publications/s2017-shading-course/

今年のセッションは以下の6つのセッションですね.

  • Real-Time Line- and Disk-Light Shading (Eric Heitz and Stephen Hill)
  • Physically Based Shading at DreamWorks Animation (Feng Xie and Jon Lanz)
  • Volumetric Skin and Fabric Shading at Framestore (Nathan Walster)
  • Practical Multilayered Materials in Call of Duty: Infinite Warfare (Michał Drobot)
  • Pixar’s Foundation for Materials: PxrSurface and PxrMarschnerHair (Christophe Hery and Junyi Ling)
  • Revisiting Physically Based Shading at Imageworks (Christopher Kulla and Alejandro Conty)

Radeon GPU Profiler 1.0リリース

AMDがRadeon GPU Profiler 1.0を公開しました.

Radeon GPU Profiler 1.0
http://gpuopen.com/radeon-gpu-profiler-1-0/

Radeon GPU Profiler(ツールのページ)
http://gpuopen.com/gaming-product/radeon-gpu-profiler-rgp/

こちらのツールは,Radeon向けのGPUプロファイラーでDirect3D12とVulkanに対応しています.

キューやコマンドの実行状況やWavefrontの占有率、コンテキストロールのストールなどを分析できます.

紹介動画なども公開されています.

VSCodeでglTFのプレビューができるglTF Extension for Visual Studio Code

VSCodeでglTFのプレビューができるglTF Extension for Visual Studio Codeが公開されています.

glTF Extension for Visual Studio Code
https://marketplace.visualstudio.com/items?itemName=cesium.gltf-vscode

VSCode上でglTFのJSONを編集しつつBabylonJS,Cesium,ThreeJSの3つのWebGLベースのエンジンで3Dモデルをプレビューすることができます.プレビュー以外にもデータの変換やチェック向きの機能もあるので便利そうですね.

HLSL to ISPC : HLSLのコードをISPCで実行できるようにするライブラリ

HLSL to ISPCというHLSLのコードをISPCで実行できるようにするライブラリが公開されています.

HLSL to ISPC
https://colinbarrebrisebois.com/2017/06/27/hlsl-to-ispc/

GitHubリポジトリ
https://github.com/zigguratvertigo/hlsl-to-ispc

テクスチャに関連する処理などは未対応なのですが,GPUのシェーダに慣れたプログラマがISPCを利用するには良いかもしれませんね.

特にCompute Shaderなどでテクスチャを使用しない演算処理などを書いている場合にCPU側に持っていきつつSIMDを活用したいというケースでは重宝しそうです.

なお,HLSL以外にGitHubリポジトリではGLSLに対応したいというようなことも記載されています.