1. Hey! Guest! The 35th GMC Jam will take place between November 28th, 12:00 UTC - December 2nd, 12:00 UTC. Why not join in! Click here to find out more!
    Dismiss Notice

GMS 2 [SOLVED] - Sprite flickering when zoom out

Discussion in 'Programming' started by Skull_k, Sep 29, 2017.

Tags:
  1. Skull_k

    Skull_k Member

    Joined:
    Sep 21, 2017
    Posts:
    10
    Hello,

    In my project, i have a gun turrel throwing fireball. But when i zoom out, these fireball seems "flicker" or "sparkle". My fireball have only one sprite. I made a gif in order to be more clear :
    upload_2017-9-29_8-52-7.gif

    Another gif when i have no zoom.
    upload_2017-9-29_9-0-5.gif

    - My laptop have a resolution of 1366x768 (16/9).
    - In room editor, i have a room of 12800 x 2080. This room is the first one.
    - In room editor, i enable viewports.
    - In room editor, in cameras properties, i have 2880 x 1620 (ratio 16/9).
    - In room editor, in viewports properties, i have 960 x 540 (ratio 16/9).
    - In game option, interpolate colors is turn off. ( i tried with turn on, and there was any improvement)

    I did a lot of research about the topic and i tried to do everything right : ratio, game otpion etc...
    I also tried to implement my own camera system with camera_create (based on Shaun Spalding tutorial, or the post [GUIDE] Meet the New Camera System), but i had always the same results.

    What can i do to solve the problem ? For information, I would like to have this zoom out constantly during my game.
     
  2. Linkdeous

    Linkdeous Member

    Joined:
    Aug 16, 2017
    Posts:
    178
    Maybe check if you have the interpolate color between pixel, if it disabled, it may have impact on the visual, since the game will no longuer try to make them look clear, thus making very sharp movement/... leading to maybe this kind of problem where the sprite flickers
     
  3. Linkdeous

    Linkdeous Member

    Joined:
    Aug 16, 2017
    Posts:
    178
    If it doesn't work, try to check if your room have the right ratio in term of the view, since making your view 1.5 times bigger make the game try to make a 1.5 pixel, wich is kinda resizing the sprite in a 1.5 fashion, which when moved, can do pretty much strange things like this
     
  4. Skull_k

    Skull_k Member

    Joined:
    Sep 21, 2017
    Posts:
    10
    thank you for your reply. I already did your advice :

    - interpolate colours between pixels : i tried enabled and disabled. There is any improvement.
    - I have a ratio of 3. Cameras properties => 2880 x 1620 and viewports properties ==> 960 x 540.
     
  5. Skull_k

    Skull_k Member

    Joined:
    Sep 21, 2017
    Posts:
    10
    Hello,

    I still have the problem. Does anyone know why i have this problem ?
     
  6. Nathan Laing

    Nathan Laing Member

    Joined:
    Jul 31, 2016
    Posts:
    355
    I know of what you speak. It is a horrible dilemma. There are possibly several factors at play, even at the same time.

    You should try to make your image sizes in multiples of 2, or in heights and widths in a number cleanly divisible by 2.

    You should use/not use colour interpolation.

    You may wish to try controlling the zoom amount so that it increases or decreases by nice 'even' amounts (numbers that work well with your resolution).

    Do/do not floor or ceil the draw positions of your sprites.
     
    Last edited: Oct 3, 2017
  7. toxigames

    toxigames Member

    Joined:
    Jun 20, 2016
    Posts:
    190
    The pixelation of your sprite (in it's original large size) seems to be 1 pixel. When you zoom in/out effectively the sprite will be drawn scaled and that means when for example scaling down drawing 1 pixel will always draw that pixel at a fractional value which puts the computer in a dillema: should it expand the drawing of for example a 0.49 pixel so it take up 1 pixel(but that would be equal to not having zoomed at all) or should it draw such that 0.49 pixels becomes 0 (but that makes the pixel dissappear!)? So as you see the computer will be forced to choose between two bad choices. This is made worse when moving the sprite in a scaled view because even when moving the sprites position a nice value of 1 along either vertical/horizonal axis it will still translate to a fractional move distance on the screen, because we zoomed the view in or out. The "shimmering" you see is the computer doing exactly that, each step choosing to draw additional pixels or not for pixels that have been scaled to a fractional value and has to be drawn at a fractional position. You can confirm this if you open your scaled downed (zoomed out) gif in a gif supported image program and look closely on each frame, you will see that they are different from eachother because the computer makes different choices for those fractional pixels when moving them in a non-native view resolution.

    If you want to be able to scale down a sprite and get a completely consistent image you will have to make sure that the scale down never divides a pixel into a fractional value. You could make your sprite double size such that the image pixelation will be 2. Scaling down the sprite to half size (same as zooming out to make the view double size) you should not get any shimmering. However that's kind of a huge zoom step; going from for example a view size of 1920x1080 to 3840x2160.

    When I tested your sprite I tried zooming in/out my view (1920x1080) like this, using interpolation disabled I saw basically no shimmering, even on a black background:
    //zoom out
    view_wview[0] -= view_wview[0]*0.5;
    view_hview[0] -= view_hview[0]*0.5;
    //Zoom in
    view_wview[0] += view_wview[0];
    view_hview[0] += view_hview[0];

    But these are huge zoom steps.

    If you want to use small incremental zoom steps it's basically impossible to avoid having each pixel scaled to being drawn at fractional values. However the resulting shimmering is much more visible when using bright sprite colors upon a black background as you are doing here. If you were to use an interesting background (for example a nicely detailed dungeon floor etc) the shimmering would be a lot less noticable. And if you were to also use nice animation for that fireball the difference caused by 'fractionalized' pixels would also be very much concealed. And if you were developing for mobile with a condensed PPI (Pixels Per Inch) it should be even less noticeable.

    Interpolation can also very effectively help combat this "shimmering" effect, mostly when scaling down sprites (that is zooming out. Using interpolation on scaling up (zooming in) will just make the sprite blurry which rarely looks nice.), unless of course you want to preserve perfect pixelation for a retro type game, then you should probably not use interpolation. But then perhaps you shouldn't be scaling your sprites in the first place, or if you do you must scale them up/down such that pixels are never "fractionalized" but kept within a power to 2.

    Another option is to make additional handcrafted larger or smaller images to use when scaling. Of course this could lead to a massively increased workload for you and take up more space.
     
    Last edited: Oct 3, 2017
    Skull_k likes this.
  8. Skull_k

    Skull_k Member

    Joined:
    Sep 21, 2017
    Posts:
    10
    Hello !

    Thank you for your answers and your explanations :)

    @Nathan Laing :
    You should try to make your image sizes in multiples of 2, or in heights and widths in a number cleanly divisible by 2. ==> Sprite is 32*32 pixels
    Do/do not floor or ceil the draw positions of your sprites. ==> i will follow your advice for the future :) In my example, there is no floor or ceil.

    @toxigames : i tried with a multiple of 2 for scaling : i set up cameras properties to 1920 x 1080 and viewports properties to 960 x 540.
    There is a lot less "shimmering", but there is still a little "shimmering". I did a gif :

    upload_2017-10-4_14-42-1.gif


    Do you think it is normal ? I tried with "interpolate colours between pixels" enabled and disabled. There is any improvement.
     
  9. toxigames

    toxigames Member

    Joined:
    Jun 20, 2016
    Posts:
    190
    I don't get that unless I move it at a fractional speed. Are you moving it at a fractional speed like x += 1.5? Because that will create more "shimmer" due to the sprite being drawn at fractional positions. Try moving it only integer values like x += 2;
    Also make sure it's initial position is an integer, so x = an integer and y = an integer. Also your monitor does 1366x768 natively, so you should use that as the initial view setting to get the most clear image. Don't use my monitors dimensions :).

    But really as I mentioned a bright sprite like that on a black background makes this unfortunate effect much much more visible and it's hard to avoid, you'll have to get quite restrictive if you want to complete abolish it. I believe conceiling would be a much better method. So for example using some kind of background would do much to alleviate it. And if it were animated it would be a LOT less noticeable, actually I don't think people would spot the issue if the fireball was animated. I mean the reason we see an issue here is because the broken image pattern from gamestep to gamestep is so easily noticed. If an animation played then each animation frame would be different to eachother on purpose, so that would be breaking the pattern in a controlled and nice way! (there's no way anyone would be able to spot that the computer didn't paint different downscaled frames pixels exactly as the 1:1 scale frame. So in fact the shimmering would still be there, but no one would be able to notice it).

    Also how do you capture lossless gif animation? I would like to show you how it looks on my screen; even with a blackground, no interpolation and no animation I can practically avoid the issue by restricting it's draw positions: make sure to move at an integer speed, and that the zoom happens by halving the resolution (starting with my monitors native resolution). But again zooming in such huge steps is hardly ideal in many situations.
     
    Last edited: Oct 4, 2017
    Skull_k likes this.
  10. Skull_k

    Skull_k Member

    Joined:
    Sep 21, 2017
    Posts:
    10
    Thank you for your explanation :)

    The shimmering has disappeared when i changed the speed to 4 (compared to 5 previously). For information, cameras properties = 1920 x 1080, viewports properties = 960 x 540 and interpolate colours between pixels is disabled. There is any shimmering when speed is a multiple of 2 and sprite's position have no influence as far as i know : i tried integer and non-integer. I understand now why there is a shimering. Thank you again :)

    I am totaly agree with you, i know that it will be very hard to abolish it completely, and i don't want to do it because it is almost imposible. There is too much constraints. We cannot build a game with only multiples of 2 for speed. I just want my game looks good.

    I wanted to understand the root cause of the problem and thanks to you i got it. Now, I can manage the issue more easily.
    For sure, I will follow your advices and pay attention to background, sprite's animation, scaling, speed.
    Thank you for your time toxigames.

    By the way, i use LICEcap for my gif. It is a free software : it is not completely lossless, but this is the best i have found. (https://www.cockos.com/licecap/).
     
    toxigames likes this.

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice