Page 1 of 3
[Help] Techniques for scaling
Posted: Mon May 06, 2024 6:02 pm
by glass2d
Background
I'm new to LOVE and could use some guidance on navigating certain aspects. Currently, I'm developing a top-down pixel art game with a 16:9 aspect ratio. The native resolution of the game is set to 480 x 270, and I've implemented the HUMP library for creating a camera that tracks the player. To maintain a consistent visual experience, I've opted for a camera scale of 4/3. When upscaling the game, such as to 1920x1080, I multiply both the camera scale and window dimensions by 4, ensuring proper scaling.
Issue
After scaling up, I've encountered tearing in the visuals. My game map is constructed using Tiled with a 16x16 tile set. Researching on forums, I found suggestions to use math.floor on the camera's x and y coordinates to address tearing. However, implementing this solution causes the player to appear jittery as the camera snaps to integer values. The player's movement is continuous in both x and y directions, while the camera's coordinates are floored. Additionally, I prefer to maintain the decimal scaling for the 4/3 camera scale, as it provides the best visual aesthetics. Some sources also recommend extruding the tiles to alleviate tearing, but I'm hesitant to undertake that task for every tile without certainty of its necessity.
I'm seeking insights into effective techniques to mitigate these issues while preserving the desired visual presentation.
Re: [Help] Techniques for scaling
Posted: Mon May 06, 2024 6:51 pm
by pgimeno
What do you mean by jittery? Do you mean it snaps to virtual 480x270 pixels, and you want it to have screen-pixel movement as opposed to virtual-pixel movement? I find it hard to imagine what can be producing the tearing with the data you've provided.
If you can, posting a .gif animation would help understanding what you mean exactly. Certainly, posting a .love file with a minimal test case would help even more - it doesn't even have to use the same assets as your production, just something basic that exhibits the problem.
Re: [Help] Techniques for scaling
Posted: Mon May 06, 2024 7:31 pm
by dusoft
Well, not flooring player movement, while camera movement is floored might cause some mismatch. Video or GIF would help as would the code as pgimeno said.
Re: [Help] Techniques for scaling
Posted: Tue May 07, 2024 2:32 pm
by RNavega
I think the inexact 4/3 camera scale at such a low fidelity will mess things up.
If your native canvas is really 480 x 270 then you should be able to draw the game screen at that size, without upscaling anything, and having it appear perfectly -- take a screenshot, go to some paint program and paste it and zoom in to see if the native graphics are coming out alright.
If you can get this native canvas / the ground truth looking fine (which you haven't exactly confirmed to have done yet), then you know that the problem is definitely coming only from the upscaling part.
Re: [Help] Techniques for scaling
Posted: Tue May 07, 2024 3:48 pm
by glass2d
I've added videos of the behavior I am describing.
1. 480_270 -> Cam at 4/3 zoom no tearing, not character blur
2. 1440_810 -> Cam at 4/3 zoom * 4 with tearing, no character blur
3. floor_cam_player_blur -> Cam at 4/3 zoom * 4 with tearing, math.floor cam x, y `self:lockPosition(math.floor(camX), math.floor(camY))` player blur in motion
Re: [Help] Techniques for scaling
Posted: Tue May 07, 2024 4:05 pm
by glass2d
Here is an example of what I'm seeing when I math.floor both the player and the camera movement. I see snapping in the background tiles during movement especially diagonal movement (FYI I scale the movement vector when the player is moving along the diagonal to limit the max speed)
Re: [Help] Techniques for scaling
Posted: Wed May 08, 2024 3:30 pm
by glass2d
I'm open to sharing my project publicly since I'm currently using placeholder assets. You can find the repository for the top-down game I'm developing here [
https://github.com/znimon/alchemist]. I'm still encountering issues understanding the root cause of tearing when I scale up both the window and the camera. Any insights into what might be causing this problem would be greatly appreciated!
Re: [Help] Techniques for scaling
Posted: Wed May 08, 2024 6:37 pm
by _JM_
I think I resolved the problem flooring player and camera position (maybe you did it the wrong way?)
Anyway, I attached a .love file with the fixes
These were my changes:
- add a global "Round" method get from lua programming book;
- use that function to round the camera position on playercamera:update;
- rounding the player position when drawing the sprite on player:draw
See if this was how it was supposed to work.
Re: [Help] Techniques for scaling
Posted: Wed May 08, 2024 8:00 pm
by glass2d
I tried what you're describing but I get the same "vibration" behavior as shown in the gif above. Observe how the fountain asset moves back and forth as the player moves along the diagonal. Here is my code...
utils.lua (Fn from Programming_in_Lua,_4th_ed._(2017))
Code: Select all
function round(x)
local f = math.floor(x)
if (x == f) or (x % 2.0 == 0.5) then
return f
else
return math.floor(x + 0.5)
end
end
playercamera.lua
Code: Select all
function PlayerCamera:update(dt)
local camX = Player.x
local camY = Player.y
local mapW = Map.width * Map.tilewidth
local mapH = Map.height * Map.tileheight
camX, camY = self:setBorders(camX, camY, mapW, mapH)
local rcamX = round(camX)
local rcamY = round(camY)
self:lockPosition(rcamX, rcamY)
end
player.lua
Code: Select all
function Player:draw()
local rpx = round(self.x)
local rpy = round(self.y)
self.anim:draw(self.spriteSheet, rpx, rpy, nil, nil, nil, 8, 16)
end
Re: [Help] Techniques for scaling
Posted: Wed May 08, 2024 9:53 pm
by _JM_
Hmm... try round the position of the player's body on syncPhysics method. Like this:
Code: Select all
function Player:syncPhysics()
local bd = self.physics.body
bd:setPosition(
round(bd:getX()),
round(bd:getY())
)
self.x, self.y = self.physics.body:getPosition()
self.physics.body:setLinearVelocity(self.vx, self.vy)
end