UI pixel size offset on low screen resolution devices

Hello!


This issue is kind of self explanatory, either way whenever I use a small screen resolution like on phones I’ve noticed pixels that are EXACTLY one pixel are not displayed properly? They appear to be bigger than a single pixel, this by itself isn’t a huge issue the issue comes with pixel movement at this scale, it appears very janky.

I’ve looked pretty much everywhere but I cannot seem to find any posts or mentions of this issue.

Images/Clips
Low Resolution

Image


image

Clip


Higher Resolution

Image


image


Just to clarify, the movement is moving EXACTLY one pixel diagonally, all I did was apply a .Unit to it but even without that it still happens.

2 Likes

Hi, do you mind sharing the device spec , i.e. device model that you observed the example for Low Resolution?

3 Likes

Hello! I assume you mean the Device Emulator? If so I used a custom emulator which I’ll provide a screenshot of the information of, but it works for pretty much any device that has a Low Screen Resolution, although it mainly affects mobile phones that come with studio by default.

Resolution (DPI): 100

Width: 320
Height: 180

Screenshot

2 Likes

Offset values are based on device independent pixels, which have an additional scaling factor applied. So for example, a phone might have an additional scaling factor of 2.0, which means each offset corresponds to 2 screen pixels. The goal of this scaling factor is so that pixels are roughly comparable sizes across phones with substantially different resolutions.

However, Roblox currently has a limitation where only integral offset values are supported. This can cause animations to jump a bit on phones with high resolution screens, because the offset values will move by 2 pixels at a time. For most UI this is fine but if you try and do pixel perfect animations it can be very apparent.

For now, this is probably working as expected - though if you have a place file to share I can investigate to see if anything else going wrong. Otherwise we’re currently looking at ways to support fractional offset values without breaking existing experiences

3 Likes

Thanks for the reply, here’s the place file! It’s slightly modified to remove most of the bloat the game has but movement should be the same. Not sure if the decals will load but I left them in just incase.

Game File.rbxl (76.6 KB)

3 Likes

I think there are a few potential issues here, although I don’t see anything that indicates a bug so far:

  • The positions you are computing for the sprite position are floating point. Because we don’t support floating point offsets, when covering this into sprite positions fraction values get dropped.
  • The sprite’s ActivePosition, move speed, et cetera all seem to be floating point values < 1, even if I run on a screen with a DPR of 1 like a desktop monitor. I think this is because you’re scaling everything by the player movement delta, and this may lead to uneven movement since the position gets rounded.
  • The resolution scale function seems iffy, though I’m not sure if that feeds into sprite positioning.

I would recommend some more investigation into how you’re computing sprite positioning and movement.

1 Like

Thanks for the help, also I should explain these with what I believe. Feel free to let me know if what I’m saying is incorrect.

  • I’m aware that it’s a floating point vector2 and I have it that way because, at least from my knowledge, :lerp() doesn’t work for non-float integers. However I don’t think this causes any issues as it just rounds both the X and Y axis.

  • I’m aware of this, but like I said, it SHOULD be rounding both the X and Y axis, also I do plan to fix this not working with delayed inputs in the future, this is mainly used to test how I would code this.

  • The resolution scaling uses Roblox’s UIScale instance, and the code for it rounds to the nearest whole number. The entire game map such as walls and player sprite is a descendant of a frame called GameUI, and that frame contains the UIScale. I tried disabling the UIScale and it still seems to presist so I doubt it’s anything to do with that.

I’d probably have to wait for this gets fixed if it does seem like a huge issue. Otherwise, I have to find a workaround. Not sure how I would do the latter.


Also, just as a reminder, my issue is that moving diagonally causes it to jitter, and when I tested it, I had a fixed move direction with no delay between setting the MoveDirection.