From BlenderWiki

Jump to: navigation, search

Blender 2.76: OpenSubdiv

OpenSubdiv プロジェクトは高解像度のキャラクタモデルを、ビューポートでリアルタイムにアニメーションし、アニメーターが最終結果を高い FPS で確認できるようにするための物です。

この目標に達する手段として、OpenSubdiv ライブラリが公開されました。

概要

OpenSubdiv は Subdivision Surface(細分割曲面、略称 Subsurf)モディファイアーの新しいオプションです。

このオプションがONの場合、モディファイアースタックの一番上の Subsurf モディファイアーは、User Preferences(ユーザー設定)内で選択された演算デバイスにより計算されます。最もパフォーマンスが上がるのは GLSL による計算時でしょう。

OpenSubdiv は高性能なビデオカードと最新のビデオドライバーのインストールを必要とします。お勧めのビデオカードは AMD と NVidia で、数年以内の物です。

Blender に全く新規に統合された技術であるため、まだバグや問題があるかもしれませんが、謹んで将来の Blender リリースで解決する予定です!

用語の定義

  • ベースメッシュ - サブディビジョンサーフェス化される前のメッシュ(Subdivision Surface(細分割曲面)モディファイアの入力)
  • ベース座標 - ベースメッシュ上の頂点位置

OpenSubdiv とは

概要

OpenSubdiv は Catmull-Clark(カトマル・クラーク)サーフェスサブディビジョンを実装したライブラリで、以下の特長があります。

  • 一度重い計算を行えば、後はベース座標の更新を高効率でリファイン可能
  • GPU サイドでの高解像度メッシュテッセレーション
  • レンダラーから使用可能な計算用 API を実装
  • エッジシャープネス(クリース)に対応(少なくとも Blender の元々の挙動より高品質)
  • CPU、GLSL、CUDA、OpenGL などの複数のバックエンド処理に対応

制限事項

OpenSubdiv には確かに利点がいくつかあるものの、魔法のアイテムではなく、制約もあります。それは主に、ベースメッシュのトポロジーが変更されていない状況に最適化されていることです。もしベースメッシュがトポロジーを変更しようとしている場合、Blender の初期実装上において、OpenSubdiv はパフォーマンス上の恩恵が何もありません。

もっと技術用語を減らすと、OpenSubdiv は最終的なメッシュ分割数で、リアルタイムにビューポート再生が必要なアニメーターを助けることを目的にしているというだけのことです。

Blender への統合

OpenSubdiv が Blender に統合され、このセクションでアーティストと開発者の両方に必要な、重要な情報をすべて取り上げます。

注意:Blender は OpenSubdiv 対応でコンパイルされている必要があります。そうでない場合、以下のセクションはあまり関係がありません。

アーティストレベルのドキュメント

User Preferences(ユーザー設定)内の OpenSubdiv Compute(OpenSubdiv 演算)オプション

アーティスト用の OpenSubdiv は非常に簡単に使用できます。単に User Preferences(ユーザー設定)内の新しいオプションと Subdivision Surface(細分割曲面)モディファイアを設定するだけです。

まず、User Preferences(ユーザー設定)内の System(システム)セクションで、OpenSubdiv Compute(OpenSubdiv 演算)オプションを操作します(Cycles で使用するデバイスオプションの真下です)。

以下の演算デバイスが利用可能です。

  • None(なし) - すべての OpenSubdiv 演算デバイスを無効にし、Blender の旧来の SubSurf コードを使用します。このオプションは、 OpenSubdiv がバグや退化を引き起こした時に使用してください。
  • CPU - シングルスレッドの CPU 実装。主に GPU 演算が可能で※、CPU スレッド化オプションでアーティファクトがでる場合(起こることはないでしょうが、可能性はあります)に便利です。(※yamyam注:原文は "GPU compute is possible"。表示用には最低限 GPU 対応が必要なことを示しているのかもしれません)
  • OpenMP - マルチスレッドの CPU 実装。旧 SubSurf コードのスレッド化モデルと似ています。GPU 演算が利用できない時に最大パフォーマンスを得るのに使用します。
  • GLSL Transform Feedback - GPU を使用し計算を処理します。ビデオカードとドライバーへの要求が最小です。
  • GLSL Compute - GPU を使用し計算を処理します。Transform Feedback に比べて効率的ですが、ビデオカードとドライバーへの要求が高くなります。
