This is the documentation for Enlighten.

7.8. 低レベル プリコンピュート API


低レベル プリコンピュート API は、EnlightenPrecomp2 ライブラリにより実装されます。

低レベル プリコンピュート API は、High Level Build Systemでサポートされていない形で Enlighten プリコンピュートを実行したい場合に必要になることがあります。通常の Enlighten のインテグレートでは、低レベル プリコンピュート API を使用する必要はありません。

ほとんどのプリコンピュート タスクは Iprecompute インターフェイスを使用して実施されます。これは、スタンドアロンの CreatePrecompute() 関数を使用して作成されます。その後、ライセンス情報 (SetLicense() を使用) と以下のいくつかのオプションのグローバル プリコンピュート設定により、このインターフェイスをセットアップする必要があります。

キー

システム割り当て

プリコンピュートを開始する前に、ジオメトリをシステムに割り当て、システム依存関係を定義する必要があります。 

低レベル プリコンピュート API は、ユーティリティ関数 GroupInstancesIntoSystems を提供し、多数のインスタンス コレクションをいくつかの類似サイズのシステムに分割します。各システムには、適切な数のラジオシティ ピクセルが含まれます。

システム依存関係

低レベル プリコンピュート API 関数 CalculateSystemDependencies は、既定のシステムの依存関係を計算します。この関数は、一連のパックされたシステム オブジェクトとの比較を行います。次に、システムを内部システムと外部システムの 2 つのカテゴリに分類します。

  • 内部システムとは、システム リストのシステムのうち、そのバウンディング ボックスが expansionDistance パラメーターにより拡大された既定のシステムのバウンディング ボックスと交差するすべてのものを指します。
  • 外部システムは、システム配列の残りのシステムすべてです。

次に、内部システムと外部システムの可視性が計算されます。すべてのシステムは、システムの可視性と最小距離データとともに IPrecompSystemDependencies オブジェクトに追加されます。その後、このデータは、最小依存関係セットを作成するために使用できます。例として、GeoRadiosityはスライダーを使用して可視性カットオフを変化させ、この数値を変更することによるシステム依存関係への影響を示します。

可視性データは次のように生成されます。既定のシステムのジオメトリとすべての内部システムを組み合わせると、レイ トレーシングによるワールドの表現になります。すべての外部システムはバウンディング ボックスにより表現され、レイ トレーシングによるワールドには含まれません。レイ オリジンはシステムのサーフェスに均一に生成され、その密度は rayOriginsPerPixelArea パラメーターで指定されます。各レイ オリジンは、多数の光線を生成するために使用され、光線はその後、ワールドでトレースされます。

内部システムの可視性は、投射された光線とそのシステムに届いた光線 (すべてのレイ オリジンのうち) の最大の比率として計算されます。

外部システム配列のシステムはレイ トレーシングされるワールドに含まれないため、可視性は投射された光線と (1) レイ トレーシングされるワールドと交差しない光線および (2) 外部システムのバウンディング ボックスがレイ トレーシングされるワールドに存在した場合に交差する光線の (すべてのレイ オリジンのうちの) 最大の比率として計算されます。

外部システムのジオメトリはレイ トレーシングされるワールドの対象にならないため、完全にロードする必要はなく、ヘッダー ロードのみが必要とされます。これによってトレース対象のジオメトリが減るため、メモリを節約でき、レイ トレーシングのパフォーマンスが向上します。expansionDistance のデフォルト値は 0 に設定されています。これは、すべてのシステムが完全にレイ トレーシングで表現されていることを意味します (外部システムのリストは空です)。

プローブ セットの依存関係

低レベル プリコンピュート API 関数 CalculateProbeSetSystemDependencies は、既定のプローブ セットの依存関係を計算します。これは以下を除き、上記の CalculateSystemDependencies 関数と同じように機能します。

  1. expansionDistance により拡張されたプローブ セットのバウンディング ボックスは、対象のシステムを内部システムと外部システムに分類するために使用されます。
  2. 可視光線を生成するために使用されるレイ オリジンは、プローブ位置ごとに 1 つ配置されます。
