Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • 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?

Show more comments

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.

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

Disabling all Cameras Android/Iphone 1 Answer

Camera.main.WorldToScreenPoint(touch.position). Help !!! 1 Answer

Why does Unity add to a manifest when building? 1 Answer

make android camera video as the background of the unity scene? 0 Answers

Gyroscope Orbit Android 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