Note
CPU 演算でもビューポートでのメッシュを最前の方法で表示するため、グラフィックカードは少なくともジオメトリシェーダーとユニフォームバッファーに対応している必要があります。もし GPU またはそのドライバーがこの機能に対応していない場合、利用可能な OpenSubdiv 演算デバイスはありません。


そのシステムに対応する最速のオプションを選択すれば、OpenSubdiv は準備完了です!

後は Subdivision Surface(細分割曲面)モディファイア設定に行き、Use OpenSubdiv(OpenSubdiv を使用)オプションを有効にするだけです。

Subdivision Surface(細分割曲面)モディファイアー設定の OpenSubdiv オプション

このオプションを有効にすれば、モディファイアは OpenSubdiv を計算に使用しはじめ、うまくいけばシーンの再生が大幅に速くなることでしょう。

必要条件

OpenSubdiv を最大のパフォーマンスで活用するには、以下の条件が必要になります。

  • Subdivision Surface(細分割曲面)モディファイアーがスタックの最後にあること
パフォーマンス向上の大半は GPU による物であるため、モディファイアースタックの途中では OpenSubdiv は使用できません。
注意:Subdivision Surface(細分割曲面)モディファイアーの上に無効になっているモディファイアーがある場合、OpenSubdiv が使用できない件については、現在 TODO として既知になっています。近い将来に解決される予定です。
  • Subdivision Surface(細分割曲面)モディファイアーの前に時間経過でメッシュのトポロジーを変更するモディファイアーがない方が望ましいです(もし入力トポロジーが変更された場合、Subdivision Surface(細分割曲面)モディファイアーは非常に重い計算部分に突入することになり、すべてのパフォーマンスが台無しになります)。
  • 他のオブジェクトが OpenSubdiv メッシュのジオメトリを使用しない方がいいでしょう。この場合、メッシュが CPU メモリ上にある必要があるため、メッシュが GPU 上で計算されていた場合は、あまり簡単・高速に処理できないためです。

制限事項

現在の OpenSubdiv リリースと現在の Blender 自身の OpenGL プロファイルでは解決不可能な制限が多数あります。

  • 現在の法線のスムージングが正しくありません。これは現在 Blender で使用可能な GLSL レベルかつ、OpenSubdiv が提供可能な物の制限です。ただしこれは高い優先度で作業中です。
  • OSX 未対応。従来、Blender は若干古い OpenGL API を使用してきており、OpenSubdiv は OpenGL 4を使用しています。そのため、アプリケーション内で新しい API を使用している場合、古い OpenGL コードを破棄することを強要する Apple のポリシーにより、OSX 上で Blender を OpenSubdiv と共に動かすことが不可能になっています。
  • ビューでの UV マッピングに未対応。この制限は OpenSubdiv が現在 GPU 上での UV マッピング計算にうまく対応しておらず、CPU 上で UV 計算する方法もないことによるものです。
  • Genarated(生成)座標に未対応。Blender の生成座標は非デフォームメッシュの計算を CPU 上で行う必要があり、すべてのデータが GPU 上にある OpenSubdiv をこのような状況で使用するのは非常に面倒です。
  • CPU 上にメッシュを持つ必要のあるツール(スナップツールなど)は、OpenSubdiv メッシュでは失敗します。これには Info(情報)ヘッダー内のプリミティブカウンターのような物も含まれます。
  • 現在シェーディングは 単一マテリアルのみに限定されています。これは Blender 側で簡単に解決でき、そのうち対処される予定です。
  • つながっていない辺や頂点は未対応です。
  • Auto Smooth※(自動スムーズ)はまだ動作していません。(※yamyam注:原文は Auto split)
  • Loop normals も未対応です。