キューブマップの依存関係

低レベル プリコンピュート API 関数 CalculateCubeMapSystemDependencies は、既定のキューブマップの依存関係を計算します。これは以下を除き、上記の CalculateSystemDependencies 関数と同じように機能します。

  1. 対象システムを内部システムと外部システムに分類するために使用されるキューブマップのバウンディング ボックスは、キューブマップの中心に位置するバウンディング ボックスとして定義され、expansionDistance で全方向に拡張します。
  2. キューブマップの中心にある 1 つのレイ オリジンのみが可視性チェックに使用されます。
  3. 可視光線の投射では、バック フェースに達してもすべて無視されます。光線はバック フェースに達したなかったものとして進みます。これは、閉じられたジオメトリに配置されたキューブマップに依存関係がないことを避けるためです。
距離に基づきシステム依存関係を推定する

システムの依存関係を推定するための代わりとなる API 関数があります。CalculateSystemDependenciesByDistance 関数は、距離のしきい値を使用して IPrecompInputSystem オブジェクトの入力配列内のシステム依存関係を計算します。この手法では、システム A のバウンディング ボックスの中心とシステム B のバウンディングボックスの中心の距離が、maxDistanceInPixelSizeUnits とシステム B の pixelSize の積以下だった場合、システム A はシステム B に依存しています。この関数では、入力システムのバウンディング ボックスを計算するために、入力システムのリストで参照されているすべての IPrecompInputGeometry オブジェクトの配列が必要です。

この関数は、レイ キャスティングを行わないため、CalculateSystemDependencies 関数よりも処理が速くなります。しかし、結果の依存関係の精度は落ちます。

依存関係の報告

プリコンピュートは、Clustering ステージと LightTransport ステージの最中、余分な内部システムの依存関係を特定しようとします。

  • Clustering ステージでは、余分である可能性が高い依存関係が検出され、そのような依存関係ごとに警告が出されます。さらに、対象システムの依存関係のリストが IPrecompSystemClustering インターフェイスに格納されます。指定の依存関係の基準として使用される可視性テストは近似であるため、Clustering ステージで誤検知が発生する可能性があることに注意してください。特に大規模なリーフ クラスタがあるシーンで発生する可能性があります。従って、除去される依存関係が多くなりすぎる可能性があるため、この情報は慎重に扱うことをお勧めします。
  • LightTransport ステージでは、実行時に実際には使用されない余分なシステム依存関係を追加で報告します。このような依存関係について警告が出され、実際の依存関係のリストは ILightTransportOutput インターフェイスに格納されます。Clustering ステージとは異なり、LightTransport ステージで作成されるシステム依存関係は正確なものです。プリコンピュートに ILightTransportOutput の作成を命令する方法の詳細は、プリコンピュートのデバッグをご覧ください。

検出された依存関係は、作成された依存関係のサブセットであるため、そのステージでは作成中に明示的に除去された依存関係を報告することはできません。また、これによって依存関係を作成する必要性がなくなるわけではありません。大規模なシーンでは、作成された依存関係がないと PreclusteringClustering ステージが非常に低速になります。

プリコンピュート パラメーターの構成

プリコンピュート パラメーターは、以下のオブジェクトを介して構成できます。

検証

ValidateBuildParameters 関数は、内部一貫性と、ランタイムの制限の超過についてビルド パラメーターをチェックします。現在のチェックには以下が含まれます。

  • クラスタ数 < システムあたり 2^31
  • 出力ピクセル数 < システムあたり 256K

この目的は、不適切なパラメーターの選択によるプリコンピュートの暴走を防ぐことです。検証には、IPrecompInputSystemIPrecompInputGeometry オブジェクトのみが必要であるため、他の時間がかかるタスクを実施する前に実行できます。

システムの処理

