diff --git a/com.unity.render-pipelines.high-definition/CHANGELOG.md b/com.unity.render-pipelines.high-definition/CHANGELOG.md index 7216985f991..c57abee852a 100644 --- a/com.unity.render-pipelines.high-definition/CHANGELOG.md +++ b/com.unity.render-pipelines.high-definition/CHANGELOG.md @@ -121,6 +121,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Fix nan in pbr sky - Fixed Light skin not properly applied on the LookDev when switching from Dark Skin (case 1278802) - Fixed accumulation on DX11 +- Fixed issue with screen space UI not drawing on the graphics compositor (case 1279272). ### Changed - Preparation pass for RTSSShadows to be supported by render graph. 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 1295258a3e7..582cf0c4b88 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Compositor/CompositionLayer.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Compositor/CompositionLayer.cs @@ -54,6 +54,8 @@ public enum ResolutionScale [SerializeField] bool m_ClearAlpha = true; // Specifies if the Alpha channel will be cleared when stacking this camera over the previous one (for overlays) [SerializeField] Renderer m_OutputRenderer = null; // Specifies the output surface/renderer [SerializeField] LayerType m_Type; + + public Camera sourceCamera => m_Camera; [SerializeField] Camera m_Camera = null; // The source camera for the layer (were we get the default properties). The actual rendering, with overridden properties is done by the m_LayerCamera [SerializeField] VideoPlayer m_InputVideo = null; [SerializeField] Texture m_InputTexture = null; @@ -131,6 +133,9 @@ public float aspectRatio [SerializeField] Camera m_LayerCamera; + // Returns true if this layer is using a camera that was cloned internally for drawing + bool isUsingACameraClone => !m_LayerCamera.Equals(m_Camera); + private CompositorLayer() { } @@ -210,39 +215,47 @@ public void Init(string layerID = "") m_Camera = CompositionManager.GetSceceCamera(); } + var compositor = CompositionManager.GetInstance(); + // Create a new camera if necessary or use the one specified by the user if (m_LayerCamera == null && m_OutputTarget == OutputTarget.CameraStack) { - - // Clone the camera that was given by the user. We avoid calling Instantiate because we don't want to clone any other children that might be attachen to the camera - var newCameraGameObject = new GameObject("Layer " + layerID) - { - hideFlags = HideFlags.HideInInspector | HideFlags.HideInHierarchy | HideFlags.HideAndDontSave - }; - m_LayerCamera = newCameraGameObject.AddComponent(); - newCameraGameObject.AddComponent(); - CopyInternalCameraData(); - - m_LayerCamera.name = "Compositor" + layerID; - m_LayerCamera.gameObject.hideFlags = HideFlags.HideInInspector | HideFlags.HideInHierarchy | HideFlags.HideAndDontSave; - if(m_LayerCamera.tag == "MainCamera") + if (!compositor.IsThisCameraShared(m_Camera)) { - m_LayerCamera.tag = "Untagged"; + // The camera is not shared, so it is safe to use it directly in the layer (no need to clone it) + m_LayerCamera = m_Camera; } - - // Remove the compositor copy (if exists) from the cloned camera. This will happen if the compositor script was attached to the camera we are cloning - var compositionManager = m_LayerCamera.GetComponent(); - if (compositionManager != null) + else { - CoreUtils.Destroy(compositionManager); - } + // Clone the camera that was given by the user. We avoid calling Instantiate because we don't want to clone any other children that might be attachen to the camera + var newCameraGameObject = new GameObject("Layer " + layerID) + { + hideFlags = HideFlags.HideInInspector | HideFlags.HideInHierarchy | HideFlags.HideAndDontSave + }; + m_LayerCamera = newCameraGameObject.AddComponent(); + newCameraGameObject.AddComponent(); + CopyInternalCameraData(); + + m_LayerCamera.name = "Compositor" + layerID; + m_LayerCamera.gameObject.hideFlags = HideFlags.HideInInspector | HideFlags.HideInHierarchy | HideFlags.HideAndDontSave; + if (m_LayerCamera.tag == "MainCamera") + { + m_LayerCamera.tag = "Untagged"; + } - var cameraData = m_LayerCamera.GetComponent(); - if (cameraData == null) - { - m_LayerCamera.gameObject.AddComponent(typeof(HDAdditionalCameraData)); - } + // Remove the compositor copy (if exists) from the cloned camera. This will happen if the compositor script was attached to the camera we are cloning + var compositionManager = m_LayerCamera.GetComponent(); + if (compositionManager != null) + { + CoreUtils.Destroy(compositionManager); + } + var cameraData = m_LayerCamera.GetComponent(); + if (cameraData == null) + { + m_LayerCamera.gameObject.AddComponent(typeof(HDAdditionalCameraData)); + } + } } m_ClearsBackGround = false; m_LayerPositionInStack = 0; // will be set in SetupLayerCamera @@ -299,7 +312,6 @@ public void Init(string layerID = "") } } - var compositor = CompositionManager.GetInstance(); if (m_OutputRenderer != null && Application.IsPlaying(compositor.gameObject)) { MaterialPropertyBlock propertyBlock = new MaterialPropertyBlock(); @@ -317,7 +329,7 @@ public void Init(string layerID = "") if (layerData == null) { layerData = m_LayerCamera.gameObject.AddComponent(); - layerData.hideFlags = HideFlags.HideAndDontSave; + layerData.hideFlags = HideFlags.HideAndDontSave | HideFlags.HideInInspector; } // Reset the layer params (in case we cloned a camera which already had AdditionalCompositorData) if (layerData != null) @@ -370,7 +382,8 @@ public bool Validate() public void DestroyRT() { - if (m_LayerCamera != null) + // We should destroy the layer camera only if it was cloned + if (m_LayerCamera != null && isUsingACameraClone) { var cameraData = m_LayerCamera.GetComponent(); if (cameraData) @@ -462,6 +475,12 @@ public void SetAdditionalLayerData() internal void CopyInternalCameraData() { + if (!isUsingACameraClone) + { + // we are using directly the source camera, so there is no need to copy any properties + return; + } + // Copy/update the camera data (but preserve the camera depth/draw-order [case 1264552]) var drawOrder = m_LayerCamera.depth; m_LayerCamera.CopyFrom(m_Camera); 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 ac12a7f6235..d1803fcf875 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Compositor/CompositionManager.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Compositor/CompositionManager.cs @@ -797,6 +797,27 @@ void CustomRender(ScriptableRenderContext context, HDCamera camera) CommandBufferPool.Release(cmd); } + /// + /// Helper function that indicates if a camera is shared between multiple layers + /// + /// The input camera + /// Returns true if this camera is used to render in more than one layer + internal bool IsThisCameraShared(Camera camera) + { + int count = 0; + foreach (var layer in m_InputLayers) + { + + if (layer.outputTarget == CompositorLayer.OutputTarget.CameraStack && + camera.Equals(layer.sourceCamera)) + { + count++; + } + } + // If we found the camera in more than one layer then it is shared between layers + return count > 1; + } + static public Camera GetSceceCamera() { if (Camera.main != null)