Standalone only error: Releasing render texture that is set to be RenderTexture.active!

Releasing render texture that is set to be RenderTexture.active!
RenderTexture warning: Destroying active render texture. Switching to main context.

Does anyone have a good explanation as to why this error is occurring, or how to prevent it? As far as I can tell it doesn’t happen in the editor, and this error seems to occur when loading a level that doesn’t have a camera which uses a render texture when the previous one did. I’ve tried releasing the active render texture before loading, after loading, during loading (LoadLevelASync), on PreRender, etc, but this error always happens on the first frame once the new level is loaded. I’ve also tried adding a dummy camera into the problematic scene with the render texture set up, but the error still occurs.

1 Like

hey i am having similar issue, only on standalone

Setting up 2 worker threads for Enlighten.
Thread → id: 116cad000 → priority: 1
Thread → id: 1171c8000 → priority: 1
Releasing render texture that is set as Camera.targetTexture!

(Filename: /Users/builduser/buildslave/unity/build/Runtime/Camera/Camera.cpp Line: 2939)

Releasing render texture that is set as Camera.targetTexture!

(Filename: /Users/builduser/buildslave/unity/build/Runtime/Camera/Camera.cpp Line: 2939)

Using Mac and Unity 5.3.0

fixed , not sure what was your case but in my case the problem happened every time i change resolution at runtime, so i fixed it by not assigning the targetTexture right immediately after setting the new resolution but a frame later, i had noticed that real resolution change ( not the emulation that happens at editor ) does not happen immediately even in other parts of my code that depends on the actual resolution i could not execute it immediately but had to wait till the resolution was actually set…
Despite it seems to be related to the same “not immediate resolution change thing” , this releasing render texture issue is totally new though, it was not happening in unity 4.6 and started to happen when i moved to unity 5…

hope this helps someone

It confirms my experience. I had to do any changes to the RenderTexture after “WaitForEndOfFrame”, otherwise it was often crashing on certain devices (it was not even consistent between same GPUs; yet it was game-breaking). Now it seems even weirder that it isn’t documented everywhere, because I’m obviously not the only one with the same problem :-). FYI, it even crashes on certain Android and iOS devices. But not all of them.

1 Like

to be totally sure i understood correctly , all problems and crashes went away when you moved all changes behind a yield WaitForEndOfFrame ?

Yes. My use-case was little bit different, but the symptoms seem to be very similar (mess with RenderTexture, get access crash in native code). If you are interested, the issue was reported and solution posted in my older thread:

Not sure if these two have anything in common, but it seems so :-). After I put the line there, I had no crash for last two months. I think it’s because all EndOfFrame yields are called after the frame has been fully rendered, and therefore you cannot access it at the same time as your camera does. But what do I know :-).

1 Like

thanks, and lol, yeah , most of the time this coding in unity is all about fixing obscure undocumented problems and making workaround solutions that do work but you don’t really know why they work …

1 Like

Word.

Hi! Can you guys post some example? I tried to do all that you said but without success.
I have to create 4 render textures using the Screen.widht and Screen.heigth. I tried to use a static value like 640x480. Also tried to do it after 5 seconds after the level loaded, so obviously much more than 1 frame after all was done.
Why? I’m going to give up. So sad… This project was working since 2012 and now didn’t work because the Unity5 :frowning:
Thanks in advance!

this is how i do it, with a coroutine to start next frame

    public void DoTheRenderTextureShit(){
        if (debug) print ("DENTRO DE DO THE RENDER TEXTURE SHIT");
        FindRenderToTextureSpecificShit();
        int x = (int)fatRes.x;
        int y = (int)fatRes.y;
        if ( fatRes.y % 2 != 0 ){ // si la altura no es divisible por 2
            canvasOffsetY = 0.5f;
            scanLinesOffsetY = 2;
            y = y + 1;
        }
        else{
            canvasOffsetY = 0;
            scanLinesOffsetY = 0;
        }
            if (debug) print(" Y = " + y + " fatRes.y = " + fatRes.y + " canvasOffsetY = " + canvasOffsetY);
   
        myRenderTexture = new RenderTexture((int)(x * pixelResolution.x), (int)(fatRes.y * pixelResolution.y), 24, RenderTextureFormat.ARGB32); // !
        myRenderTexture.filterMode = renderTextureFilterMode;

        SnapTo.realPixel.x = (int)pixelResolution.x;
        SnapTo.realPixel.y = (int)pixelResolution.y;
   
        float xFloat = (float)x; // para no tener que castear todo el rato
        float yFloat = (float)y; // para no tener que castear todo el rato
        Rect newRect = screenCanvasRectTransform.rect;
        newRect.width = xFloat;
        newRect.height = yFloat;
        screenRect.rectTransform.sizeDelta = new Vector2( xFloat, yFloat);
        float orthoSize;
        if (Application.isEditor == false) orthoSize= fatRes.y/2f;
        else orthoSize = (gResolutions[gri].height/zoomFactor) / 2f;
        if (debug) print ("Y ="+ y +" ORTHO SIZE ="+ orthoSize);
        camTex.orthographicSize = orthoSize;
        camTexBounds.size = new Vector3(camTex.pixelWidth, camTex.pixelHeight, 0) / zoomFactor;
        camTexBounds.center = camTex.transform.position;
        for (int n=0; n < shiftOnOddVerticalRes.Length; n++){
            TransformHelper.SetLocalPosY(shiftOnOddVerticalRes[n].transform, canvasOffsetY);
        }
   
        camTK2D.forceResolutionInEditor = true;
        camTK2D.forceResolution = new Vector2(xFloat , fatRes.y);
        camTK2D._screenExtents = new Rect(-xFloat/2, -fatRes.y/2, xFloat, fatRes.y);
        StartCoroutine( AssignRenderTextureNextFrame() ); // WORKAROUND
   
        camUnity.orthographicSize = orthoSize;
        camUnity.enabled = false;
        camUnity.enabled = true;
       
        if (camUI){
            camUI.orthographicSize = camUnity.orthographicSize;
            camUI.gameObject.SetActive(false);
            camUI.gameObject.SetActive(true);
        }
    }
    public IEnumerator AssignRenderTextureNextFrame(){ // WORKAROUND unity5.3 me da un error SOLO EN STANDALONE que dice Releasing RenderTexture that is set as Camera.targetTexture
        yield return null;
        camUnity.targetTexture = myRenderTexture;
        screenRect.texture = myRenderTexture;
        if (camSky) camSky.targetTexture = myRenderTexture;
        if (camUI) camUI.targetTexture = myRenderTexture;
        if (shadowMaker) shadowMaker.OnSetResolution();
    }

uhm… i just found this

i was not aware of that, could it be the reason we getting that error?

Thanks for share DrKucho!
So, I already tried to solve using the Create method.
In true nothing changes using this in my case.
In some post someone said to do something like:

rt = new RenderTexture(256, 256, 16, RenderTextureFormat.ARGB32);
if (!rt.isCreated(){
    rt.Create();
}

Well… I have good news (for me at least :slight_smile: ).

I solved this issue disabling the camera that use rendertexture every time that I need to do some of this actions:

  • When changing any attribute of RenderTexture after isCreated().
  • When changing Screen size or Resolution of the camera where was added a RenderTexture.
  • When changing VSyncCount of QualitySettings.
  • When changing Antialising of QualitySettings.

We don’t need to use the WaitForEndOfFrame or even Coroutine in most cases :wink: 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 action 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 be more easy to identify where I’m changing the attribute, as I need to call it from other script too.

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.

3 Likes

good to know, thanks for sharing, i’ll keep in mind to disable camera in case i get any more errors