ハードウェアの制限

現在 GLSL Compute は AMD ハードウェアでは無効になっています。これは OpenSubdiv 自身に問題があるためで、現在作業中であるものの、Blender のリリース前に完全には解決できませんでした。

Intel カードも現在 OpenSubdiv では無効になっています。これはこのカードに様々な問題が報告されている所為です。また、OpenSubdiv がこのハードウェアで高速になるのかどうかも不明です。しかし、OPENSUBDIV_ALLOW_INTEL 環境変数を設定することで、Intel カードでも強制的に有効にできます。

最大のパフォーマンスを得るには

OpenSubdiv 用に最大のパフォーマンスを得るテクニックがいくつかあります。

  • Outline Selection(選択時にアウトライン表示)を切る
現在の Blender のアウトライン描画のアプローチによる、OpenSubdiv メッシュのアウトライン描画はシェーディングメッシュの描画の約2倍の時間がかかります。これはジオメトリとテッセレーションシェーダーがアウトラインとシェーディングされたモデル両方で実行する必要があるからです。
  • 選択方法を OpenGL Occlusion Queries(OpenGL オクルージョンクエリー)に切り替える
デフォルトの選択方法では OpenSubdiv メッシュの選択は遅くなる可能性があります。これは OpenGL Select(OpenGL セレクト)モードがジオメトリとテッセレーションシェーダーの処理を CPU で行うためで、これは GPU を使用するより確実に遅いです。

開発者レベルのドキュメンテーション

このセクションは、新しい開発者たちがコードを理解するのに必要な事を主に取り上げています。

全体的な設計

この設計の主となる考えは、最終的に現在の Subsurf(訳注:Subdivision Surface の略)コードを、 OpenSubdiv を元にした新しい物に完全に切り替えることです。この観点から、OpenSubdiv は CCGSubSurf.c コードの透過的な(ユーザーに意識されない)代替だと思われます。実際この目標までもう少し時間がかかりそうですが、最終的には達成されるでしょう。

それはさておき、メインコンセプトは以下の通りです。

  • OpenSubdiv で CCGSubSurf.c 内のコードを置き換え、CCGDerivedMesh 内に視覚化に必要なコードをいくつか追加。
  • OpenSubdiv は GPU パイプライン(計算を CPU か GPU のいずれか、テッセレーションを GPU)とフル CPU(互換性とレンダーエンジン用)の両方に対応。
  • もし Subsurf がスタックの最後のモディファイアーであれば、計算はデフォルトの GPU コード経路になります。
もし GPU compute に対応していない場合、CPU 経路が代わりに使用されます。
  • CPU と GPU パイプラインの両方は、Blender 内で出来る限りローレベルで維持します。これは Blender 全体で OpenSubdiv を完全に透過(が意識されないよう)にするためです。
  • GPU コード経路が使用される場合、CCG ジオメトリ(CCGVert、CCGEdge 、CCGFace)は作成されません。これはメモリ消費量を最低限にするためです。

CPU による計算 (Evaluation)

CPU による計算は以下の場合に必要になります。

  • Subsurf モディファイアーがモディファイアースタックの途中にある
  • オブジェクトがレンダーエンジン用に処理中である

新しいコード経路のこの部分は CCG の従来の挙動に非常によく似せて模倣しています。CCG ジオメトリはまだ従来に使用されていた方法と完全に同じ方法で作成されており、OpenSubdiv は単に OpenSubdiv の EvaluationAPI を使用し、サーフェス計算コードをリプレースしているだけです。そのプロセスは大体以下のようになります。

  • CCgSubSurf を同期し、頂点や辺、面で埋める。
  • OpenSubdiv の計算が確実に更新されるようにする。
