Skip to content

Commit 86e4116

Browse files
[HDRP][Compositor] Fix camera stacking for AOVs in the graphics compositor (#1912)
* Fix camera stacking for AOVs in the graphics compositor * Fix null reference exception when closing the compositor window * RenderGraph implementation for AOV stacking and misc improvements * Update HDRenderPipelineResources.asset Co-authored-by: sebastienlagarde <[email protected]>
1 parent 513d609 commit 86e4116

File tree

12 files changed

+210
-5
lines changed

12 files changed

+210
-5
lines changed

com.unity.render-pipelines.high-definition/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
132132
- Fixed an inconsistency in the LOD group UI where LOD bias was not the right one.
133133
- Fixed outlines in transitions between post-processed and plain regions in the graphics compositor (case 1278775).
134134
- Fix decal being applied twice with LOD Crossfade.
135+
- Fixed camera stacking for AOVs in the graphics compositor (case 1273223).
135136

136137
### Changed
137138
- Preparation pass for RTSSShadows to be supported by render graph.

com.unity.render-pipelines.high-definition/Editor/Compositor/CompositorWindow.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,12 +190,17 @@ private void OnDestroy()
190190
GraphData.onSaveGraph -= MarkShaderAsDirty;
191191

192192
Undo.undoRedoPerformed -= UndoCallback;
193-
s_SelectionIndex = m_Editor.selectionIndex;
193+
s_SelectionIndex = m_Editor ? m_Editor.selectionIndex : -1;
194194
}
195195

