Search Unity

2D Sprite Jitters

Discussion in 'Cinemachine' started by bowserscastle, Apr 3, 2018.

  1. bowserscastle

    bowserscastle

    Joined:
    Jul 9, 2017
    Posts:
    14
    So I've gone through all the threads concerning 2D sprite jittering problems and learned a lot, but none of the solutions seem to fully fix what I'm seeing.

    I'm got a very simple "player object" moving across a Tilemap and a CM Virtual Camera following it. The CMVC has an Ortho size of 16, and all sprites are 32px with 32 PPU. Resolution is locked to 1280x1024. The CMVC is using a framing transposer on the player object. The CM Brain Update Method is set to FixedUpdate(), though I've tried the other two to no avail. Unity 2017.4.0f1, and CM v2.1.10.

    The player object has a Rigidbody 2D on it, Body type: Dynamic, Interpolate: None.
    I'm moving the player object only in FixedUpdate() by adjusting the velocity on the Rigidbody.

    As you can see in this video:
    there's a pretty apparently jitter (when you adjust the scale). I've uploaded a sample project here that demonstrates the problem. I can see the transform position shifting back and forth as the object jitters, but from what I've seen on other threads, that can be a symptom, not a cause.

    Thank you in advance for any pointers!
     
    Last edited: Apr 3, 2018
  2. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,728
    I downloaded your project and am able to see the jittering.
    The thing is, it happens even when the CM brain is disabled (and therefore NOT moving the camera).
    You can see it here, I'm just resizing the inspector, player not moving, camera not moving.
    I think it has something to do with the way the sprite is rendered, some kind of pixel rounding.
     

    Attached Files:

    Last edited: Apr 3, 2018
    bowserscastle likes this.
  3. bowserscastle

    bowserscastle

    Joined:
    Jul 9, 2017
    Posts:
    14
    Thank you for taking a look!

    The ortho size in that gif is 8.40625 - does that have something to do with it? I have the resolution locked to 1280x1024, and when you combine that with the ortho size calculation being done in the attached script:
    (Screen.height / 32) / 2

    we get a camera size = 16. When I resize the inspector with the resolution locked, I don't see the jittering. I only see it when moving the player sprite.
     
  4. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,728
    OK I figured it out. The problem is that the camera is positioned between pixels, and for some reason the background and foreground sprites are rounding differently. The solution would be to make sure that the camera never moves to a sub-pixel position.

    Here is a little script that post-processes the vcam's position to force it onto pixel boundaries. Add it to your project, then select it as an extension on your vcam:

    Code (CSharp):
    1. using UnityEngine;
    2. using Cinemachine;
    3.  
    4. [ExecuteInEditMode] [SaveDuringPlay] [AddComponentMenu("")] // Hide in menu
    5. public class RoundCameraPos : CinemachineExtension
    6. {
    7.     public float m_PixelsPerUnit = 32;
    8.  
    9.     protected override void PostPipelineStageCallback(
    10.         CinemachineVirtualCameraBase vcam,
    11.         CinemachineCore.Stage stage, ref CameraState state, float deltaTime)
    12.     {
    13.         if (stage == CinemachineCore.Stage.Body)
    14.         {
    15.             Vector3 pos = state.FinalPosition;
    16.             Vector3 pos2 = new Vector3(Round(pos.x), Round(pos.y), pos.z);
    17.             state.PositionCorrection += pos2 - pos;
    18.         }
    19.     }
    20.  
    21.     float Round(float x)
    22.     {
    23.         return Mathf.Round(x * m_PixelsPerUnit) / m_PixelsPerUnit;
    24.     }
    25. }
    26.  
    upload_2018-4-3_11-18-53.png

    Let me know if this fixes the problem.
     
    Zodd, Kizaqt, Deeeds and 1 other person like this.
  5. bowserscastle

    bowserscastle

    Joined:
    Jul 9, 2017
    Posts:
    14
    I only "Liked" your post because these forums have no option to "Love" posts.
    Thank you! This script fixed the issue.
     
    Kizaqt and Gregoryl like this.
  6. Kizaqt

    Kizaqt

    Joined:
    Nov 3, 2018
    Posts:
    1
    Another newbie who just had 2 days of frustration on this same issue as a result (I guess) of background tilemap rounding differently to the foreground sprites. Pixel snapping extension script solved my issue.
    Thanks for both working out the problem and solving it Gregory!
     
    bowserscastle and Gregoryl like this.
  7. ShervinM

    ShervinM

    Joined:
    Sep 16, 2017
    Posts:
    67
    Hi guys! I'm running into a similar issue, and wanted to check out your extension @Gregoryl . I'm working on unity 2019.1.10f1, and whenever I try to select an extension, the box remains as "(select)". Have you heard of this happening?
     
  8. ShervinM

    ShervinM

    Joined:
    Sep 16, 2017
    Posts:
    67
    Ah I had some other compiler issues that were getting in the way, apologies for the hasty question. In any case, I managed to get the extension, but it seems like my problem must be something else. Much like @bowserscastle , I've been looking at quite a few posts on achieving pixel perfect games, and 2d jitter, particularly the following post: https://gamedev.stackexchange.com/q...57021?newreg=eeff1626394749b1a5570cad5d2f4a72

    (By the way, is that you @Gregoryl ?).

    I've attached a gif of the issue im observing. Notice how pieces in the environment (the top row of furniture) jiggle up and down when the camera moves. This is particularly evident when the camera makes more up and down motions.

    As from the other link, I've taken precautions and set up my game as follows:
    - I've turned off anti-aliasing and anisotropic textures
    - Specifically targetting 1920 x 1080
    - All sprites have a PPU of 20
    - The camera has an orthographic size of 13.5 (this means that I'm showing 27 units of the world vertically, for 20 sprite texels, which means 540 texels vertically (20 * 27). This is half of 1080, so I should be good on this account right?
    - I'm using a cinemachine vcam that is following my target object (the moving chair in this case).
    - I'm using a framing transposer
    - I'm using a cinamchine confiner
    - The brain is updating on Fixed Update
    - the motion of my target is using rigidbody (non kinematic) by changing the velocity directly. These updates are also done in fixed update.

    Any ideas what might be going on? Any help would be very much appreciated!

     
  9. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,728
    It looks to me as though the problem is in the code that places the furniture. The camera is moving nicely (thanks to the position rounding, I presume), but the furniture seems to be suffering from a similar position rounding problem. Can you round its position in the same manner as the camera?
     
    ShervinM likes this.
  10. ShervinM

    ShervinM

    Joined:
    Sep 16, 2017
    Posts:
    67
    Hi Gregoryl!

    Thanks so much for getting back to me!

    I went ahead and made a quick monobehaviour to set the transform.position of the object to the rounded xyz based on the same ppu (just like the camera extension):


    Code (CSharp):
    1. using System.Collections;
    2. using UnityEngine;
    3.  
    4. public class SnapEnvironment : MonoBehaviour
    5. {
    6.  
    7.     public float m_PixelsPerUnit = 20f;
    8.  
    9.     float Round(float x)
    10.     {
    11.          return Mathf.Round(x * m_PixelsPerUnit) / m_PixelsPerUnit;
    12.     }
    13.  
    14.     private void Update()
    15.     {
    16.          transform.position = new Vector3(Round(transform.position.x),
    17.                                        Round(transform.position.y),
    18.                                        Round(transform.position.z));
    19.     }
    20. }
    I also realized the camera extension you provided wasn't rounding for the z axis (but in my case, the camera is facing towards the x & z plane at a 45 degree angle, and thus moves along the x and z axis, with a fixed y position).

    So I also amended your code to the following:
    Code (CSharp):
    1. ...
    2.             Vector3 pos2 = new Vector3(Round(pos.x), Round(pos.y), Round(pos.z));
    3. ...
    I've attached a gif of the result below. What do you see?

    All of the furniture pieces have the new snap monobehaviour EXCEPT for the right armchair.

    Personally I see less jitter with the armchair to the left, and the top fern, but the others still seem to go crazy.


    Some more information about my scene:
    - The tilemap is sitting on the x & z plane with (interestingly, no jitter here...)
    - Each furniture object is made of a parent root object with nothing but a transform, and then a child object with a sprite renderer with the transform at 45 degrees on the x axis. Both the parent and the child have the snap monobehaviour.
    - As mentioned before, my camera is on a 45 degree angle, facing directly with the 45 degree tilted furniture.


     
  11. yuanxing_cai

    yuanxing_cai

    Unity Technologies

    Joined:
    Sep 26, 2014
    Posts:
    335
    Hi! If you're willing to try out the latest alpha version of Unity 2019.3, then we have a new CM extension in the 2D Pixel Perfect package that enables you to use Cinemachine with the Pixel Perfect Camera. We have code in the Pixel Perfect package that synchronizes the pixel snapping behaviors of the camera and the sprites, which might help in your case.
     
    bowserscastle likes this.
  12. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,728
    I'm definitely seeing some jitter in the furniture. I wonder if it's due to the 45 degrees. Maybe the rounding algorithm is too naive, and you have to modify it to take that angle into account.
     
  13. Juandapp

    Juandapp

    Joined:
    May 11, 2016
    Posts:
    53
    Thank you,

    I am using that combination, and I have strange movements in my character, if you can help me, I have put my evidence here. https://forum.unity.com/threads/cinemachine-with-pixel-art-2d-problem.777587/
     
  14. DaydreamStudio

    DaydreamStudio

    Joined:
    Aug 12, 2022
    Posts:
    1
    Hello

    I really do hope you don't mind me commenting on this thread... It's just that I'm researching a problem I've been having for weeks and came across this thread. Reading through it, it seemed to be the solution to all my problems.

    I'm having trouble with my Game Objects jittering vertically while my Cinemachine camera is scrolling/panning. Basically the exact same problem as @ShervinM, looking at their video. My game is also almost exactly the same as theirs design wise too. My game is 2.5D (using 2D Pixel Art sprites in the 3D engine with an orthographic perspective) with everything sitting on a x & z plane at an angle, along with the camera facing the same angle as everything else.

    I got really excited when I saw your RoundCameraPos script as I was SURE using it, amending it to work for x & z, and attaching it to my vcam would fix everything... But unfortunately, everything is still the same as before and my jitters haven't changed. I also tried Shervin's SnapEnvironment script to see if that would fix it too (I hope they won't mind) but no luck.

    However, I did notice that my x & z position coordinates don't seem to be any different to before, even with the scripts attached. The numbers still go on forever when the camera moves e.g. 226.557845 lol. If the rounding script is working, then those numbers shouldn't be that long anymore right? Maybe I've missed a simple step?
     
  15. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,728
    @DaydreamStudio Have you solved this? If not, would you be willing to DM me a project that has this problem?