基本的に計算機(Evaluator)をキャッシュしており、違うフレームでも再利用可能です。しかし、もしトポロジーが変更された場合、計算機をを再構築する必要があります。
  • 各面のグリッド毎に繰り返し、グリッドの計算を呼び出す。
  • グリッドの「節」で計算が発生する。OpenSubdiv はグリッドではなく面を操作するため、グリッド座標から面座標への変換が呼び出されます。
  • OpenSubdiv の Evaluation API が両座標系と法線の計算で使用される。
  • 結果を CCG グリッドに格納する。

CCGSubSurf は完全に CCGDerievdMesh によって使用可能になっており、さらに Blender のどのエリアも、新しいコード経路が使用されていることが判らないようになっています。

GPU での計算

GPU コード経路はもう少し複雑で、主にメモリをできるだけ少なく消費するようにしていることに起因します。

とはいえ、Subsurf モディファイアーが GPU コード経路で計算されている時、CCG ジオメトリは何も作成されず、ベースメッシュは直接 OpenSubdiv メッシュにエクスポートされます。この処理は一度行われる以外は、トポロジーが変更された時のみ起こります。実際にはこれがスタックの評価によって唯一確実に行われる物で、残りの魔法は描画中に起こります。

描画はいくつかのステップを経て行われます。

  • まず最初に、更新されたベース座標を計算デバイス上にアップロードする。
  • デバイスの同期とリファインが呼び出される。これにより、メッシュは描画の準備が整います。
この二つのステップはスタック評価中には行うことができません。これらはスレッドからは起こりえない OpenGL バッファーによる操作だからです。
  • 描画がパッチ上で発生し、glDrawElement が最小限の回数で呼ばれる。

コードレイアウト

OpenSubdiv プロジェクトがタッチする主なエリアは3つあります。

  • intern/opensubdiv には、OpenSubdiv ライブラリといくつかのユーティリティを結ぶ、 C-API によるバインディングがあります。また、パッチ描画コードも十分な量含まれています。
  • source/blender/blenkernel/intern/CCGSubSurf* には旧 CCG (Catmull-Clark Grids) を作成するすべてのコードと、新しい OpenSubdiv サブディビジョンコードが同居しています。可能な限り多くのコードを共用していますが、新旧のコード経路を綺麗に分割することもできます。
  • source/blender/blenkernel/intern/subsurf_ccg* には OpenSubdiv の描画の対応に必要な、CCGDerivedMesh の改造版が含まれています。
  • source/blender/gpu ジオメトリシェーダーと face-varying アトリビュートへの対応に必要な変更が含まれています。

コードの残りの領域はソース内を WITH_OPENSUBDIV で検索することで簡単に探し出すことができます。

OpenSubdiv でのビルド

Windows

Windows プラットフォームにはコンパイル済みライブラリがあり、SCons と CMake の両方で OpenSubdiv がデフォルトで有効になっています。これは OpenSubdiv による Blender のビルドは、単に lib フォルダーを更新しておく必要があること以外に何も特別な物は必要ないということです。

Linux

Linux 上の OpenSubdiv は最新の OpenSubdiv branchから手動でコンパイル可能です。下記がそのブランチのURLです。

 https://github.com/PixarAnimationStudios/OpenSubdiv/tree/dev

SCons または CMake の OpenSubdiv に関連するすべてのオプションに適切な値を確実に設定した後、OpenSubdiv を有効にし、通常どおり blender をビルドしてください。

TODO

このプロジェクトは実際にはまだ完成しておらず、既知のやるべきことがいくつかあります。

  • 生成座標の対応
  • UV マップの対応
  • OpenSubdiv へのトポロジーのエクスポートの改善(現在、vert-edge と vert-face の方向が失われている可能性があり、壊れているようです)
  • OpenSubdiv メッシュ構造上のパフォーマンスにも改善の余地があります
  • また、トポロジー変更の探知のパフォーマンスも改善可能です
  • スナップや AABB 計算、その他モディファイアースタック評価後に呼ばれる可能性のあるツールへの対応
  • 分離した辺と頂点の対応
  • CUDA と OpenCL によるバックエンド処理対応
  • OSX 対応
  • 辺の Auto Split(自動分割)の対応
  • Custom Normals(カスタム法線)対応