プリコンピュートの最初のステージは以下のとおりです。

  1. メッシュ データを Enlighten IPrecompInputGeometry クラスのインスタンスにロードします。
  2. 必要な各ランタイム システム向けに IPrecompInputSystem を作成します。
  3. そのシステムの以前のジオメトリの各インスタンスに対して PrecompInputInstance を作成し、システムに追加します。
  4. すべての IPrecompInputGeometry を 1 度パッキングする必要があります。
  5. システムのすべてのジオメトリの準備ができたら、システムをパッキングできます。

前のステージの出力は、後のステージで変更されることがないため、これらのステージのほとんどは (IncrediBuild などの全体に分配されるビルド システムを介して) 並行して実行できます。

以下の図は、1 つの IPrecompPackedSystem の作成を示しています。複数のシステムがある場合、それぞれをパッキングする必要があります。異なる場所/向きの同じメッシュを使用する場合、同じ IPrecompPackedGeometry オブジェクトを共有することができます。


ラジオシティの処理

  1. システム依存関係を決定した後、これらのシステムを IPrecompute::CreatePreClustering 関数に渡し、その次に IPrecompute::CreateClustering 関数に渡します。出力データは、ラジオシティと球面調和関数の両方の生成に使用されます。
  2. ラジオシティを処理するには、これらのシステム (およびそのクラスタ データ) を IPrecompute::CreateLightTransport 関数に渡します。このタスクでは、ライト トランスポートが出力されます。
  3. ライト トランスポートはプラットフォームごとのランタイム データ、IPrecompSystemRadiosity クラスの RadSystemCore を生成するために IPrecompute::CompileRadiosity に渡されます。

以下の図は、 2 つの IPrecompPackedSystem を持つシーンを示しています。この内容は増減する場合があります。

プリクラスタリングとクラスタリングに渡される一連のシステムが、ライト トランスポートに渡されるものと同じものであることを確認する必要があります。ライトは、(プレ) クラスタリングとライト トランスポート ステージの両方に渡されたシステムの間のみを移動します。独自のビルド パイプラインを実装している場合、CompressLightTransport により作成されたオブジェクトはプリコンピュートの結果として格納でき、CompileRadiosity の後のステージは必要なプラットフォームがわかっている場合にのみ実行されます。

ワークスペースの作成

次のステップでは、プリコンピュート データからランタイム ワークスペースを作成します。

中間オブジェクトをランタイム形式にデータを圧縮するだけで済むため、すべて迅速に処理されます。InputWorkspaceAlbedoWorkspace は再配置可能なオブジェクトであるため、必要に応じてメモリ内外へのストリーミングが可能です。

エンディアン変換のために EnlightenUtils に関数が提供されています。

プローブ セットの処理

(オプションの) プローブ セットの処理は、IPrecompSystemClustering が利用可能になると開始できます (従って、ラジオシティ計算と平行して実行できます)。ラジオシティの生成で使用したものと同じ一連のクラスタを IPrecompute::CreateProbeSet 関数に渡します。次に、IPrecompOutputProbeSetIPrecompProbeSetRadiosity 出力を生成する IPrecompute::CompileProbeSet に渡されます。最終的に、IPrecompProbeSetRadiosity にランタイムに渡すことができる RadDataBlock が含まれます。

オクトリーで Adaptive Probe 配置を使用するには、 (以下の画像で破線の表示されている) 追加のステージが必要です。IPrecompute::CreateOutputProbeOctree を使用して、IPrecompInputProbeOctreeIPrecompOutputProbeOctree に変換します。次に、IPrecompInputProbeSet::SetOctreeProbePositions 関数を使用すると、残りのプローブ セット パイプラインの入力の設定ができるようになります。

キューブマップの処理

キューブマップの処理は、プローブ セットと同じパイプライン構造に従います。プローブ セットと同様に、キューブマップの処理は、IPrecompSystemClustering が利用可能になると開始でき、他のプリコンピュート計算と平行して行えます。プローブ セットとキューブマップに対するインターフェイス オブジェクトとプリコンピュート関数の対応関係は以下のとおりです。

プローブ セット アイテム

キューブマップ アイテム

説明

IPrecompInputProbeSet

IPrecompInputCubeMap

