Order of transformations for uvs

Hi I’m struggling to understand how to transform uvs.
Normally if I want to move and rotate and object on its pivot, I would first move to the pivot then rotate and then add the translation(finally move the pivot back).
But with uvs I found I need to first subtract the translation and then rotate.
Why is that?

v2f vert (appdata v)
{
   v2f o;
   o.vertex = UnityObjectToClipPos(v.vertex);
   o.uv = TRANSFORM_TEX(v.uv, _MainTex);
   float c = cos(_Rotation);
   float s = sin(_Rotation);
   float2x2 rotationMatrix = float2x2(c, -s, s, c);
   o.effectuv = o.uv - _Pivot.xy;
   o.effectuv -= _Translation;
   o.effectuv = mul(rotationMatrix, o.effectuv);
   o.effectuv += _Pivot.xy;
   return o;
}

Transforms for meshes and UVs work exactly the same way, there is no actual difference in the behavior.

The difference is in your expectations of what translation and rotation mean for a texture vs a mesh.

When you move and rotate an object, the expectation is you’re rotating it around the “pivot” that’s being moved. Rotation matrices rotate around where ever the “0” position is. So for mesh rotation you apply the rotation first, because the “0” position is still at the center of the mesh, then apply the translation offset which moves the “0” off of the center of the mesh. You wouldn’t want it to rotate around the world origin after you’ve moved it.

When you move and rotate a texture, the expectation is usually that you want to rotate around a fixed position on the surface regardless of anything else. In your case the _Pivot. The translation shouldn’t affect the rotation’s pivot, so it needs to be applied before the rotation.

Try this:
Put your scene camera into 2D mode and center it on the world origin. Place a quad or sprite at the world origin. Roate it a round a bit. Now move it up slightly and rotate it around again. It will rotate’s around the center of the game object that’s being moved.

If you change your above shader to do the translation after the rotation, then do something similar while staring at a stationary quad with your shader, you’ll see the same behavior. You can rotate it, and it’ll rotate around the _Pivot. If you move it up a little bit and rotate it again, it will rotate around the slightly moved up position. Exactly the same behavior as moving around a mesh.

Now swap the shader back to the code you have above, and you’ll see the translation has no affect on where the rotation happens. It stays locked on the pivot.