diff --git a/com.unity.render-pipelines.high-definition/CHANGELOG.md b/com.unity.render-pipelines.high-definition/CHANGELOG.md index 79107569998..4845040bccd 100644 --- a/com.unity.render-pipelines.high-definition/CHANGELOG.md +++ b/com.unity.render-pipelines.high-definition/CHANGELOG.md @@ -132,6 +132,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Fixed an inconsistency in the LOD group UI where LOD bias was not the right one. - Fixed outlines in transitions between post-processed and plain regions in the graphics compositor (case 1278775). - Fix decal being applied twice with LOD Crossfade. +- Fixed camera stacking for AOVs in the graphics compositor (case 1273223). ### Changed - Preparation pass for RTSSShadows to be supported by render graph. diff --git a/com.unity.render-pipelines.high-definition/Editor/Compositor/CompositorWindow.cs b/com.unity.render-pipelines.high-definition/Editor/Compositor/CompositorWindow.cs index b3611d288fd..95215eeaad0 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Compositor/CompositorWindow.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Compositor/CompositorWindow.cs @@ -190,12 +190,17 @@ private void OnDestroy() GraphData.onSaveGraph -= MarkShaderAsDirty; Undo.undoRedoPerformed -= UndoCallback; - s_SelectionIndex = m_Editor.selectionIndex; + s_SelectionIndex = m_Editor ? m_Editor.selectionIndex : -1; } void UndoCallback() { // Undo-redo might change the layer order, so we need to redraw the compositor UI and also refresh the layer setup + if (!m_Editor) + { + return; + } + m_Editor.CacheSerializedObjects(); m_RequiresRedraw = true; s_SelectionIndex = m_Editor.selectionIndex; diff --git a/com.unity.render-pipelines.high-definition/Runtime/Compositor/AdditionalCompositorData.cs b/com.unity.render-pipelines.high-definition/Runtime/Compositor/AdditionalCompositorData.cs index 4f72320ced8..cfc3a55dd23 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Compositor/AdditionalCompositorData.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Compositor/AdditionalCompositorData.cs @@ -14,6 +14,7 @@ internal enum BackgroundFitMode internal class AdditionalCompositorData : MonoBehaviour { public Texture clearColorTexture = null; + public RenderTexture clearDepthTexture = null; 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). public BackgroundFitMode imageFitMode = BackgroundFitMode.Stretch; public List layerFilters; @@ -29,6 +30,7 @@ public void Init(List layerFilters, bool clearAlpha) public void ResetData() { clearColorTexture = null; + clearDepthTexture = null; clearAlpha = true; imageFitMode = BackgroundFitMode.Stretch; diff --git a/com.unity.render-pipelines.high-definition/Runtime/Compositor/CompositionLayer.cs b/com.unity.render-pipelines.high-definition/Runtime/Compositor/CompositionLayer.cs index ad3e8fc6cc2..2ca6e1ffad2 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Compositor/CompositionLayer.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Compositor/CompositionLayer.cs @@ -612,7 +612,7 @@ public void SetupLayerCamera(CompositorLayer targetLayer, int layerPositionInSta var cameraData = m_LayerCamera.GetComponent(); m_LayerCamera.targetTexture = targetLayer.GetRenderTarget(false); - if (targetLayer.m_AOVBitmask == 0) + // Setup the custom clear pass for camera stacking { if (layerPositionInStack != 0) { @@ -625,7 +625,8 @@ public void SetupLayerCamera(CompositorLayer targetLayer, int layerPositionInSta } if (m_Type != LayerType.Image) { - compositorData.clearColorTexture = targetLayer.GetRenderTarget(false); + compositorData.clearColorTexture = targetLayer.GetRenderTarget(); + compositorData.clearDepthTexture = targetLayer.m_RTHandle; } cameraData.volumeLayerMask |= 1 << 31; } @@ -638,7 +639,7 @@ public void SetupLayerCamera(CompositorLayer targetLayer, int layerPositionInSta // The target layer expects AOVs, so this stacked layer should also generate AOVs int aovMask = (1 << (int)targetLayer.m_AOVBitmask); - if (aovMask > 1) + if (m_Show && aovMask > 1) { var aovRequestBuilder = new AOVRequestBuilder(); diff --git a/com.unity.render-pipelines.high-definition/Runtime/Compositor/CompositionManager.cs b/com.unity.render-pipelines.high-definition/Runtime/Compositor/CompositionManager.cs index ed8cbfe6098..34641d061a7 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Compositor/CompositionManager.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Compositor/CompositionManager.cs @@ -861,5 +861,39 @@ static public Vector4 GetAlphaScaleAndBiasForCamera(HDCamera hdCamera) return new Vector4(1.0f, 0.0f, 0.0f, 0.0f); } + /// + /// For stacked cameras, returns the color buffer that will be used to draw on top + /// + /// The input camera + /// The color buffer that will be used to draw on top, or null if not a stacked camera + static internal Texture GetClearTextureForStackedCamera(HDCamera hdCamera) + { + AdditionalCompositorData compositorData = null; + hdCamera.camera.TryGetComponent(out compositorData); + + if (compositorData) + { + return compositorData.clearColorTexture; + } + return null; + } + + /// + /// For stacked cameras, returns the depth buffer that will be used to draw on top + /// + /// The input camera + /// The depth buffer that will be used to draw on top, or null if not a stacked camera + static internal RenderTexture GetClearDepthForStackedCamera(HDCamera hdCamera) + { + AdditionalCompositorData compositorData = null; + hdCamera.camera.TryGetComponent(out compositorData); + + if (compositorData) + { + return compositorData.clearDepthTexture; + } + return null; + } + } } diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.Debug.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.Debug.cs index 6b237d1770a..4d0af913e9c 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.Debug.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.Debug.cs @@ -507,11 +507,15 @@ class DebugViewMaterialData public RendererListHandle transparentRendererList; public Material debugGBufferMaterial; public FrameSettings frameSettings; + + public Texture clearColorTexture; + public RenderTexture clearDepthTexture; } TextureHandle RenderDebugViewMaterial(RenderGraph renderGraph, CullingResults cull, HDCamera hdCamera) { bool msaa = hdCamera.frameSettings.IsEnabled(FrameSettingsField.MSAA); + var output = renderGraph.CreateTexture( new TextureDesc(Vector2.one, true, true) { @@ -557,9 +561,19 @@ TextureHandle RenderDebugViewMaterial(RenderGraph renderGraph, CullingResults cu rendererConfiguration: m_CurrentRendererConfigurationBakedLighting, stateBlock: m_DepthStateOpaque))); + passData.clearColorTexture = Compositor.CompositionManager.GetClearTextureForStackedCamera(hdCamera); // returns null if is not a stacked camera + passData.clearDepthTexture = Compositor.CompositionManager.GetClearDepthForStackedCamera(hdCamera); // returns null if is not a stacked camera + builder.SetRenderFunc( (DebugViewMaterialData data, RenderGraphContext context) => { + // 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 + // Note: Ideally here we would like to draw directly on the same buffers as the previous camera, but currently the compositor is not using + // Texture Arrays so this would not work. We might need to revise this in the future. + if (data.clearColorTexture != null) + { + HDUtils.BlitColorAndDepth(context.cmd, data.clearColorTexture, data.clearDepthTexture, new Vector4(1, 1, 0, 0), 0, !hdCamera.clearDepth); + } DrawOpaqueRendererList(context, data.frameSettings, data.opaqueRendererList); DrawTransparentRendererList(context, data.frameSettings, data.transparentRendererList); }); diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs index 6a209f3a735..c92bb76f752 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs @@ -175,6 +175,7 @@ internal static Volume GetOrCreateDefaultVolume() Material m_Blit; Material m_BlitTexArray; Material m_BlitTexArraySingleSlice; + Material m_BlitColorAndDepth; MaterialPropertyBlock m_BlitPropertyBlock = new MaterialPropertyBlock(); RenderTargetIdentifier[] m_MRTCache2 = new RenderTargetIdentifier[2]; @@ -327,6 +328,7 @@ internal int GetMaxScreenSpaceShadows() string m_ForwardPassProfileName; internal Material GetBlitMaterial(bool useTexArray, bool singleSlice) { return useTexArray ? (singleSlice ? m_BlitTexArraySingleSlice : m_BlitTexArray) : m_Blit; } + internal Material GetBlitColorAndDepthMaterial() { return m_BlitColorAndDepth; } ComputeBuffer m_DepthPyramidMipLevelOffsetsBuffer = null; @@ -1088,6 +1090,7 @@ void InitializeDebugMaterials() m_DebugColorPicker = CoreUtils.CreateEngineMaterial(defaultResources.shaders.debugColorPickerPS); m_DebugExposure = CoreUtils.CreateEngineMaterial(defaultResources.shaders.debugExposurePS); m_Blit = CoreUtils.CreateEngineMaterial(defaultResources.shaders.blitPS); + m_BlitColorAndDepth = CoreUtils.CreateEngineMaterial(defaultResources.shaders.blitColorAndDepthPS); m_ErrorMaterial = CoreUtils.CreateEngineMaterial("Hidden/InternalErrorShader"); // 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 { // 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 // we must override the state here. - CoreUtils.SetRenderTarget(cmd, m_CameraColorBuffer, m_SharedRTManager.GetDepthStencilBuffer(), ClearFlag.All, Color.clear); + + // [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 + var clearColorTexture = Compositor.CompositionManager.GetClearTextureForStackedCamera(hdCamera); // returns null if is not a stacked camera + var clearDepthTexture = Compositor.CompositionManager.GetClearDepthForStackedCamera(hdCamera); // returns null if is not a stacked camera + if (clearColorTexture) + { + HDUtils.BlitColorAndDepth(cmd, clearColorTexture, clearDepthTexture, new Vector4(1, 1, 0, 0), 0, !hdCamera.clearDepth); + } + // Render Opaque forward var rendererListOpaque = RendererList.Create(CreateOpaqueRendererListDesc(cull, hdCamera.camera, m_AllForwardOpaquePassNames, m_CurrentRendererConfigurationBakedLighting, stateBlock: m_DepthStateOpaque)); DrawOpaqueRendererList(renderContext, cmd, hdCamera.frameSettings, rendererListOpaque); diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPipelineResources.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPipelineResources.cs index 204d0f1b12a..c41bc87b960 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPipelineResources.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPipelineResources.cs @@ -110,6 +110,8 @@ public sealed class ShaderResources public Shader copyDepthBufferPS; [Reload("Runtime/ShaderLibrary/Blit.shader")] public Shader blitPS; + [Reload("Runtime/ShaderLibrary/BlitColorAndDepth.shader")] + public Shader blitColorAndDepthPS; [Reload("Runtime/ShaderLibrary/DownsampleDepth.shader")] public Shader downsampleDepthPS; diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Utility/HDUtils.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Utility/HDUtils.cs index 95af0e96c60..499584b578e 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Utility/HDUtils.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Utility/HDUtils.cs @@ -307,6 +307,32 @@ public static void BlitTexture(CommandBuffer cmd, RTHandle source, Vector4 scale s_PropertyBlock.SetFloat(HDShaderIDs._BlitMipLevel, mipLevel); BlitTexture(cmd, source, scaleBias, GetBlitMaterial(TextureXR.dimension), bilinear ? 1 : 0); } + + /// + /// Blit a 2D texture and depth buffer. + /// + /// Command Buffer used for rendering. + /// Source Texture for color. + /// Source RenderTexture for depth. + /// Scale and bias for sampling the input texture. + /// Mip level to blit. + /// Enable bilinear filtering. + internal static void BlitColorAndDepth(CommandBuffer cmd, Texture sourceColor, RenderTexture sourceDepth, Vector4 scaleBias, float mipLevel, bool blitDepth) + { + HDRenderPipeline hdPipeline = RenderPipelineManager.currentPipeline as HDRenderPipeline; + if (hdPipeline != null) + { + Material mat = hdPipeline.GetBlitColorAndDepthMaterial(); + + s_PropertyBlock.SetFloat(HDShaderIDs._BlitMipLevel, mipLevel); + s_PropertyBlock.SetVector(HDShaderIDs._BlitScaleBias, scaleBias); + s_PropertyBlock.SetTexture(HDShaderIDs._BlitTexture, sourceColor); + if (blitDepth) + s_PropertyBlock.SetTexture(HDShaderIDs._InputDepth, sourceDepth, RenderTextureSubElement.Depth); + cmd.DrawProcedural(Matrix4x4.identity, mat, blitDepth ? 1 : 0, MeshTopology.Triangles, 3, 1, s_PropertyBlock); + } + } + /// /// Blit a RTHandle texture /// diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/HDRenderPipelineResources.asset b/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/HDRenderPipelineResources.asset index dcb067827a6..401d03bcdb4 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/HDRenderPipelineResources.asset +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/HDRenderPipelineResources.asset @@ -85,6 +85,8 @@ MonoBehaviour: type: 3} copyDepthBufferPS: {fileID: 4800000, guid: 42dfcc8fe803ece4096c58630689982f, type: 3} blitPS: {fileID: 4800000, guid: 370f7a9cc4e362d488af024d371091e8, type: 3} + blitColorAndDepthPS: {fileID: 4800000, guid: c6e57f5bdbd2a284a86a3097c03884c8, + type: 3} downsampleDepthPS: {fileID: 4800000, guid: 67d6171b0acc6554aad48c845ec7e67f, type: 3} upsampleTransparentPS: {fileID: 4800000, guid: 2ad7ce40f0dbaf64dadef1f58d8524d3, type: 3} diff --git a/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/BlitColorAndDepth.shader b/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/BlitColorAndDepth.shader new file mode 100644 index 00000000000..d63396de25c --- /dev/null +++ b/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/BlitColorAndDepth.shader @@ -0,0 +1,97 @@ +Shader "Hidden/HDRP/BlitColorAndDepth" +{ + HLSLINCLUDE + + #pragma target 4.5 + #pragma editor_sync_compilation + #pragma only_renderers d3d11 playstation xboxone vulkan metal switch + #pragma multi_compile _ DISABLE_TEXTURE2D_X_ARRAY + #pragma multi_compile _ BLIT_SINGLE_SLICE + #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" + #include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl" + + TEXTURE2D (_BlitTexture); + TEXTURE2D (_InputDepthTexture); + SamplerState sampler_PointClamp; + SamplerState sampler_LinearClamp; + uniform float4 _BlitScaleBias; + uniform float _BlitMipLevel; + + struct Attributes + { + uint vertexID : SV_VertexID; + UNITY_VERTEX_INPUT_INSTANCE_ID + }; + + struct Varyings + { + float4 positionCS : SV_POSITION; + float2 texcoord : TEXCOORD0; + UNITY_VERTEX_OUTPUT_STEREO + }; + + Varyings Vert(Attributes input) + { + Varyings output; + UNITY_SETUP_INSTANCE_ID(input); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output); + output.positionCS = GetFullScreenTriangleVertexPosition(input.vertexID); + output.texcoord = GetFullScreenTriangleTexCoord(input.vertexID) * _BlitScaleBias.xy + _BlitScaleBias.zw; + return output; + } + + float4 FragColorOnly(Varyings input) : SV_Target + { + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + + return SAMPLE_TEXTURE2D_LOD(_BlitTexture, sampler_LinearClamp, input.texcoord.xy, _BlitMipLevel); + } + + struct PixelData + { + float4 color : SV_Target; + float depth : SV_Depth; + }; + + PixelData FragColorAndDepth(Varyings input) + { + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + + PixelData pd; + pd.color = SAMPLE_TEXTURE2D_LOD(_BlitTexture, sampler_LinearClamp, input.texcoord.xy, _BlitMipLevel); + pd.depth = SAMPLE_TEXTURE2D_LOD(_InputDepthTexture, sampler_PointClamp, input.texcoord.xy, _BlitMipLevel).x; + return pd; + } + + ENDHLSL + + SubShader + { + Tags{ "RenderPipeline" = "HDRenderPipeline" } + + // 0: Color Only + Pass + { + ZWrite Off ZTest Always Blend Off Cull Off + + HLSLPROGRAM + #pragma vertex Vert + #pragma fragment FragColorOnly + ENDHLSL + } + + // 1: Color Only and Depth + Pass + { + ZWrite On ZTest Always Blend Off Cull Off + + HLSLPROGRAM + #pragma vertex Vert + #pragma fragment FragColorAndDepth + ENDHLSL + } + + } + + Fallback Off +} diff --git a/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/BlitColorAndDepth.shader.meta b/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/BlitColorAndDepth.shader.meta new file mode 100644 index 00000000000..495357f7108 --- /dev/null +++ b/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/BlitColorAndDepth.shader.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c6e57f5bdbd2a284a86a3097c03884c8 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + preprocessorOverride: 0 + userData: + assetBundleName: + assetBundleVariant: