※本記事は Unity2021.1.16f1 を元に記載しています
一つ前の記事
で、
ScriptableRenderPass.Configure() は ScriptableRenderer.InternalStartRendering() と ScriptableRenderer.InternalFinishRendering() の間で、RenderPassBlock分連なっている
と書いたのですが、では「RenderPassBlockとは何ぞや?」という事も書いておきます
RenderPassBlockは4つ
連なると書きはしましたが、RenderPassBlockは実は4つしかなく
static class RenderPassBlock
{
// Executes render passes that are inputs to the main rendering
// but don't depend on camera state. They all render in monoscopic mode. f.ex, shadow maps.
public static readonly int BeforeRendering = 0;
// Main bulk of render pass execution. They required camera state to be properly set
// and when enabled they will render in stereo.
public static readonly int MainRenderingOpaque = 1;
public static readonly int MainRenderingTransparent = 2;
// Execute after Post-processing.
public static readonly int AfterRendering = 3;
}
- 描画前
- 不透明描画
- 半透明描画
- 描画後
の4つだけです。シンプル。
RenderPassをAddする際に指定したRenderPassEventを、この4つの大カテゴリに応じて振り分けて、ブロック毎にExecute()しているわけです。
RenderPassEventの大別
各RenderPassEventが何処に所属しているかはRenderPassBlockのコードを見ると確認出来ます。
m_BlockEventLimits[RenderPassBlock.BeforeRendering] = RenderPassEvent.BeforeRenderingPrePasses;
m_BlockEventLimits[RenderPassBlock.MainRenderingOpaque] = RenderPassEvent.AfterRenderingOpaques;
m_BlockEventLimits[RenderPassBlock.MainRenderingTransparent] = RenderPassEvent.AfterRenderingPostProcessing;
m_BlockEventLimits[RenderPassBlock.AfterRendering] = (RenderPassEvent)Int32.MaxValue;
振り分けの条件式を見るに
while (currRenderPass < activeRenderPassQueue.Count && activeRenderPassQueue[currRenderPass].renderPassEvent < m_BlockEventLimits[i])
currRenderPass++;
「 < m_BlockEventLimits[i]」含まずなので
- RenderPassBlock.BeforeRendering
- RenderPassEvent.BeforeRendering
- RenderPassEvent.BeforeRenderingShadows
- RenderPassEvent.AfterRenderingShadows
- RenderPassBlock.MainRenderingOpaque
- RenderPassEvent.BeforeRenderingPrePasses
- RenderPassEvent.AfterRenderingPrePasses
- RenderPassEvent.BeforeRenderingOpaques
- RenderPassBlock.MainRenderingTransparent
- RenderPassEvent.AfterRenderingOpaques
- RenderPassEvent.BeforeRenderingSkybox
- RenderPassEvent.AfterRenderingSkybox
- RenderPassEvent.BeforeRenderingTransparents
- RenderPassEvent.AfterRenderingTransparents
- RenderPassEvent.BeforeRenderingPostProcessing
- RenderPassBlock.AfterRendering
- RenderPassEvent.AfterRenderingPostProcessing
- RenderPassEvent.AfterRendering
- それ以降
となります。
ForwardRendererではどうなる?
よって、普通にForwardRendererで描画した場合は、下記のような大別でPassが振り分けられています
- RenderPassBlock.BeforeRendering
- MainLightShadowCasterPass ← RenderPassEvent.BeforeRenderingShadows
- RenderPassBlock.MainRenderingOpaque
- ColorGradingLutPass ← RenderPassEvent.BeforeRenderingPrePasses
- DepthOnlyPass ← RenderPassEvent.BeforeRenderingPrePasses
- DrawObjectsPass ← m_RenderOpaqueForwardPassについてはRenderPassEvent.BeforeRenderingOpaques
- RenderPassBlock.MainRenderingTransparent
- CopyDepthPass ← RenderPassEvent.AfterRenderingSkybox
- CopyColorPass ← RenderPassEvent.AfterRenderingSkybox
- DrawObjectsPass ← m_RenderTransparentForwardPassについてはRenderPassEvent.BeforeRenderingTransparents
- InvokeOnRenderObjectCallbackPass ← RenderPassEvent.BeforeRenderingPostProcessing
- PostProcessPass ← RenderPassEvent.BeforeRenderingPostProcessing (FinalPostProcessPassはAfterRendering。詳しくはPostProcessingPassesを参照)
- RenderPassBlock.AfterRendering
- FinalBlitPass ← RenderPassEvent.AfterRendering + 1
- SceneViewCopyDepthPass ← RenderPassEvent.AfterRendering + 9
FrameDebuggerで見た時のお馴染みの順番ですね。
注意点としては↑はあくまでRenderPassEventを元にリストアップしただけなので、 必ず描画の度に↑のPassが全て実行されるわけではありません。
PostProcessの有効無効やCameraStackの有無、そしてCameraStackのどの位置のカメラを描画しているか、Depthはクリアするかしないかなどで各Passの有無は変わります。
※FinalBlitPassはCameraStackの最後のカメラのAfterRenderingでしか実行されない、など。
ご自身のカスタムPassを、どのタイミングで呼び出したいかの指標になれば幸いです。