196196
void UndoCallback()
197197
{
198198
// Undo-redo might change the layer order, so we need to redraw the compositor UI and also refresh the layer setup
199+
if (!m_Editor)
200+
{
201+
return;
202+
}
203+
199204
m_Editor.CacheSerializedObjects();
200205
m_RequiresRedraw = true;
201206
s_SelectionIndex = m_Editor.selectionIndex;

com.unity.render-pipelines.high-definition/Runtime/Compositor/AdditionalCompositorData.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ internal enum BackgroundFitMode
1414
internal class AdditionalCompositorData : MonoBehaviour
1515
{
1616
public Texture clearColorTexture = null;
17+
public RenderTexture clearDepthTexture = null;
1718
public bool clearAlpha = true; // Clearing the alpha allows the post process to run only on the pixels covered by a stacked camera (and not the previous ones).
1819
public BackgroundFitMode imageFitMode = BackgroundFitMode.Stretch;
1920
public List<CompositionFilter> layerFilters;
@@ -29,6 +30,7 @@ public void Init(List<CompositionFilter> layerFilters, bool clearAlpha)
2930
public void ResetData()
3031
{
3132
clearColorTexture = null;
33+
clearDepthTexture = null;
3234
clearAlpha = true;
3335
imageFitMode = BackgroundFitMode.Stretch;
3436

com.unity.render-pipelines.high-definition/Runtime/Compositor/CompositionLayer.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -612,7 +612,7 @@ public void SetupLayerCamera(CompositorLayer targetLayer, int layerPositionInSta
612612
var cameraData = m_LayerCamera.GetComponent<HDAdditionalCameraData>();
613613
m_LayerCamera.targetTexture = targetLayer.GetRenderTarget(false);
614614

615-
if (targetLayer.m_AOVBitmask == 0)
615+
// Setup the custom clear pass for camera stacking
616616
{
617617
if (layerPositionInStack != 0)
618618
{
@@ -625,7 +625,8 @@ public void SetupLayerCamera(CompositorLayer targetLayer, int layerPositionInSta
625625
}
626626
if (m_Type != LayerType.Image)
627627
{
628-
compositorData.clearColorTexture = targetLayer.GetRenderTarget(false);
628+
compositorData.clearColorTexture = targetLayer.GetRenderTarget();
629+
compositorData.clearDepthTexture = targetLayer.m_RTHandle;
629630
}
630631
cameraData.volumeLayerMask |= 1 << 31;
631632
}
@@ -638,7 +639,7 @@ public void SetupLayerCamera(CompositorLayer targetLayer, int layerPositionInSta
638639

639640
// The target layer expects AOVs, so this stacked layer should also generate AOVs
640641
int aovMask = (1 << (int)targetLayer.m_AOVBitmask);
641-
if (aovMask > 1)
642+
if (m_Show && aovMask > 1)
642643
{
643644
var aovRequestBuilder = new AOVRequestBuilder();
644645

com.unity.render-pipelines.high-definition/Runtime/Compositor/CompositionManager.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -861,5 +861,39 @@ static public Vector4 GetAlphaScaleAndBiasForCamera(HDCamera hdCamera)
861861
return new Vector4(1.0f, 0.0f, 0.0f, 0.0f);
862862
}
863863

864+
/// <summary>
865+
/// For stacked cameras, returns the color buffer that will be used to draw on top
866+
/// </summary>
867+
/// <param name="hdCamera">The input camera</param>
868+
/// <returns> The color buffer that will be used to draw on top, or null if not a stacked camera </returns>
869+
static internal Texture GetClearTextureForStackedCamera(HDCamera hdCamera)
870+
{
871+
AdditionalCompositorData compositorData = null;
872+
hdCamera.camera.TryGetComponent<AdditionalCompositorData>(out compositorData);
873+
874+
if (compositorData)
875+
{
876+
return compositorData.clearColorTexture;
877+
}
878+
return null;
879+
}
880+
881+
/// <summary>
882+
/// For stacked cameras, returns the depth buffer that will be used to draw on top
883+
/// </summary>
884+
/// <param name="hdCamera">The input camera</param>
885+
/// <returns> The depth buffer that will be used to draw on top, or null if not a stacked camera </returns>
886+
static internal RenderTexture GetClearDepthForStackedCamera(HDCamera hdCamera)
887+
{
888+
AdditionalCompositorData compositorData = null;
889+
hdCamera.camera.TryGetComponent<AdditionalCompositorData>(out compositorData);
890+
891+
if (compositorData)
892+
{
893+
return compositorData.clearDepthTexture;
894+
}
895+
return null;
896+
}
897+
864898
}
865899
}

com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.Debug.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,11 +507,15 @@ class DebugViewMaterialData
507507
public RendererListHandle transparentRendererList;
508508
public Material debugGBufferMaterial;
509509
public FrameSettings frameSettings;
510+
511+
public Texture clearColorTexture;
512+
public RenderTexture clearDepthTexture;
510513
}
511514

512515
TextureHandle RenderDebugViewMaterial(RenderGraph renderGraph, CullingResults cull, HDCamera hdCamera)
513516
{
514517
bool msaa = hdCamera.frameSettings.IsEnabled(FrameSettingsField.MSAA);
518+
515519
var output = renderGraph.CreateTexture(
516520
new TextureDesc(Vector2.one, true, true)
517521
{
@@ -557,9 +561,19 @@ TextureHandle RenderDebugViewMaterial(RenderGraph renderGraph, CullingResults cu
557561
rendererConfiguration: m_CurrentRendererConfigurationBakedLighting,
558562
stateBlock: m_DepthStateOpaque)));
559563

564+
passData.clearColorTexture = Compositor.CompositionManager.GetClearTextureForStackedCamera(hdCamera); // returns null if is not a stacked camera
565+
passData.clearDepthTexture = Compositor.CompositionManager.GetClearDepthForStackedCamera(hdCamera); // returns null if is not a stacked camera
566+
560567
builder.SetRenderFunc(
561568
(DebugViewMaterialData data, RenderGraphContext context) =>
562569
{
570+
// If we are doing camera stacking, then we want to clear the debug color and depth buffer using the data from the previous camera on the stack
571+
// Note: Ideally here we would like to draw directly on the same buffers as the previous camera, but currently the compositor is not using
572+
// Texture Arrays so this would not work. We might need to revise this in the future.
573+
if (data.clearColorTexture != null)
574+
{
575+
HDUtils.BlitColorAndDepth(context.cmd, data.clearColorTexture, data.clearDepthTexture, new Vector4(1, 1, 0, 0), 0, !hdCamera.clearDepth);
576+
}
563577
DrawOpaqueRendererList(context, data.frameSettings, data.opaqueRendererList);
564578
DrawTransparentRendererList(context, data.frameSettings, data.transparentRendererList);
565579
});

com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ internal static Volume GetOrCreateDefaultVolume()
175175
Material m_Blit;
176176
Material m_BlitTexArray;
177177
Material m_BlitTexArraySingleSlice;
178+
Material m_BlitColorAndDepth;
178179
MaterialPropertyBlock m_BlitPropertyBlock = new MaterialPropertyBlock();
179180

180181
RenderTargetIdentifier[] m_MRTCache2 = new RenderTargetIdentifier[2];
@@ -327,6 +328,7 @@ internal int GetMaxScreenSpaceShadows()
327328
string m_ForwardPassProfileName;
328329

329330
internal Material GetBlitMaterial(bool useTexArray, bool singleSlice) { return useTexArray ? (singleSlice ? m_BlitTexArraySingleSlice : m_BlitTexArray) : m_Blit; }
331+
internal Material GetBlitColorAndDepthMaterial() { return m_BlitColorAndDepth; }
330332

331333
ComputeBuffer m_DepthPyramidMipLevelOffsetsBuffer = null;
332334

@@ -1088,6 +1090,7 @@ void InitializeDebugMaterials()
10881090
m_DebugColorPicker = CoreUtils.CreateEngineMaterial(defaultResources.shaders.debugColorPickerPS);
10891091
m_DebugExposure = CoreUtils.CreateEngineMaterial(defaultResources.shaders.debugExposurePS);
10901092
m_Blit = CoreUtils.CreateEngineMaterial(defaultResources.shaders.blitPS);
1093+
m_BlitColorAndDepth = CoreUtils.CreateEngineMaterial(defaultResources.shaders.blitColorAndDepthPS);
10911094
m_ErrorMaterial = CoreUtils.CreateEngineMaterial("Hidden/InternalErrorShader");
10921095

10931096
// With texture array enabled, we still need the normal blit version for other systems like atlas
@@ -4080,8 +4083,16 @@ void RenderDebugViewMaterial(CullingResults cull, HDCamera hdCamera, ScriptableR
40804083
{
40814084
// When rendering debug material we shouldn't rely on a depth prepass for optimizing the alpha clip test. As it is control on the material inspector side
40824085
// we must override the state here.
4083-
40844086
CoreUtils.SetRenderTarget(cmd, m_CameraColorBuffer, m_SharedRTManager.GetDepthStencilBuffer(), ClearFlag.All, Color.clear);
4087+
4088+
// [case 1273223] When the camera is stacked on top of another one, we need to clear the debug view RT using the data from the previous camera in the stack
4089+
var clearColorTexture = Compositor.CompositionManager.GetClearTextureForStackedCamera(hdCamera); // returns null if is not a stacked camera
4090+
var clearDepthTexture = Compositor.CompositionManager.GetClearDepthForStackedCamera(hdCamera); // returns null if is not a stacked camera
4091+
if (clearColorTexture)
4092+
{
4093+
HDUtils.BlitColorAndDepth(cmd, clearColorTexture, clearDepthTexture, new Vector4(1, 1, 0, 0), 0, !hdCamera.clearDepth);
4094+
}
4095+
40854096
// Render Opaque forward
40864097
var rendererListOpaque = RendererList.Create(CreateOpaqueRendererListDesc(cull, hdCamera.camera, m_AllForwardOpaquePassNames, m_CurrentRendererConfigurationBakedLighting, stateBlock: m_DepthStateOpaque));
40874098
DrawOpaqueRendererList(renderContext, cmd, hdCamera.frameSettings, rendererListOpaque);

com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPipelineResources.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ public sealed class ShaderResources
110110
public Shader copyDepthBufferPS;
111111
[Reload("Runtime/ShaderLibrary/Blit.shader")]
112112
public Shader blitPS;
113+
[Reload("Runtime/ShaderLibrary/BlitColorAndDepth.shader")]
114+
public Shader blitColorAndDepthPS;
113115

114116
[Reload("Runtime/ShaderLibrary/DownsampleDepth.shader")]
115117
public Shader downsampleDepthPS;

com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Utility/HDUtils.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,32 @@ public static void BlitTexture(CommandBuffer cmd, RTHandle source, Vector4 scale
307307
s_PropertyBlock.SetFloat(HDShaderIDs._BlitMipLevel, mipLevel);
308308
BlitTexture(cmd, source, scaleBias, GetBlitMaterial(TextureXR.dimension), bilinear ? 1 : 0);
309309
}
310+
311+
/// <summary>
312+
/// Blit a 2D texture and depth buffer.
313+
/// </summary>
314+
/// <param name="cmd">Command Buffer used for rendering.</param>
315+
/// <param name="sourceColor">Source Texture for color.</param>
316+
/// <param name="sourceDepth">Source RenderTexture for depth.</param>
317+
/// <param name="scaleBias">Scale and bias for sampling the input texture.</param>
318+
/// <param name="mipLevel">Mip level to blit.</param>
319+
/// <param name="bilinear">Enable bilinear filtering.</param>
320+
internal static void BlitColorAndDepth(CommandBuffer cmd, Texture sourceColor, RenderTexture sourceDepth, Vector4 scaleBias, float mipLevel, bool blitDepth)
321+
{
322+
HDRenderPipeline hdPipeline = RenderPipelineManager.currentPipeline as HDRenderPipeline;
323+
if (hdPipeline != null)
324+
{
325+
Material mat = hdPipeline.GetBlitColorAndDepthMaterial();
326+
327+
s_PropertyBlock.SetFloat(HDShaderIDs._BlitMipLevel, mipLevel);
328+
s_PropertyBlock.SetVector(HDShaderIDs._BlitScaleBias, scaleBias);
329+
s_PropertyBlock.SetTexture(HDShaderIDs._BlitTexture, sourceColor);
330+
if (blitDepth)
331+
s_PropertyBlock.SetTexture(HDShaderIDs._InputDepth, sourceDepth, RenderTextureSubElement.Depth);
332+
cmd.DrawProcedural(Matrix4x4.identity, mat, blitDepth ? 1 : 0, MeshTopology.Triangles, 3, 1, s_PropertyBlock);
333+
}
334+
}
335+
310336
/// <summary>
311337
/// Blit a RTHandle texture
312338
/// </summary>

com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/HDRenderPipelineResources.asset

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ MonoBehaviour:
8585
type: 3}
8686
copyDepthBufferPS: {fileID: 4800000, guid: 42dfcc8fe803ece4096c58630689982f, type: 3}
8787
blitPS: {fileID: 4800000, guid: 370f7a9cc4e362d488af024d371091e8, type: 3}
88+
blitColorAndDepthPS: {fileID: 4800000, guid: c6e57f5bdbd2a284a86a3097c03884c8,
89+
type: 3}
8890
downsampleDepthPS: {fileID: 4800000, guid: 67d6171b0acc6554aad48c845ec7e67f, type: 3}
8991
upsampleTransparentPS: {fileID: 4800000, guid: 2ad7ce40f0dbaf64dadef1f58d8524d3,
9092
type: 3}

0 commit comments

Comments
 (0)