Hi guys, I’m stuck with a problem I haven’t found a solution yet. Krisse noticed that the objects in the mario demo I made have a little flick when the screen is moved.
It happens because of the rounding from a real position (I’m using fixed 23-9 math) to integer position which represent the pixels on the screen. So there’s obviously information lost because of the fixed math a the rounding to integers.
I know that in current hardware the solution to these kind of problems is to use anti-aliasing, but being the VB too week to handle that, which solution do you suggest?
Hmm… I’m not sure I understand what the problem is. Since the screen is in pixels, rounding to the nearest pixel is the best you can do. Can you describe the problem more, or explain exactly how I can see it?
This is funny, I was working on Zelda again yesterday, adding more objects, and I noticed the exact same effect in my engine, caused by the same reasons 😛
The problem is, rounding to the nearest pixel rounds to one of two adjacent pixels depending on how much the screen has scrolled, making objects that are supposed to stand still relative to the background look like they wobble back and forth as the background scrolls…
Here’s some frames of Mario moving to the right. If you look at the positions of the front and back layers, they don’t move smooth relative to each other.
Yeah, I did kinda notice that… I wasn’t sure if that’s what you were talking about (it wasn’t obvious enough to the naked eye that it was happening, just that something seemed a little weird). I’m still not sure how rounding to the nearest pixel can cause that problem though.
Assuming right is + and left is -… if you move to the right, the number should always get larger, whether fractional or not, and shouldn’t bounce between one or the other. If you have 2.3=2 and move right .2 you get 2.5=3. Move right .001 and you get 2.501=3. I don’t see how moving in the same direction can cause it to round the wrong way (especially 3px to 6px like K showed).
Can you descibe the process on how your fixed pt. numbers change, and how the rounding works? The problem doesn’t make sense to me, so I’m just trying to figure out exactly what’s happening.
Sure, the objects in my engine are positioned in 3D Space, so when you create a game world you place things with x,y and z coordinates.
Here is the calculation:
position2D->x = FIX23_9_ROUNDTOI(position3D->x +
_optical->horizontalViewPointCenter – position3D->x,
I will use numbers out of my head to illustrate the problem:
We have two objects at the same x coordinate 100, but at different z positions: 64 and 83 for example. At the moment of project the x position from 3d to 2d space let’s say that
– 64 becomes 50.48 rounded to 50
– 83 becomes 74.16 rounded to 74
When the screen moves there will be moment in which the projected position from 64 will be rounded to 51, but 83 will be rounded still to 74.
From my understanding because some positions get rounded first than others to the next pixel is what causes the problem.
Ah… so in the example K posted, the 4, 3, 3, and 6 pixel distance is just a difference relative to each other and neither are absolute to the screen? Hmm… lemme think about this… still not sure I totally understand the problem (seems like rounding should only be one pixel off). Does it still do the same thing if you just truncate the number (floor, as in >>9) rather than rounding?
Have you tried outputting coordinates for debugging, so you can compare the results with a hand-calculation?
Yes the problem should be just 1 pixel, that’s why it’s not that much noticeable. I cannot notice the 3, 4, 4 and 6 pixel from the pictures.
Krisse, can you specify between which 2 objects are you measuring the number of pixels so I can take a look at their coordinates progression? Is it between the japanese arc and the middle bridge part?.
Ok I’ve isolated the problem and can now see Krisse’s point. I’m looking into it. Will post soon an update on the matter.
Hey Krisse, I’ve doing some testing on this matter, and moving the screen one pixel at a time never producer a jump as big as in your captures ( from 3 pixels to 6 in a single screen move). The difference between the japanese arc an the background platform always rises/decreases by one.
I recorded the change in distance for both object’s positions on screen (projected to 2d space) and the change in distance was always of 1 pixel. It did go back and forth because of rounding to an integer. Now the difference when moving the screen to the right and the objects are closer to the left of the screen will always increase because the object closer to the screen moves faster.
Maybe the jump from 3 to 6 pixels you got was because in a single update mario moved more distance, remember that I’m using independent framerate move, so it’s possible for mario to displace more distance in a given frame because of the drop of frame rate.
I will try to find a way to solve the rounding problems, but I don’t think it’s that easy to do. So there is another work around to solve it:
The engine uses the Sprite_setPosition method to calculate the x and y coordinates to render a bgmap based on the object’s 3d position in space. It is possible to inherit a new class from Sprite and make it to calculate the same position based on other factors i.e: each layer having a different velocity when the screen scrolls. But such solutions are a specialization of an specific requirement for a sidescroll game, and as such it does not make sense to include into the core engine since the whole engine is designed from the premise that every game world is a 3d space with objects defined by their 3d coordinates.