ShaderTips

シェーダーTips

主にUnityシェーダーについての記事を書いています。

LoadAction と StoreAction の最適化について

Unity で用いられる RenderBufferLoadAction/RenderBufferStoreAction(以下、LoadAction/StoreAction と記述します)の動作と、不要なデータ転送を避けるための最適化手法について解説します。


LoadAction(読み込み時の動作)

描画処理を始めるときに、既存のバッファ内容をどのように扱うかを定義します。

説明
Load 既存のバッファ内容を読み込んで使用する。
例:前のフレームやパスの結果を利用したい場合。
DontCare バッファ内容を無視する。
例:上書き前提の描画など、前の内容を利用しない場合。
Clear ※一部のAPIのみ。描画前にバッファを明示的にクリア(初期化)する。
Unityでは CommandBuffer.ClearRenderTarget 等で代用可能。

StoreAction(描画後の保存動作)

描画処理が終わったあとに、バッファ内容をどのように扱うか(保存するかどうか)を定義します。

説明
Store 描画結果をそのまま保存する。
例:次のパスや最終出力で使用する場合。
DontCare 描画結果の保存が不要。
例:中間パスや一時バッファの場合、保存コストを削減するために使用。

LoadAction / StoreAction の使い分け例

シーン LoadAction StoreAction 説明
最初のカメラ描画パス(全画面上書き) DontCare Store 前の内容は不要。描いた内容は最終出力に必要。
Additive系のブレンディングパス Load Store 前の内容を引き継ぎながら加算描画を行う。
シャドウマップ用の一時的な深度バッファ DontCare DontCare 毎フレーム再構築されるため、読み書きの必要がない。
一部だけ描画するマスク合成パス Load Store 未描画領域は前の内容を残す必要がある場合に使用。
最終出力の後処理エフェクト(PostProcess) Load Store 前の描画結果を利用して処理し、そのまま保存。
一時バッファへの出力で使い捨ての場合 DontCare DontCare 中間処理用なので、保存も読み込みも不要。

LoadAction と StoreAction による最適化

Load を使用すると、前のバッファ内容を読み込むため、メインメモリからグラフィックスメモリへのデータ転送が発生します。これにより、必要なデータが高速なグラフィックスメモリで利用可能になります。一方、Store を使用すると、描画結果がグラフィックスメモリからメインメモリに書き戻され、次の描画パスやフレームで再利用できるように保存されます。

これらの操作が頻繁に行われると、メインメモリとグラフィックスメモリ間でのデータ転送が増え、メモリ帯域幅の消費や遅延がパフォーマンス低下を引き起こす可能性があります。
したがって、描画処理において前のデータが不要な場合や、中間処理結果を次回利用しない場合は、DontCare を活用して不要な Load や Store 操作を回避することが有効です。これにより、GPU のメモリ帯域が効率的に使用され、全体のパフォーマンスが向上します。

メインメモリとグラフィックスメモリの簡単な説明

  • メインメモリ
    GPU(またはCPU)の外部にある大容量のメモリ。
    容量は大きいが、アクセス速度はグラフィックスメモリに比べて遅い。

  • グラフィックスメモリ
    GPU内部に搭載された高速なメモリ。
    キャッシュや一時バッファとして利用され、処理中のデータアクセスを高速化する。
    容量はメインメモリに比べて小さい。