Skip to content

Commit cc3971d

Browse files
committed
Improve camera management in compositor
1 parent 3d7b4e6 commit cc3971d

File tree

3 files changed

+26
-6
lines changed

3 files changed

+26
-6
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
1111

1212
### Fixed
1313
- Fixed probe volumes debug views.
14+
- Fixed issues with image layers in graphics compositor (empty layers don't render black, improve internal camera management - case 1289936)
1415

1516
## [10.2.0] - 2020-10-19
1617

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

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ public float aspectRatio
137137

138138
// Returns true if this layer is using a camera that was cloned internally for drawing
139139
internal bool isUsingACameraClone => !m_LayerCamera.Equals(m_Camera);
140+
internal bool isImageOrVideoLayer => (m_Type == LayerType.Image || m_Type == LayerType.Video);
140141

141142
// 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.
142143
[SerializeField] float m_AlphaMin = 0.0f;
@@ -151,12 +152,12 @@ public static CompositorLayer CreateStackLayer(LayerType type = CompositorLayer.
151152
var newLayer = new CompositorLayer();
152153
newLayer.m_LayerName = layerName;
153154
newLayer.m_Type = type;
154-
newLayer.m_Camera = CompositionManager.GetSceneCamera();
155+
newLayer.m_Camera = newLayer.isImageOrVideoLayer ? null : CompositionManager.GetSceneCamera();
155156
newLayer.m_CullingMask = newLayer.m_Camera? newLayer.m_Camera.cullingMask : 0; //LayerMask.GetMask("None");
156157
newLayer.m_OutputTarget = CompositorLayer.OutputTarget.CameraStack;
157158
newLayer.m_ClearDepth = true;
158159

159-
if (newLayer.m_Type == LayerType.Image || newLayer.m_Type == LayerType.Video)
160+
if (newLayer.isImageOrVideoLayer)
160161
{
161162
// Image and movie layers do not render any 3D objects
162163
newLayer.m_OverrideCullingMask = true;
@@ -229,6 +230,11 @@ public void Init(string layerID = "")
229230

230231
// Compositor output layers (that allocate the render targets) also need a reference camera, just to get the reference pixel width/height
231232
// Note: Movie & image layers are rendered at the output resolution (and not the movie/image resolution). This is required to have post-processing effects like film grain at full res.
233+
if (m_Camera == null && isImageOrVideoLayer)
234+
{
235+
// For image and video layers, we use a brand-new camera (to avoid sharing the same camera with other layers)
236+
m_Camera = CompositionManager.AddNewCamera(m_LayerName);
237+
}
232238
if (m_Camera == null)
233239
{
234240
m_Camera = CompositionManager.GetSceneCamera();
@@ -242,11 +248,11 @@ public void Init(string layerID = "")
242248
// We do not clone the camera if :
243249
// - it has no layer overrides
244250
// - is not shared between layers
245-
// - is not used in an mage/video layer (in this case the camera is not exposed at all, so it makes sense to let the compositor manage it)
251+
// - it is an mage/video layer (in this case we use a brand-new camera that is not exposed at all and is managed by the compositor)
246252
// - it does not force-clear the RT (the first layer of a stack, even if disabled by the user), still clears the RT
247253
bool shouldClear = !enabled && m_LayerPositionInStack == 0;
248-
bool isImageOrVideo = (m_Type == LayerType.Image || m_Type == LayerType.Video);
249-
if (!isImageOrVideo && !hasLayerOverrides && !shouldClear && !compositor.IsThisCameraShared(m_Camera))
254+
255+
if (isImageOrVideoLayer || (!hasLayerOverrides && !shouldClear && !compositor.IsThisCameraShared(m_Camera)))
250256
{
251257
m_LayerCamera = m_Camera;
252258
}
@@ -414,7 +420,7 @@ public void DestroyCameras()
414420
// We should destroy the layer camera only if it was cloned
415421
if (m_LayerCamera != null)
416422
{
417-
if (isUsingACameraClone)
423+
if (isUsingACameraClone || isImageOrVideoLayer)
418424
{
419425
var cameraData = m_LayerCamera.GetComponent<HDAdditionalCameraData>();
420426
if (cameraData)

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -843,6 +843,19 @@ static public Camera GetSceneCamera()
843843
return null;
844844
}
845845

846+
static public Camera AddNewCamera(string cameraName)
847+
{
848+
var newCameraGameObject = new GameObject(cameraName)
849+
{
850+
hideFlags = HideFlags.HideInInspector | HideFlags.HideInHierarchy | HideFlags.HideAndDontSave
851+
};
852+
853+
var camera = newCameraGameObject.AddComponent<Camera>();
854+
newCameraGameObject.AddComponent<HDAdditionalCameraData>();
855+
856+
return camera;
857+
}
858+
846859
static public CompositionManager GetInstance() =>
847860
s_CompositorInstance ?? (s_CompositorInstance = GameObject.FindObjectOfType(typeof(CompositionManager), true) as CompositionManager);
848861

0 commit comments

Comments
 (0)