Hello,
I’ve a simple setup with a Planar Reflection Probe in the scene and 2 cameras; One renders on display, the other on a render texture.
In order to save some rendering time I’ve turned off the ability to render the reflection on the secondary camera. The problem comes when switching between the 2. Configuring custom frame settings at runtime allocates, in some cases 300kb of GC and makes the build spike.
I’ve profiled on a standalone build.
Using
Unity 2019.3.15f1
HDRP 7.3.1
Here is the set up repro on the starting HDRP project:
And here is the profiling:
And the simplified version of the script.
public class SwitchCamera : MonoBehaviour
{
[System.Serializable]
public class AirCamera
{
public Camera camera;
public HDAdditionalCameraData cameraData;
public bool isActive;
internal FrameSettings _frameSettings;
internal FrameSettingsOverrideMask _frameSettingsOverrideMask;
}
public AirCamera[] airCameras;
public LayerMask activeMask;
public LayerMask deactiveMask;
public LayerMask activeProbeMask;
public LayerMask deactiveProbeMask;
public RawImage previewImage;
public RenderTexture cameraPreview;
void Start()
{
InitCameras();
}
void InitCameras()
{
for (int i = 0; i < airCameras.Length; i++)
{
airCameras[i]._frameSettings = airCameras[i].cameraData.renderingPathCustomFrameSettings;
airCameras[i]._frameSettingsOverrideMask = airCameras[i].cameraData.renderingPathCustomFrameSettingsOverrideMask;
if (i == 0)
{
OnAirCamera(i);
}
else
{
OffAirCamera(i);
}
}
}
private void SetFrameSettings(FrameSettings frameSettings, int i)
{
airCameras[i].cameraData.renderingPathCustomFrameSettings = frameSettings;
}
//OnAir Camera Configuartion
void OnAirCamera(int i)
{
//Set the bool for the active camera, used forr quick acess and checks
airCameras[i].isActive = true;
//Enable Audio Listener -> TODO:cache it!
airCameras[i].camera.gameObject.GetComponent<AudioListener>().enabled = true;
//Set Target Texture to null to render on the dislay
airCameras[i].camera.targetTexture = null;
//Set the antialiasing
airCameras[i].cameraData.antialiasing = HDAdditionalCameraData.AntialiasingMode.SubpixelMorphologicalAntiAliasing;
//Set Custom Frame Setting
airCameras[i]._frameSettingsOverrideMask.mask[(uint)FrameSettingsField.PlanarProbe] = false;
airCameras[i]._frameSettings.SetEnabled(FrameSettingsField.PlanarProbe, true);
airCameras[i].cameraData.renderingPathCustomFrameSettingsOverrideMask = airCameras[i]._frameSettingsOverrideMask;
SetFrameSettings(airCameras[i]._frameSettings, i);
}
//OffAir Camera Configuartion
void OffAirCamera(int i)
{
airCameras[i].isActive = false;
//Disable Audio Listener -> TODO:cache it!
airCameras[i].camera.gameObject.GetComponent<AudioListener>().enabled = false;
//Set off aliasing to reduce draw calls
airCameras[i].cameraData.antialiasing = HDAdditionalCameraData.AntialiasingMode.None;
//Set Target Texture to render on a RenderTex
airCameras[i].camera.targetTexture = cameraPreview;
// //Set Custom Frame Settings
airCameras[i]._frameSettingsOverrideMask.mask[(uint)FrameSettingsField.PlanarProbe] = true;
airCameras[i]._frameSettings.SetEnabled(FrameSettingsField.PlanarProbe, false);
airCameras[i].cameraData.renderingPathCustomFrameSettingsOverrideMask = airCameras[i]._frameSettingsOverrideMask;
SetFrameSettings(airCameras[i]._frameSettings, i);
}
void Update()
{
if(Input.GetKeyDown(KeyCode.F1))
{
Debug.Log("active cam1");
OnAirCamera(0);
OffAirCamera(1);
}
else if (Input.GetKeyDown(KeyCode.F2))
{
Debug.Log("active cam2");
OnAirCamera(1);
OffAirCamera(0);
}
}
}
now, I’m wondering if there’s a better way to optimize this aspect without incurring in those issue.
Here’re the links to download the test project and the profiler data.
TestPrj: Deleted
ProfilerData: Deleted
Thanks.