/
7.1.1.4. 低レベル キューブマップ API

This is the documentation for Enlighten.

7.1.1.4. 低レベル キューブマップ API


概要

動的キューブマップ生成 API は Enlighten のその他のタスク ベースのシステムと同じパターンに従い、通常どおりアプリケーションが更新レートとシェーディングの使用を制御します。 

以下のセクションでは、▲低レベル キューブマップ ランタイム API▲ の使用方法の概要を説明します。

プリコンピュートされたキューブマップ データのロード

プリコンピュート データのロードで説明されているように、Utilities API を使用して実行時に RadCubeMapCore オブジェクトを作成できます。

RadCubeMap タスク構造体の準備

キューブマップ ソルバー API は、Enlighten System ソルバーとよく似ています。解決する対象のキューブマップが依存しているシステムごとに入力ライティング バッファのリストを 1 つ、正しい順序で渡す必要があります。以下のコード例に示すように、このリストを準備するために RadCubeMapCore をとる PrepareInputLightingList()GetInputWorkspaceListLength() 関数のバージョンがあります。

// タスク構造体を作成します
Enlighten::RadCubeMapTask cubeMapTask;
cubeMapTask.m_CoreCubeMap = radCubeMapCore; // プリコンピュートされた RadCubeMapCore 
 
// 入力ライティング バッファを正しく並べたリストをキューブマップが依存するシステムごとに 1 つずつ準備します
cubeMapTask.m_InputLighting = GEO_NEW_ARRAY(const Enlighten::InputLightingBuffer*, Enlighten::GetInputWorkspaceListLength(cubeMapTask.m_CoreCubeMap));
Enlighten::PrepareInputLightingList(cubeMapTask.m_CoreCubeMap, inputLightingBufferArray.GetArray(), inputLightingBufferArray.GetSize(), cubeMapTask.m_InputLighting);
 
cubeMapTask.m_Environment       = emissiveEnvironment;               // オプションのエミッシブ環境
cubeMapTask.m_OutputFormat      = Enlighten::ENLIGHTEN_FORMAT_FP16;  // 16 ビット浮動小数点ベクトルとしての出力値
cubeMapTask.m_OutputScale       = 1.0f;                              // 出力に対する追加のスケーリングなし
cubeMapTask.m_ComputeMipMaps    = true;                              // ミップチェーン全体を計算します 
 
for (s32 faceIdx = 0; faceIdx < 6; ++faceIdx)
{
    cubeMapTask.m_OutputTextures[faceIdx] = cubeMapOutputs[faceIdx];
}

エミッシブ環境 InputLightingBuffer がオプションであることに注意してください。環境クラスタは平滑化されていないため、最大品質の結果を出すには、これを NULL に設定し、GPU で skybox のような高解像度環境テクスチャと Enlighten キューブマップ出力を合成することをお勧めします。これは、Enlighten::ENLIGHTEN_FORMAT_FP16 出力形式を使用している場合に、キューブマップ ソルバーにより計算され、テクスチャのアルファ チャネルに格納されるアルファ マスクを使用して実現できます。他の出力形式ではアルファ チャネルを HDR エンコードに使用するため、このマスクは含まれていません。

キューブマップに Enlighten エミッシブ環境を使用していない場合、environmentResolutionキューブマップ プリコンピュート パラメーターを最小値の 1 に設定して、最適なメモリ使用率とパフォーマンスを実現します。

キューブマップの解決

RadCubeMapTask 構造体の準備が終わったら、ワーキング メモリのブロックとともに SolveCubeMapTask() に渡す必要があります。AllInputLightingStatic() ヘルパー関数を呼び出し、すべての入力ライティングが静的であることを確認して、不必要な解決を避けることができます。

Geo::u32 timeUs, Geo::u32 numPixelsSolved;
 
// 解決のためのワーキング メモリを見つけます
void* workingMemory = GEO_ALIGNED_MALLOC(Enlighten::CalcRequiredWorkspaceMemory(cubeMapTask->m_RadCubeMapCore), 16);
 
// すべての入力ライティングが静的である場合を除き、キューブマップを解決します
if(false == Enlighten::AllLightingInputsStatic(cubeMapTask.m_InputLighting, Enlighten::GetInputWorkspaceListLength(cubeMapTask.m_CoreCubeMap), cubeMapTask.m_Environment))
{
    bool solvedOk = Enlighten::SolveCubeMapTask(&cubeMapTask, workingMemory, timeUs, numPixelsSolved);
}

ラジオシティのみの出力の計算

ラジオシティのみの間接的なライティングを含む出力を計算する場合、キューブマップ ソルバーは InputLightingBuffers のリストではなく、BounceBuffers のリストから入力ライティングを読み取る必要があります。このタイプの出力を指定するには、RadCubeMapTask 構造体の m_RadiosityOnlyLighting メンバーを、キューブマップが依存する Enlighten のシステムごとに 1 つずつ、BounceBuffer オブジェクトへのポインターを正しく並べたリストに割り当てます。これらの BounceBuffers には、各システムのバウンスのリサンプリング ステージの実行結果が含まれます。

// バウンス バッファを正しく並べたリストを、キューブマップが依存するシステムごとに 1 つずつ準備しま
s32 numCubeMapDependencies = Enlighten::GetInputWorkspaceListLength(cubeMapTask.m_CoreCubeMap);
cubeMapTask.m_RadiosityOnlyLighting = GEO_NEW_ARRAY(const BounceBuffer*, numCubeMapDependencies);
 
for (s32 i = 0; i < numCubeMapDependencies; ++i)
{
    GeoGuid systemDepGuid = Enlighten::GetInputWorkspaceGUID(existingCubeMap->m_RadCubeMapCore, i);
    cubeMapTask.m_RadiosityOnlyLighting[i] = GetBounceBufferForSystem(systemDepGuid);
}
 
// 環境はラジオシティ ライティングを受けないため、InputLightingBuffer を NULL に設定します
cubeMapTask.m_Environment = NULL;
 
// GPU でラジオシティのみの出力が高周波アルベドと直接光と合成された後にこれがエンジンで実施される場合、ソルバーのミップマップの生成を無効にすることをお勧めします。
cubeMapTask.m_ComputeMipMaps = false;
 
// これまでと同じように、静的ライティングがないかシステムの InputLightingBuffers のリストをチェックし、通常どおり解決します
if(false == Enlighten::AllLightingInputsStatic(cubeMapTask.m_InputLighting, Enlighten::GetInputWorkspaceListLength(cubeMapTask.m_CoreCubeMap), cubeMapTask.m_Environment))
{
    bool solvedOk = Enlighten::SolveCubeMapTask(&cubeMapTask, workingMemory, timeUs, numPixelsSolved);
}

参照情報: