Scaling a sprite after rotating it

I have some sprites scaled down on the Y axis to give the illusion that they are being viewed at a certain angle. The problem is when I try to rotate any sprites, the scaling axes rotate as well, so the sprite appears skewed.
I only want to scale the height of the sprite, regardless of rotation. Is this possible?
I’d like to avoid using animation/spritesheets if possible.
Thanks.

try to rotate the scale vector.
You could for example create a quaternion with the same rotation around Z and then call transform.

2 Likes

Thanks for the response, what transform method do you mean exactly? Like with a matrix?

Yes, you can do the same with a rotation matrix. It works the same way.
Use Matrix.CreateRotationZ() and then Vector3/2.TranformNormal().

I am not 100% sure this will work , it’s just a thought.

Interesting, okay. I’ll give it a try when I get the chance.
It would be better to not need a new spritebatch but it’s worth trying at least.

I only want to scale the height of the sprite, regardless of rotation. Is this possible?

Isn’t the bottom row of images you posted doing exactly what you just described you want it to do ?

Yes that’s what I want

Oh i see because spritebatch draw lets you rotate or scale but doesn’t let you define which comes first.
If i remember the order of operations its scale then rotate in spritebatch and even if it wasn’t i don’t think you would get the right results.

That might be a bit tough to solve with spritebatch, gotta think about that one.

Humm i looked at this for a couple hours and couldn’t see a way to do it with spritebatch properly unless someone else has tackled this problem and wants to chime in.

Even with custom vertices im unsure if this can be done easily i know m11 and m22 is normally the scaling elements of any matrix you should be able to do this with a custom shader via rotate then scale the output of that. Or via m41 m42 can be used to directly dimensionally skew but it has side effects and with both you have to be careful.

Okay yeah I’d appreciate it. I haven’t had the chance to try what was suggested before since I’ve been really busy.

I know it’s been a while and I put this issue on the side to work on other stuff, but today I tried out what was suggested for using a matrix.

It looks like this:
Matrix.CreateTranslation(origin.X, origin.Y, 1f) *
Matrix.CreateRotationZ(rotation) *
Matrix.CreateScale(1f, scaleY, 1f) *
Matrix.CreateTranslation(position2.X - origin.X, position2.Y - origin.Y, 0f);

It looks decent enough (a little blurry but that’s ok)
The main problem is the need to interrupt the spritebatch in order to use this matrix. So there’s a performance drawback. And also it seems to me like very bad code to end the spritebatch in the code for each instance of this object.
There’s a suggestion that was made a long time ago to support matrices as an overload for SpriteBatch.Draw(). https://github.com/MonoGame/MonoGame/issues/3156

It also just so happens that in my GUI code that I’ve been working on, I use matrices to keep objects tethered to each other. To do this, I have to call Decompose just to pass the values (position, rotation, etc) into Draw. I’m sure there are many other people doing the same thing. So adding a matrix overload to Draw would not only make this sprite skewing/rotation more doable but also simplify other Matrix uses as well.

Another option to consider is using a RenderTarget. Use your matrix to draw the image onto a RenderTarget, and then use the resulting RT as normal in your regular SpriteBatch draw routines.

The downside is you’ll need to create a new RT whenever your transform changes, but it gets away from the issue of reduced performance during your regular draw routines.

This approach might not work if your transform is constantly changing, but should be fine if it changes only occasionally.

Yeah I thought about doing that too, but just saving the render target for each rotation of the sprite during game load and then reusing them. Because my object just rotates and changes directions. I also considered just using different sprites for each rotation, but using render target might be better.

I will probably do it one of those two ways unless a matrix overload is added to SpriteBatch.Draw() in the future.
Thanks for the suggestions. :slight_smile: