Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Scrolling Jitters when using Pixel perfect camera

Discussion in '2D' started by 9uile, Sep 6, 2020.

  1. 9uile

    9uile

    Joined:
    Mar 11, 2016
    Posts:
    32
    Hi,
    I have some jitters when using the Pixel perfect camera asset.
    This is a shmup project. I have a level and a camera. The scrolling script is on the camera, so the level transform position stays static and the camera goes to the right.

    settings : ppu 16, res 320*180, Upscale Render Texture = ON
    I need Upscale Render Texture because i need all pixels on the grid (e.g during asteroid rotation).


    To not be disturb by my current project (with a lot of stuff not related to my problem), i make a new simple project to show you the issue. You can see that the ground movement is not fluid. By changing the SpeedX value, sometimes it's better and sometimes worse...

    https://www.dropbox.com/s/fc7ma3ew5q626zc/ShmupScrolling(pixelperfectCam).zip?dl=0



    Can you help me ?
    :)
     
    Last edited: Sep 7, 2020
    Dieter_Dagger likes this.
  2. eses

    eses

    Joined:
    Feb 26, 2013
    Posts:
    2,637
    Hi @9uile

    I bet it simply is caused by the fact that you are targeting such a low resolution (320x180).

    There will be moments when the background won't move in some rendered frame.

    You see similar happening in 80's shmups like R-Type, even if the game runs 60fps. See this video, and check the first level part:
     
    Dieter_Dagger likes this.
  3. spryx

    spryx

    Joined:
    Jul 23, 2013
    Posts:
    558
    Took a look at your project:

    When you "upscale render texture", you are effectively telling unity "Hey, I want you to scale this source texture (Camera.main) to this resolution". Assuming the render texture is larger than source, Unity still needs to "get" that data from somewhere. The texture is interpolated.

    Consider:
    1. Move Main Camera
    2. Render Camera.Main
    3. Rescale this to match reference res with interpolation ("fill in the missing pieces").

    The scrolling speed being slow makes this super noticeable. If you double it to "5" with the current settings, you will notice the motion is much smoother. If you can get away with it, i'd turn the upscale off altogether.

    I'm not a graphics guy and admittedly, this is my best guess of what is happening. I will also be the first to admit that something else could be wrong.

    TLDR: Camera's slow transform movement when upscaled from 320x180 is being trounced by rendertexture interpolation.
     
    Last edited: Sep 6, 2020
  4. 9uile

    9uile

    Joined:
    Mar 11, 2016
    Posts:
    32
    Thank you, i can see the jitter in your link. I will try a higher res to see if the issue will be minimized.
     
  5. 9uile

    9uile

    Joined:
    Mar 11, 2016
    Posts:
    32
    Thanks for trying my demo project ! I will try to find a better scrolling value. Unfortunately, i really want to use 'upscale render texture'...
     
    Last edited: Sep 7, 2020
  6. 9uile

    9uile

    Joined:
    Mar 11, 2016
    Posts:
    32
    Thanks to help from another forum, I have improvements !
    I modified my scrolling script attached to my camera like this :

    Code (CSharp):
    1. public class Scrolling : MonoBehaviour
    2. {
    3.     public float SpeedX;
    4.     public float SpeedY;
    5.     public float pixelsPerUnit;
    6.  
    7.     public bool FixJitters; //launch a built to see the result (may still have jitters in editor)
    8.  
    9.  
    10.     void Update()
    11.     {
    12.         transform.Translate(SpeedX * Time.deltaTime, SpeedY * Time.deltaTime, 0);
    13.  
    14.         if (FixJitters)
    15.         {
    16.             int i_x = Mathf.FloorToInt(transform.localPosition.x * (float)pixelsPerUnit);
    17.             int i_y = Mathf.FloorToInt(transform.localPosition.y * (float)pixelsPerUnit);
    18.             int i_z = Mathf.FloorToInt(transform.localPosition.z * (float)pixelsPerUnit);
    19.             //Vector3 oldPos = transform.localPosition;
    20.             Vector3 p = new Vector3((float)i_x / (float)pixelsPerUnit, (float)i_y / (float)pixelsPerUnit, (float)i_z / (float)pixelsPerUnit);
    21.      
    22.             transform.localPosition = p;
    23.         }
    24.     }
    25. }
    There are (almost) no more jitters now, like you can see here :
    https://twitter.com/9uileTweet/status/1303457642434658304?s=20

    I don't understand why but when SpeedX is below 4, there was a lot of jitters and below 3.5 the scrolling don't move !
    Then i modified the code again by using scrolloffsetX because if the movement is under a pixel, 'p' replace the camera at the same position.

    Code (CSharp):
    1. void Update()
    2.     {
    3.         //transform.Translate(SpeedX * Time.deltaTime, SpeedY * Time.deltaTime, 0);
    4.         transform.position = transform.position + new Vector3((SpeedX * Time.deltaTime) + scrolloffsetX, SpeedY * Time.deltaTime, 0);
    5.      
    6.         if (FixJitters)
    7.         {
    8.             Vector3 oldPos = transform.localPosition;
    9.  
    10.             int i_x = Mathf.FloorToInt(transform.localPosition.x * (float)pixelsPerUnit);
    11.             int i_y = Mathf.FloorToInt(transform.localPosition.y * (float)pixelsPerUnit);
    12.             int i_z = Mathf.FloorToInt(transform.localPosition.z * (float)pixelsPerUnit);
    13.  
    14.             Vector3 p = new Vector3((float)i_x / (float)pixelsPerUnit, (float)i_y / (float)pixelsPerUnit, (float)i_z / (float)pixelsPerUnit);
    15.          
    16.             scrolloffsetX = oldPos.x - p.x;
    17.          
    18.             transform.localPosition = p;
    19.         }
    20.     }
    I store the X offset like this :
    scrolloffsetX = oldPos.x - p.x;

    and then add this offset in this line :
    transform.position = transform.position + new Vector3((SpeedX * Time.deltaTime) + scrolloffsetX, SpeedY * Time.deltaTime, 0);

    Now, the scrolling occurs with SpeedX values below '4' but it wasn't fluid even with higher values than '4'.

    I put a link to the demo project if somebody want to see (you need to built the project because results can be weird in the editor):
    https://www.dropbox.com/s/fc7ma3ew5q626 ... 9.zip?dl=0
     
    stardewv971 likes this.