• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
2
Question by daemionx · Aug 02, 2012 at 06:35 PM · androidcameravsyncflickertearing

Second Camera Tearing on Android

I'm using two cameras to render my scene - the main camera (depth 0) clears everything, has a perspective projection, and renders everything but my GUI. The second camera (depth 10) clears the depth buffer, has an orthographic projection, and renders just the GUI. This works great except in rare instances, parts of my GUI are tearing. The main camera doesn't seem to have any tearing issues but the camera isn't moving most of the time so you probably wouldn't notice anything anyways.

I've tried using VSync which made things arguably worse - I've tried doing it every other vblank which made the problem almost disappear but not quite.

This is on a Kindle Fire - I have no issues on any other device I've tried this on so far.

Any ideas? Also, why would the backbuffer be allowed to be flipped before all the cameras are done rendering anyways?

Here are some screenshots I made based on what it looks like on the device.

What it's supposed to look like:

alt text

What it looks like when the GUI flickers/tears (note that although most of the GUI isn't being drawn, part of the text is being drawn. All of the GUI is being rendered as textures on meshes on a layer called 'GUI' that is drawn by the "GUICamera" as mentioned before):

alt text

EDIT: Attached some screenshots.

normal.png (209.0 kB)
tearing.png (203.3 kB)
Comment
Add comment · Show 13
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image ScroodgeM · Aug 02, 2012 at 09:02 PM 0
Share

can you explain 'parts of my GUI are $$anonymous$$ring'? could you make a screenshot? it's will be nice.

avatar image daemionx · Aug 02, 2012 at 09:24 PM 0
Share

I added some screenshots. What I mean is that a portion of my GUI is being drawn while another portion is not. When I draw larger textures for dialog boxes, it seems like the top 20% of the image remains while the bottom 80% will be cut off (horizontally). It seems very much like a standard $$anonymous$$ring issue but is only affecting cameras beyond my main camera.

avatar image ScroodgeM · Aug 02, 2012 at 09:28 PM 0
Share

just for testing: try to disable cameras and draw them manually using 'camera.Render();' in correct order in Update() function

avatar image daemionx · Aug 02, 2012 at 09:35 PM 0
Share

I actually tried that already and it was much worse.

avatar image ScroodgeM · Aug 02, 2012 at 09:37 PM 0
Share

if you render ONLY second camera with GUI - is GUI looks ok?

avatar image daemionx · Aug 02, 2012 at 09:41 PM 0
Share

Yeah, that's fine also - it's actually fairly difficult to get the flickering to occur. It generally only happens on very busy levels with lots going on, more draw calls, etc.

avatar image daemionx · Aug 02, 2012 at 09:57 PM 0
Share

Also, I sometimes have menus where I'm just rendering the GUI with the GUI Camera (the main camera is turned off) and then I'm rendering things on top of the GUI with a camera that has an even higher depth. This "on top" camera will also sometimes flicker. Again, it seems to only happen to cameras beyond the first one used to render.

avatar image Bovine · Aug 02, 2012 at 10:25 PM 0
Share

Do you get the same in the editor?

it looks odd, but it doesn't look like $$anonymous$$ring, it looks like clipping or Z fighting. What are your near and far clip planes set to?

avatar image daemionx · Aug 02, 2012 at 11:22 PM 0
Share

No, only on the $$anonymous$$indle Fire (tried it on some other Android Tablets and don't get the same problem). I don't think it's Z-fighting because the camera clears the depth buffer and the text is the only thing at that location for instance. Regardless, the near plane is 2, the farplane is 100, and the text for example is 70 world units from the camera.

avatar image ScroodgeM · Aug 03, 2012 at 06:36 AM 0
Share

looks like hardware issue. if so, the easies way to avoid this, not to fix. one of possible ways is to render all cameras except main to render textures and draw them on top of all by main camera. did you try this?

avatar image HazeTI · Aug 09, 2012 at 09:39 AM 0
Share

Now this is interesting because we're seeing something similar. We've got a second camera which we use to render our GUI and only on the $$anonymous$$indle and only in certain places our GUI flickers, as if the camera is sometimes not being rendered. We've not found a solution ourselves yet although for us it doesn't relate to how busy the device is. It can happen even on screen where very little is going on.

avatar image daemionx · Aug 09, 2012 at 05:32 PM 0
Share

@Scroodge$$anonymous$$: It will take quite a while to adjust our shaders to render to texture, apparently - they don't write to the alpha channel, yet, so I'm unable to render them as an overlay. Also, the last time I played with render textures on device, the performance was terrible - I've made many performance optimizations in our game so maybe it will now be fast enough, though. When I eventually have time to try this, I'll update the thread.

@HazeTI: For us, this actually usually happens on scenes where a medium amount of things are going on. I have been able to force this to happen all the time by doing things such as setting the Frames Per Second manually to > 25 FPS (i.e. 30, 40, 50, or 60) and turning off VSync, or by Turning VSync on every Frame. If I turn the frame rate very low, I haven't been able to reproduce the problem (i.e. 15 FPS).

avatar image ScroodgeM · Aug 09, 2012 at 10:23 PM 0
Share

do you use NGUI for GUI? i got one interesting issue today with it 8)

one more hint: try to reproduce the issue with second camera that draws a static something, cube for example. just to be sure your issue is not caused by some image effects or something like it.

1 Reply

· Add your reply
  • Sort: 
avatar image
2
Best Answer

Answer by daemionx · Aug 27, 2012 at 09:42 PM

I was ultimately able to fix this by creating a camera that gets rendered before any other cameras (depth -100). This camera has its script execution order set to run after everything else. Each frame it does the following:

  1. In LateUpdate it disables all other cameras.

  2. In OnRenderImage, it sets texture of each camera to the source render texture and renders them manually (it internally keeps a list of depth sorted cameras).

  3. A coroutine I set to run (in LateUpdate) that yields WaitForEndOfFrame reenables all of the cameras (a lot of logic in other parts of the code depended on various cameras existing/being enabled).

Unfortunately rendering to texture is SLOW on any version of Unity prior to 3.5.3 (a separate issue we're looking into) and we are having problems with 3.5.3 and later crashing so aren't actually using this solution right now.

Here's the code in case anybody is interested:

 public class CameraCombiner : MonoBehaviour
 {
     private int frameSkip = 0;
     private List<Camera> camerasToCombine = new List<Camera>();
     
     private static CameraCombiner instance;
     
     private static bool quitting = false;
     
     void OnApplicationQuit() {
         quitting = true;
     }
     
     public static CameraCombiner Instance() {
         if (Application.isPlaying && instance == null && !quitting) {
             Debug.LogWarning("CREATING CAMERA COMBINER");
             Debug.LogWarning("###################################################################################");
             
             GameObject cameraCombinerGameObject = GameObject.Find("CameraCombiner"); 
             if (cameraCombinerGameObject == null) {
                 cameraCombinerGameObject = new GameObject("CameraCombiner");
                 Object.DontDestroyOnLoad(cameraCombinerGameObject);
             }
             
             Camera fakeCamera = cameraCombinerGameObject.GetComponent<Camera>();
             if (fakeCamera == null) {
                 fakeCamera = cameraCombinerGameObject.AddComponent<Camera>();
             }
             fakeCamera.cullingMask = 0;
             fakeCamera.depth = -100;
             
             CameraCombiner combiner = cameraCombinerGameObject.GetComponent<CameraCombiner>();
             if (combiner == null ) {
                 combiner = cameraCombinerGameObject.AddComponent<CameraCombiner>();
             }
             instance = combiner;
         }
         return instance;
     }
     
     void OnEnable()
     {
         if (Application.isPlaying)
         {
             frameSkip = 1;
         }
     }
     
     private IEnumerator OnFinishedRenderingEverything() {
         yield return new WaitForEndOfFrame();
         foreach (Camera cameraToCombine in camerasToCombine) {
             if (cameraToCombine != null && cameraToCombine.gameObject.active) {
                 cameraToCombine.enabled = true;
             }
         }
     }
     
     void LateUpdate() {
         StartCoroutine(OnFinishedRenderingEverything());
         foreach (Camera cameraToCombine in camerasToCombine) {
             if (cameraToCombine != null && cameraToCombine.gameObject.active) {                
                 cameraToCombine.enabled = false;
             }
         }
     }
     
     void OnRenderImage(RenderTexture source, RenderTexture destination) {
         if (frameSkip > 0)
         {
             frameSkip--;
             return;
         }
         
         foreach (Camera cameraToCombine in camerasToCombine) {
             if (cameraToCombine != null && cameraToCombine.gameObject.active) {                
                 cameraToCombine.targetTexture = source;
                 cameraToCombine.Render();
                 cameraToCombine.targetTexture = null;
             }
         }
         
         Graphics.Blit(source, destination);
     }
     
     private static int CompareCameraDepths(Camera lhs, Camera rhs) {
         if (lhs == rhs) return 0;
         if (lhs == null) return -1;
         if (rhs == null) return 1;
         return lhs.depth.CompareTo(rhs.depth);
     }
     
     public void RegisterCamera(Camera camera) {
         if (!camerasToCombine.Contains(camera)) {
             camerasToCombine.Add(camera);
             camerasToCombine.Sort(CompareCameraDepths);
         }
     }
     
     public void DeregisterCamera(Camera camera) {
         camerasToCombine.Remove(camera);
     }
 }
 
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

10 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Android Cardboard - Fake UI Overlay 0 Answers

Android Unity ARCore camera access 0 Answers

OnRenderImage in one of the two cameras, Android showing only post processed camera. 1 Answer

WebCamTexture and VSync (iPhone 4) 3 Answers

Android VSync Auto-Enabling 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges