diff --git a/com.unity.render-pipelines.high-definition/CHANGELOG.md b/com.unity.render-pipelines.high-definition/CHANGELOG.md index 03b0a187a6d..1d5f2229539 100644 --- a/com.unity.render-pipelines.high-definition/CHANGELOG.md +++ b/com.unity.render-pipelines.high-definition/CHANGELOG.md @@ -137,6 +137,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Fix decal being applied twice with LOD Crossfade. - Fixed camera stacking for AOVs in the graphics compositor (case 1273223). - Disable quad overdraw on ps4. +- Fixed error when resizing the graphics compositor's output and when re-adding a compositor in the scene ### Changed - Preparation pass for RTSSShadows to be supported by render graph. diff --git a/com.unity.render-pipelines.high-definition/Editor/Compositor/CompositionUtils.cs b/com.unity.render-pipelines.high-definition/Editor/Compositor/CompositionUtils.cs index a61403487d4..3ea545e1d62 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Compositor/CompositionUtils.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Compositor/CompositionUtils.cs @@ -69,16 +69,15 @@ static public void RemoveAudioListeners(Camera camera) static public void SetDefaultCamera(CompositionManager compositor) { - var camera = CompositionManager.GetSceceCamera(); - if (camera != null) + // Create a new camera for the compositor's output + var newCameraGameObject = new GameObject(k_DefaultCameraName); + var camera = newCameraGameObject.AddComponent(); { - var outputCamera = Object.Instantiate(camera); - RemoveAudioListeners(outputCamera); - outputCamera.name = k_DefaultCameraName; - outputCamera.tag = "Untagged"; - outputCamera.cullingMask = 0; // we don't want to render any 3D objects on the compositor camera - compositor.outputCamera = outputCamera; + camera.tag = "Untagged"; + camera.cullingMask = 0; // we don't want to render any 3D objects on the compositor camera } + newCameraGameObject.AddComponent(); + compositor.outputCamera = camera; } static public void SetDefaultLayers(CompositionManager compositor) 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 2ca6e1ffad2..82497f32d92 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Compositor/CompositionLayer.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Compositor/CompositionLayer.cs @@ -134,7 +134,7 @@ 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); + internal bool isUsingACameraClone => !m_LayerCamera.Equals(m_Camera); // The input alpha will be mapped between the min and max range when blending between the post-processed and plain image regions. This way the user can controls how steep is the transition. [SerializeField] float m_AlphaMin = 0.0f; @@ -266,7 +266,11 @@ public void Init(string layerID = "") if (m_OutputTarget != OutputTarget.CameraStack && m_RenderTarget == null) { - m_RenderTarget = new RenderTexture(pixelWidth, pixelHeight, 24, (GraphicsFormat)m_ColorBufferFormat); + // If we don't have a valid camera (zero width or height) avoid creating the RT + if (pixelWidth > 0 && pixelHeight > 0) + { + m_RenderTarget = new RenderTexture(pixelWidth, pixelHeight, 24, (GraphicsFormat)m_ColorBufferFormat); + } } // check and fix RT handle 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 34641d061a7..a773847c8a6 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Compositor/CompositionManager.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Compositor/CompositionManager.cs @@ -66,7 +66,7 @@ public bool enableOutput // also change the layers foreach(var layer in m_InputLayers) { - if (layer.camera) + if (layer.camera && layer.isUsingACameraClone) { layer.camera.enabled = value; } @@ -351,10 +351,25 @@ public void OnEnable() public void DeleteLayerRTs() { + int numRTReferences = 0; + // delete the layer from last to first, in order to release first the camera and then the associated RT for (int i = m_InputLayers.Count - 1; i >= 0; --i) { - m_InputLayers[i].DestroyRT(); + // Since some layers are not useing cloned cameras, we have to count the number of references in a RT and only delete if it is zero + if (numRTReferences == 0) + { + m_InputLayers[i].DestroyRT(); + } + + if (m_InputLayers[i].outputTarget == CompositorLayer.OutputTarget.CompositorLayer) + { + numRTReferences = 0; + } + else + { + numRTReferences += (m_InputLayers[i].camera != null) ? 1 : 0; + } } } @@ -522,11 +537,7 @@ void Update() void OnDestroy() { - // We need to destroy the layers from last to first, to avoid releasing a RT that is used by a camera - for (int i = m_InputLayers.Count - 1; i >= 0; --i) - { - m_InputLayers[i].Destroy(); - } + DeleteLayerRTs(); if (m_CompositorGameObject != null) { @@ -804,6 +815,11 @@ void CustomRender(ScriptableRenderContext context, HDCamera camera) /// Returns true if this camera is used to render in more than one layer internal bool IsThisCameraShared(Camera camera) { + if (camera == null) + { + return false; + } + int count = 0; foreach (var layer in m_InputLayers) {