プリコンピュートしたいアイテムを説明するオブジェクト

IPrecompOutputProbeSet

IPrecompOutputCubeMap

プリコンピュートの結果を説明するオブジェクトですが、ランタイム形式ではありません

IPrecompProbeSetRadiosity

IPrecompCubeMapCore

ソルバー固有のランタイム データ関連のラッパー オブジェクト


IPrecompDepthCubeMap

キューブマップの深度データ関連のラッパー オブジェクト (ランタイム形式ではありません)

CreateProbeSet(...)

CreateCubeMap(...)

プリコンピュートを実行します

CompileProbeSet(...)

CompileCubeMap(...)

プリコンピュート出力をソルバー固有のバージョンにコンパイルします


CompileDepthCubeMap(...)

カスタム処理のためにプリコンピュート出力から深度データを抽出します

メッセージ報告およびエラー処理

低レベル プリコンピュート API の使用時に問題が発生した場合は、GeoAttachSystemLogger/GeoAttachLogger 関数を呼び出してエラーおよび警告メッセージを発行します。

また、IGeoProgressProxy クラスを実装して、ReportError() 経由で報告されるエラー情報を処理することもできます。これらのエラー情報には、エラー コード、重大度、テキスト メッセージ、そのエラーに関する追加情報を含むペイロードが含まれます。ReportError の実装の簡単な例を次に示します。

void MyProgressProxy::ReportError(const PrecompError& error)
{
    if (error.m_Code == 2106) //警告 PE2106 は無視します
    {
        return;
    }
    else if (error.m_Code == 2001) //PE2001 から具体的な情報を抽出し、問題のシステムをハイライトします
    {
        Enlighten::Errors::PE2001* payload = static_cast<Enlighten::Errors::PE2001*>(error.m_Payload);
        GeoGuid systemGuid = payload->m_SystemGuid;
        HighlightSystemInError(systemGuid);
    }
 
    //エラー メッセージをコンソールに表示します
    switch(error.m_Severity)
    {
    case ES_FATAL:
        printf("\nError %i: %s\n", error.m_Code, error.m_Message.ToUtf8().GetCString());
        break;
    case ES_WARNING:
        printf("\nWarning %i: %s\n", error.m_Code, error.m_Message.ToUtf8().GetCString());
        break;
    }
}

また、単にエラーをコンソールに表示する、既定の TxtProgressBar の実装を使用することもできます。エラーおよび進捗情報を取得するための呼び出しの場合、このオブジェクトをプリコンピュート関数に渡す必要があります。この方法でプリコンピュートから報告できるエラーの詳細については、EnlightenPrecomp2/Errors のヘッダー ファイルをご覧ください。

プリコンピュートから想定されるエラーをすべて把握するには、GeoAttachSystemLogger/GeoAttachLogger の両方と IGeoProgressProxy の実装を使用することをお勧めします。その他の情報については、メッセージ報告およびエラー処理に関する API ドキュメントをご覧ください。

GeoRadiosity を使用したデバッグ

GeoRadiosity は、High Level Build System の入力として使用できるファイルをロードできます。GeoRadiosity では独自のレンダラーを使用してシーンが表示されるため、実行時のインテグレートの問題がエラーの原因となることを防ぐことができ、デバッグに役立ちます。さらに、設定の問題を特定できるデバッグ表示モードも提供されます。低レベル API を使用する際、ディスクにファイルが書き込まれないため、GeoRadiosity をそのまま使用することはできません。

High Level Build System の使用時と同じ機能を利用できるようにするため、GeoRadiosity には Extract from cacheコマンドが含まれています。プリコンピュートへのすべての入力ファイルをシリアル化し 1 つのフォルダに格納すると、GeoRadiosity ではシーンを再作成し、High level Build System を使用するための入力ファイルを作成できるため、 GeoRadiosity も作成できます。

Enlighten シーンの問題を迅速に再現してデバッグするために、Enlighten サポートにお問い合わせいただく際はこれらのプリコンピュート入力ファイルを提供してください。