- Home /
Unexpected Release of RenderTexture
I have a RenderTexture which is targetTexture for the camera.
This RenderTexture created from a script in a following way:
RenderTexture rt = new RenderTexture(Screen.width, Screen.height, 0);
rt.Create();
camera.targetTexture = rt;
The problem is that sometimes, after about 2-3 min of game play the unexpected "release" of this RenderTexture occurs and I have:
RenderTexture which state is "not created" (IsCreated() == false)
RenderTexture is no more camera's target (camera.targetTexture == null)
Message in the log: "Releasing render texture that is set as Camera.targetTexture!"
This also happens each time when I change vSync:
QualitySettings.vSyncCount = QualitySettings.vSyncCount == 0 ? 1 : 0;
There is a notice about possibility of release on certain events on the RenderTexture scripting API's page: http://docs.unity3d.com/ScriptReference/RenderTexture.html
But this not explains much. Why these releases happen?
I've managed to handle this problem by simply checking IsCreated() and restoring the state. This code I placed in the end of the Update() method:
if (!rt.IsCreated())
{
rt.Create();
camera.targetTexture = rt;
}
While this solution works, for me it fills like it some kind of workaround and I still missing something...
Is this a good solution for the problem? Or maybe it should be handled in a different way ?
I've the same problem. It seems checking IsCreated() is right thing to do. I would like to have an event when texture is reset...
Even if isCreated is necessary, the log message "Releasing render texture that is set as Camera.targetTexture!" implies something is going wrong. Was this ever filed as a bug?
Same problem here. Unity 5.3.3f1. I can not trace to understand when it occurs :/ Some news about this issue? Thanks!
Have you tried updating to 5.3.4? I had a similar render texture issue that got fixed
PS: In my case this error does not happen in Editor mode... Only in the build.
Answer by Ricna · Mar 26, 2016 at 10:28 PM
After a lot of debugs i found a solution (at least for me)....
So, I already tried to solve using the Create method. In true nothing changes using Create. Using or not the result after new RenderTexture will be "isCreated == true".
I solved my issue disabling the camera that use rendertexture every time that I need to do some of this actions:
1. When changing any attribute of RenderTexture after isCreated().
2. When changing Screen size or Resolution of the camera where was added a RenderTexture.
3. When changing VSyncCount of QualitySettings.
4. When changing Antialising of QualitySettings.
We don't need to use the WaitForEndOfFrame or even Coroutine in most cases. The only case for is while changing the resolution to Fullscreen, because it take some time and even with WaitForEndOfFrame I didn't have success, so was better to use a delay using WaitForSeconds(2);
In short, all that we need is to disable the camera before some of those actions and then enable again after all changes was completed.
I created this method to be called from any case:
public void SwitchOnOffAllCameras(bool enabled) {
for (int i = 0; i < XMLHandler.Instance.layersNow; i++) {
camLayer[i].GetComponent<Camera>().enabled = enabled;
}
}
NOTE: In my case I use 1,2,3 or 4 cameras using RenderTexture, but you can simplify using only something like:
public void SwitchOnOffCameraWithRenderTexture(bool enabled) {
camera.enabled = enabled;
}
I like to use methods to identify where I'm changing the attribute and if needed change something only there, as I need to call it from other script too its very better to handle.
So... I called that method before to change something that was causing the error. After all is done I called it again: SwitchOnOffAllCameras(true);
Example 1 (quality settings):
SwitchOnOffAllCameras(false);
QualitySettings.antiAliasing = QualitySettings.antiAliasing ==0?2: QualitySettings.antiAliasing *2;
SwitchOnOffAllCameras(true);
Example 2 (fullscreen issue):
private IEnumerator SwitchFullscreen() {
CameraHandler.Instance.SwitchOnOffAllCameras(false);
if (Screen.fullScreen) {
Screen.SetResolution(940, 720, false);
} else {
Screen.SetResolution(Screen.currentResolution.width, Screen.currentResolution.height, true);
}
yield return new WaitForSeconds(2);
CameraHandler.Instance.SwitchOnOffAllCameras(true);
}
Example 3 (creating camera and RenderTexture): In this case I didn't use that method as I'm creating cameras and RenderTextures for the first time and would generate a null exception.
private void CreateCamerasForRenderTexture() {
Debug.LogAssertion("Before Create RT");
camLayer = new GameObject[XMLHandler.Instance.layersNow];
renderTextureLayer = new RenderTexture[XMLHandler.Instance.layersNow];
for (int i = 0; i < XMLHandler.Instance.layersNow; i++) {
camLayer[i] = new GameObject("CamLayerAB" + i);
camLayer[i].AddComponent<Camera>();
camLayer[i].GetComponent<Camera>().enabled = false;
camLayer[i].GetComponent<Camera>().orthographic = true;
camLayer[i].GetComponent<Camera>().orthographicSize = 0.6f * (XMLHandler.Instance.scale);
camLayer[i].transform.parent = cam.transform;
camLayer[i].transform.localPosition = Vector3.zero;
camLayer[i].transform.localRotation = Quaternion.identity;
camLayer[i].GetComponent<Camera>().backgroundColor = new Color(0, 0, 0, 0);
camLayer[i].GetComponent<Camera>().cullingMask = 1 << LayerMask.NameToLayer(XMLHandler.Instance.layerNameToApply[i]);
camLayer[i].GetComponent<Camera>().useOcclusionCulling = false;
renderTextureLayer[i] = new RenderTexture(Screen.width, Screen.height, 24, RenderTextureFormat.ARGB32);
renderTextureLayer[i].name = "RenderTextureLayerAB" + i;
camLayer[i].GetComponent<Camera>().targetTexture = renderTextureLayer[i];
camLayer[i].GetComponent<Camera>().renderingPath = RenderingPath.Forward;
camLayer[i].GetComponent<Camera>().enabled = true;
}
Debug.LogAssertion("After Create RT");
}
To discover where (in my case) was occurring the error I create a LOT of Debug.LogAssertion() entries to see in the console of Standalone build.
NOTE: I listed 4 cases, but probably have more situations where the issue could happens.
I hope that it can help someone.
In case "Alt+Enter", how can i switch off camera before screen change.
Incase full screen, I implemented SwitchOnOffAllCameras function. It worked on Windows but not on OSX. do you know any other solution?