Sprite shearing to fake rotation
Moderator: Moderators
Sprite shearing to fake rotation
A radian is the angle whose arc length is the same length as the circle's radius. For example, if something moves through an arc of 0.4 radians, it'll have moved through a distance 40% of that to the center. If your game has 16-direction movement, there's a gap of (2*Pi/16) = about 0.4 radians between positions. For example, if something has 16 frames of rotation and a lever arm 20 pixels long, the end will move by 8 pixels between one angle and the next.
In this figure, an angle close to 22.5 degrees or 0.4 radians is marked in red, and a distance of 40 percent of the radius is marked in green.
Now say I have something spinning on an off-center axis, such as a ball on a chain or a character swinging on a trapeze. From the axis of rotation to the active part is 20 pixels. But with 16 frames of animation (8 stored, 8 flipped), that's still about 0.4 radian per frame. So when the object rotates through 1/16 of a circle, its active part instantly moves about 8 pixels, enough to confuse collision detection, eject the object the wrong way, and cause it to glitch through a wall.
I could try shearing the rotating sprite by sliding the 8-pixel strips. This is analogous to how games use "Y offset per column" background modes of the Super NES PPU and Sega Genesis VDP to fake rotation; psycopathicteen could tell you more about these modes. Sliding each strip by 1 pixel works for up to 1/8 radian (7.16 degrees) either way.
Or I could try decoupling the collision position from the display position so that the active part moves smoothly despite discrete angle changes in the sprite.
In this figure, an angle close to 22.5 degrees or 0.4 radians is marked in red, and a distance of 40 percent of the radius is marked in green.
Now say I have something spinning on an off-center axis, such as a ball on a chain or a character swinging on a trapeze. From the axis of rotation to the active part is 20 pixels. But with 16 frames of animation (8 stored, 8 flipped), that's still about 0.4 radian per frame. So when the object rotates through 1/16 of a circle, its active part instantly moves about 8 pixels, enough to confuse collision detection, eject the object the wrong way, and cause it to glitch through a wall.
I could try shearing the rotating sprite by sliding the 8-pixel strips. This is analogous to how games use "Y offset per column" background modes of the Super NES PPU and Sega Genesis VDP to fake rotation; psycopathicteen could tell you more about these modes. Sliding each strip by 1 pixel works for up to 1/8 radian (7.16 degrees) either way.
Or I could try decoupling the collision position from the display position so that the active part moves smoothly despite discrete angle changes in the sprite.
- mikejmoffitt
- Posts: 1353
- Joined: Sun May 27, 2012 8:43 pm
Re: Sprite shearing to fake rotation
This is neat, but in the context of the Famicom/NES what would be the best way to set about implementing the idea without eating a lot of cycles figuring out how to position sprites that compose a larger meta-sprite in order to achieve the smoother rotation? To slide individual rows could be done I suppose, but vertical strips of pixels would mean eating up a lot more CHR in order to fit these modified tiles, unless you propose modifying CHR-RAM directly for this purpose, though such an operation would not be very quick, I would presume.
Re: Sprite shearing to fake rotation
I'm guessing you simply use tables.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
Re: Sprite shearing to fake rotation
Yeah, it wouldn't make much sense to do this if it requires new graphics anyway. If this was e.g. moving the individual tiles of the sprite separately, it'd make more sense (indeed Treasure did this on Yuu Yuu Hakusho, albeit for scaling).mikejmoffitt wrote:This is neat, but in the context of the Famicom/NES what would be the best way to set about implementing the idea without eating a lot of cycles figuring out how to position sprites that compose a larger meta-sprite in order to achieve the smoother rotation? To slide individual rows could be done I suppose, but vertical strips of pixels would mean eating up a lot more CHR in order to fit these modified tiles, unless you propose modifying CHR-RAM directly for this purpose, though such an operation would not be very quick, I would presume.
EDIT: I always keep up mixing the names of the two Yuu Yuu Hakusho games on the system -_-'
Last edited by Sik on Mon Jan 07, 2013 10:46 am, edited 1 time in total.
-
- Posts: 3178
- Joined: Wed May 19, 2010 6:12 pm
Re: Sprite shearing to fake rotation
You could use the CPU to do software vertical scrolling, while doing horizontal scrolling with the oam x coordinates. Of course, you'll need enough vblank time to write the sprite patterns to vram.
Re: Sprite shearing to fake rotation
Try doing the horizontal scrolling thing with several sprites and you'll see how messy it gets (and you'll probably run out of cycles if you try to use a general approach, you'll need to impose some special restrictions). Also that assumes the use of CHR-RAM, if you use CHR-ROM it won't work since you can't generate graphics on the fly (obviously).psycopathicteen wrote:You could use the CPU to do software vertical scrolling, while doing horizontal scrolling with the oam x coordinates. Of course, you'll need enough vblank time to write the sprite patterns to vram.
Also wouldn't software horizontal line scrolling be faster than software vertical line scrolling? May as well do both in the CPU.
Re: Sprite shearing to fake rotation
A metasprite in such an engine is stored either as a set of 8xn pixel columns (if it is wider than tall) or as a set of nx8 pixel rows (if it is taller than wide). A shear of +1/8 or -1/8 would slide an individual row or column of 8x8 pixel sprites by one pixel. They'd be slid around in OAM, not in CHR RAM, which means this technique would work as well with CHR ROM assuming fine-grained bank switching. Compare to what's done in the first two levels of Battletoads. The walkers' legs in level 1 are sheared for smooth movement, as is the rope in level 2.mikejmoffitt wrote:in the context of the Famicom/NES what would be the best way to set about implementing the idea without eating a lot of cycles figuring out how to position sprites that compose a larger meta-sprite in order to achieve the smoother rotation? To slide individual rows could be done I suppose, but vertical strips of pixels would mean eating up a lot more CHR in order to fit these modified tiles, unless you propose modifying CHR-RAM directly for this purpose, though such an operation would not be very quick, I would presume.
Shall I draw another illustration of this?
Re: Sprite shearing to fake rotation
So what you want seems to be what I mentioned: move around the individual sprites to make the illusion of a smoother animation (even though the actual amount of graphics is smaller).
Something like in here? (but possibly with intersecting sprites so gaps aren't obvious)
http://www.youtube.com/watch?v=e6z14xfCHV4#t=147s
Or heck, something like the swinging wires here:
http://www.youtube.com/watch?v=YptU9ig9R9A#t=14s
Something like in here? (but possibly with intersecting sprites so gaps aren't obvious)
http://www.youtube.com/watch?v=e6z14xfCHV4#t=147s
Or heck, something like the swinging wires here:
http://www.youtube.com/watch?v=YptU9ig9R9A#t=14s
- rainwarrior
- Posts: 8758
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: Sprite shearing to fake rotation
So you're suggesting to shear a sprite into two or more sprites as a tween between two key sprites that are rotations of each other? I guess it's possible, but without hardware support it sounds like it would take up a lot of probably-precious sprite resources. On the NES you can do shearing of background tiles via scrolling, perhaps.
In the example you provided pictures of, I'd say the 8-directions worth of sprites for the two components (with flipping I guess it's really 3 sprites each) are probably what I'd stick with. I would leave the inner sprite where it is, coarsely sticking to those 8 directions, and the outer sprite can move smoothly in a circle. Even though it would only have 8 rotations, the motion of its position can be very smooth. With sprites that are carefully drawn to work with a varying amount of overlap, it can look pretty good, and the smoothness of motion might make up for the lack of rotation granularity. I'm also reminded of the common vectorball technique, where sprite rotations are abandoned entirely, but the motion is quite smooth. (Edit: I just remembered the NES port of the vectorball example.)
I guess Sik is suggesting the same thing.
In the example you provided pictures of, I'd say the 8-directions worth of sprites for the two components (with flipping I guess it's really 3 sprites each) are probably what I'd stick with. I would leave the inner sprite where it is, coarsely sticking to those 8 directions, and the outer sprite can move smoothly in a circle. Even though it would only have 8 rotations, the motion of its position can be very smooth. With sprites that are carefully drawn to work with a varying amount of overlap, it can look pretty good, and the smoothness of motion might make up for the lack of rotation granularity. I'm also reminded of the common vectorball technique, where sprite rotations are abandoned entirely, but the motion is quite smooth. (Edit: I just remembered the NES port of the vectorball example.)
I guess Sik is suggesting the same thing.
Re: Sprite shearing to fake rotation
8 directions usually looks ugly, it's better to stick to 16 =P (which with flipping gets reduced to 5) Also even with 16 it can be quite noticeable, it depends on how fast the sprite rotates (if it spins quite fast it probably won't be very noticeable, if it spins slowly it will still be quite blatant).
EDIT: and before I forget, that dragon example has 16 rotations, not 8 =P
EDIT 2: also if the sprite is constantly spinning in a given direction you probably don't care if the sprite ever ends up aligned to the axes, so you can shift the rotation such that you only would need 4 sprites instead of 5.
EDIT: and before I forget, that dragon example has 16 rotations, not 8 =P
EDIT 2: also if the sprite is constantly spinning in a given direction you probably don't care if the sprite ever ends up aligned to the axes, so you can shift the rotation such that you only would need 4 sprites instead of 5.
-
- Posts: 3178
- Joined: Wed May 19, 2010 6:12 pm
Re: Sprite shearing to fake rotation
Vertical tile scrolling is just a matter of loading and storing bytes.Sik wrote:Also wouldn't software horizontal line scrolling be faster than software vertical line scrolling? May as well do both in the CPU.psycopathicteen wrote:You could use the CPU to do software vertical scrolling, while doing horizontal scrolling with the oam x coordinates. Of course, you'll need enough vblank time to write the sprite patterns to vram.
- rainwarrior
- Posts: 8758
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: Sprite shearing to fake rotation
Yes, Dragon Breed has 16 rotation sprites, none of them flipped. I wasn't referring to its sprite count, just that it is using the sprite position to get extra smoothness between the rotation sprites, and the overlap between sprites allows visual continuity between segments even though the positions are shifting irregularly.Sik wrote:EDIT: and before I forget, that dragon example has 16 rotations, not 8 =P
EDIT 2: also if the sprite is constantly spinning in a given direction you probably don't care if the sprite ever ends up aligned to the axes, so you can shift the rotation such that you only would need 4 sprites instead of 5.
Not aligning to the axes can have an aesthetic appeal as well, so that's a good suggestion not just for extra smoothness, but breaking up the look of 8-pointy things.
Re: Sprite shearing to fake rotation
That depends on how symmetric the object is. If it isn't left-right symmetric, you need 8 anyway to produce 16, as only half of them can be computed through vh-flipping. Flipping only vertically or only horizontally produces a sprite facing the other direction.Sik wrote:8 directions usually looks ugly, it's better to stick to 16 =P (which with flipping gets reduced to 5)
Re: Sprite shearing to fake rotation
Another game to look at for this, by the way, is Syvalion. Compare, say, the Amiga or SNES version to that of the arcade (arcade is a lot smoother but can't figure out if the sprites are significantly different), and look at the Chinese dragon's segments during movement.
Yeah, the game is similar to Dragon Breed (which I own :-) ) in that it has a Chinese dragon. HAI I LIEK DAGRONS. I give them milk and sugar and in return they give me good luck and the ability to manipulate water. (This line added just to try and get Tepples to go on a link spree, probably involving pictures of Spyro or strange child-like dragons with baseball hats carrying bento boxes while fishing).
Yeah, the game is similar to Dragon Breed (which I own :-) ) in that it has a Chinese dragon. HAI I LIEK DAGRONS. I give them milk and sugar and in return they give me good luck and the ability to manipulate water. (This line added just to try and get Tepples to go on a link spree, probably involving pictures of Spyro or strange child-like dragons with baseball hats carrying bento boxes while fishing).
Re: Sprite shearing to fake rotation
This was on the assumption of scrolling each column of pixels separately. Then you're moving individual bits.psycopathicteen wrote:Vertical tile scrolling is just a matter of loading and storing bytes.Sik wrote:Also wouldn't software horizontal line scrolling be faster than software vertical line scrolling? May as well do both in the CPU.psycopathicteen wrote:You could use the CPU to do software vertical scrolling, while doing horizontal scrolling with the oam x coordinates. Of course, you'll need enough vblank time to write the sprite patterns to vram.