- Home /
 
Fading in one camera over another as an overlay with RenderTexture and GUI.DrawTexture. Any way to control pixel clearing?
Update: As of now I'm using this script in my project and locking my objects' movement during the transition. This works fine, but solving the original problem would be a more ideal, general solution.
Download example package - RenderTextureQuestionSubmit.unitypackage
I'm trying to use a RenderTexture and GUI.DrawTexture to do a fade-up of a second camera as an overlay. Once the fade is complete, it switches to a live view of both cameras. I have attached screen shots and a unitypackage showing a ghosting problem that I'm getting.
The example fades in a moving foreground over a static background. Once the fade-in is complete, the foreground camera's targetTexture is set to null, causing both background and foreground cameras to be rendered live. The depth-only option for Clear Flags is used on the foreground camera. The Culling mask of the foreground camera is set to a layer called "Foreground" (you'll have to add this yourself as a custom layer if you download the example package) and the gray plane is assigned to that layer. I have included the shader, but I don't think it's the problem here.
The ghosting seems to be caused by a lack of clearing of the RenderTexture between Camera renders. You can see it on the second screen shot: The horizontal ping-pong motion of the gray plane causes the ghosting effect. I tried to fix it by adding a RenderTexture.Release() each frame, but that causes it to appear darker so the ending of the fade doesn't match the live camera when they are swapped, which causes a jump in apparent brightness value. This is easiest to see in the example if you press M to stop moving, and press R to activate Release-each-frame mode. I think the "darkening" is actually fast flicker.
Thanks in advance for any help!
Key script on my "foreground" camera:
public class CameraFadeUpScript: MonoBehaviour {
 
               public Camera thisCamera;
 
               public bool inTransition; public bool releaseEachFrame=false; public float fadeSpeed;
 
               public float alpha = 1.0f;
 
               private RenderTexture renderTex; private Texture tex;
 
               // Use this for initialization void Start () {
 
               }
 
               void OnEnable() {
 
                if (renderTex==null) renderTex = new RenderTexture(Screen.width, Screen.height, 24);
 renderTex.Release();
 Debug.Log(Time.time + " Enabled");
 alpha = 0f;
 inTransition = true;
 thisCamera.targetTexture = renderTex;
 tex = renderTex;
 Debug.Log(Time.time + "FG cam enabled");
 
               }
 
               // Update is called once per frame void Update () {
 
                if (Input.GetKeyDown(KeyCode.R))
 {
     releaseEachFrame = !releaseEachFrame;
 }
 if (inTransition)
 {
     alpha = Mathf.MoveTowards(alpha, 1f, Time.deltaTime * fadeSpeed);
     alpha = Mathf.Clamp(alpha, 0f, 1f);
     Debug.Log(Time.time + "Update: " + alpha);
     if (releaseEachFrame)
     {
         renderTex.Release();
     }
     tex = renderTex;
     if (alpha > 0.99999f)
     {
         inTransition = false;
         thisCamera.targetTexture = null;
         renderTex.Release();
         Debug.Log(Time.time + "Transition to foreground complete");
     }
 }
 
               }
 
               void OnGUI() {
 
                if (inTransition && alpha < 1f)
 {
     GUI.color = new Color(1f, 1f, 1f, alpha);
     GUI.DrawTexture(new Rect(0, 1, Screen.width, Screen.height), tex, ScaleMode.StretchToFill, true);
     Debug.Log(Time.time + " GUI.DrawTexture");
 }
  
               } } 
Notes:
- This technique is similar to the CrossFadePro script in the wiki.
 - I tried a double-buffering solution with two render textures, where each frame it would alternate between drawing one and Release()-ing one, but this didn't seem to improve upon the darkening observed when you release the rendertexture every frame.
 - Side note, I noticed that the transition between GUI.DrawTexture and the live camera looks best if this rectangle is used: Rect(0, 1, Screen.width, Screen.height). Anyone else see a one pixel jump if you use Rect(0, 0, Screen.width, Screen.height)?
 
Screenshots:


Your answer