in unity/Assets/PostProcessingV2/Runtime/PostProcessLayer.cs [306:432]
void BuildCommandBuffers()
{
var context = m_CurrentContext;
var sourceFormat = m_Camera.allowHDR ? RenderTextureFormat.DefaultHDR : RenderTextureFormat.Default;
context.Reset();
context.camera = m_Camera;
context.sourceFormat = sourceFormat;
// TODO: Investigate retaining command buffers on XR multi-pass right eye
m_LegacyCmdBufferBeforeReflections.Clear();
m_LegacyCmdBufferBeforeLighting.Clear();
m_LegacyCmdBufferOpaque.Clear();
m_LegacyCmdBuffer.Clear();
SetupContext(context);
context.command = m_LegacyCmdBufferOpaque;
UpdateSettingsIfNeeded(context);
// Lighting & opaque-only effects
var aoBundle = GetBundle<AmbientOcclusion>();
var aoSettings = aoBundle.CastSettings<AmbientOcclusion>();
var aoRenderer = aoBundle.CastRenderer<AmbientOcclusionRenderer>();
bool aoSupported = aoSettings.IsEnabledAndSupported(context);
bool aoAmbientOnly = aoRenderer.IsAmbientOnly(context);
bool isAmbientOcclusionDeferred = aoSupported && aoAmbientOnly;
bool isAmbientOcclusionOpaque = aoSupported && !aoAmbientOnly;
var ssrBundle = GetBundle<ScreenSpaceReflections>();
var ssrSettings = ssrBundle.settings;
var ssrRenderer = ssrBundle.renderer;
bool isScreenSpaceReflectionsActive = ssrSettings.IsEnabledAndSupported(context);
// Ambient-only AO is a special case and has to be done in separate command buffers
if (isAmbientOcclusionDeferred)
{
var ao = aoRenderer.Get();
// Render as soon as possible - should be done async in SRPs when available
context.command = m_LegacyCmdBufferBeforeReflections;
ao.RenderAmbientOnly(context);
// Composite with GBuffer right before the lighting pass
context.command = m_LegacyCmdBufferBeforeLighting;
ao.CompositeAmbientOnly(context);
}
else if (isAmbientOcclusionOpaque)
{
context.command = m_LegacyCmdBufferOpaque;
aoRenderer.Get().RenderAfterOpaque(context);
}
bool isFogActive = fog.IsEnabledAndSupported(context);
bool hasCustomOpaqueOnlyEffects = HasOpaqueOnlyEffects(context);
int opaqueOnlyEffects = 0;
opaqueOnlyEffects += isScreenSpaceReflectionsActive ? 1 : 0;
opaqueOnlyEffects += isFogActive ? 1 : 0;
opaqueOnlyEffects += hasCustomOpaqueOnlyEffects ? 1 : 0;
// This works on right eye because it is resolved/populated at runtime
var cameraTarget = new RenderTargetIdentifier(BuiltinRenderTextureType.CameraTarget);
if (opaqueOnlyEffects > 0)
{
var cmd = m_LegacyCmdBufferOpaque;
context.command = cmd;
// We need to use the internal Blit method to copy the camera target or it'll fail
// on tiled GPU as it won't be able to resolve
int tempTarget0 = m_TargetPool.Get();
context.GetScreenSpaceTemporaryRT(cmd, tempTarget0, 24, sourceFormat);
cmd.Blit(cameraTarget, tempTarget0);
context.source = tempTarget0;
int tempTarget1 = -1;
if (opaqueOnlyEffects > 1)
{
tempTarget1 = m_TargetPool.Get();
context.GetScreenSpaceTemporaryRT(cmd, tempTarget1, 24, sourceFormat);
context.destination = tempTarget1;
}
else context.destination = cameraTarget;
if (isScreenSpaceReflectionsActive)
{
ssrRenderer.Render(context);
opaqueOnlyEffects--;
var prevSource = context.source;
context.source = context.destination;
context.destination = opaqueOnlyEffects == 1 ? cameraTarget : prevSource;
}
if (isFogActive)
{
fog.Render(context);
opaqueOnlyEffects--;
var prevSource = context.source;
context.source = context.destination;
context.destination = opaqueOnlyEffects == 1 ? cameraTarget : prevSource;
}
if (hasCustomOpaqueOnlyEffects)
RenderOpaqueOnly(context);
if (opaqueOnlyEffects > 1)
cmd.ReleaseTemporaryRT(tempTarget1);
cmd.ReleaseTemporaryRT(tempTarget0);
}
// Post-transparency stack
// Same as before, first blit needs to use the builtin Blit command to properly handle
// tiled GPUs
int tempRt = m_TargetPool.Get();
context.GetScreenSpaceTemporaryRT(m_LegacyCmdBuffer, tempRt, 24, sourceFormat, RenderTextureReadWrite.sRGB);
m_LegacyCmdBuffer.Blit(cameraTarget, tempRt, RuntimeUtilities.copyStdMaterial, stopNaNPropagation ? 1 : 0);
m_NaNKilled = stopNaNPropagation;
context.command = m_LegacyCmdBuffer;
context.source = tempRt;
context.destination = cameraTarget;
Render(context);
m_LegacyCmdBuffer.ReleaseTemporaryRT(tempRt);
}