Getting object rotation in world space

I am writing a shader for a particle billboard. I am making it look like those retro styled doom sprites, where it shows a different sprite depending on which side you are looking at it. So far I have been able to make it look the way I wanted it to.
Now I seem to have reached the problem where I forgot to think about if I want to rotate the object, it always “looks” the same direction. In other words I forgot to include the object rotation, but I have no idea how. Currently I calculate rotation like this

// from object to camera direction; in world space
float3 cameraDirection = -1 * mul((float3x3)unity_ObjectToWorld, transpose(mul(unity_WorldToObject, unity_MatrixInvV)) [2].xyz);

// Rotate cameraDirection about axis, to simulate spinning
vector <float, 3> rotatedTransform;
RotateAboutAxis_Radians_float(cameraDirection, float3(0, 1, 0), rotateAmount, rotatedTransform);

// Rotation towards ??? (I'm guessing (0, 0, 1) in world space) in radians
float artanned = atan2(rotatedTransform.x, rotatedTransform.z);

My rotate amount is just calculated with _Time like this float animation = floor((_Time * _Fps) % _AnimFrameCount);

I use all this information to map it to a sprite sheet with a flipbook.
How would I go about getting the object world space rotation so I can += onto the rotateAmount?

I am very new to shader programming so here is my entire shader

Shader "Bjørn/Directional Particle"
{
    Properties
    {
        [NoScaleOffset] _MainTex ("Sprite Sheet", 2D) = "white" {}
        _AnimFrameCount ("Animation Frame Count", int) = 1
        _SideCount ("Side count", int) = 8
        _Fps ("Fps", int) = 5
        [Toggle] _Rotate ("Rotate", Float) = 0
        _RotateSpeed ("Rotate Speed", Float) = 1
    }

    SubShader
    {
        Tags { "RenderType"="Transparent" "DisableBatching"="True" }
        LOD 100
        Blend SrcAlpha OneMinusSrcAlpha
        Cull Back
        ZWrite Off

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma exclude_renderers gles xbox360 ps3
            #pragma exclude_renderers gles xbox360 ps3
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            v2f vert (appdata v)
            {
                v2f o;

                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                UNITY_TRANSFER_FOG(o,o.vertex);
                return o;
            }

            void Flipbook_float(float2 UV, float Width, float Height, float Tile, float2 Invert, out float2 Out)
            {
                Tile = fmod(Tile, Width * Height);
                float2 tileCount = float2(1.0, 1.0) / float2(Width, Height);
                float tileY = abs(Invert.y * Height - (floor(Tile * tileCount.x) + Invert.y * 1));
                float tileX = abs(Invert.x * Width - ((Tile - Width * floor(Tile * tileCount.x)) + Invert.x * 1));
                Out = (UV + float2(tileX, tileY)) * tileCount;
            }

            void Remap_float(float In, float2 InMinMax, float2 OutMinMax, out float Out)
            {
                Out = OutMinMax.x + (In - InMinMax.x) * (OutMinMax.y - OutMinMax.x) / (InMinMax.y - InMinMax.x);
            }

            void RotateAboutAxis_Radians_float(float3 In, float3 Axis, float Rotation, out float3 Out)
            {
                float s = sin(Rotation);
                float c = cos(Rotation);
                float one_minus_c = 1.0 - c;

                Axis = normalize(Axis);
                float3x3 rot_mat =
                {   one_minus_c * Axis.x * Axis.x + c, one_minus_c * Axis.x * Axis.y - Axis.z * s, one_minus_c * Axis.z * Axis.x + Axis.y * s,
                    one_minus_c * Axis.x * Axis.y + Axis.z * s, one_minus_c * Axis.y * Axis.y + c, one_minus_c * Axis.y * Axis.z - Axis.x * s,
                    one_minus_c * Axis.z * Axis.x - Axis.y * s, one_minus_c * Axis.y * Axis.z + Axis.x * s, one_minus_c * Axis.z * Axis.z + c
                };
                Out = mul(rot_mat,  In);
            }

            int _AnimFrameCount;
            int _SideCount;
            int _Fps;
            bool _Rotate;
            float _RotateSpeed;

            fixed4 frag (v2f i) : SV_Target
            {
                float animation = floor((_Time * _Fps) % _AnimFrameCount);

                // Rotate amount
                float rotateAmount;
                if (_Rotate == 1)
                {
                    rotateAmount = _RotateSpeed * _Time;
                }
                else if (_Rotate == 0)
                {
                    rotateAmount = 0;
                }

                // from object to camera direction; in world space
                float3 cameraDirection = -1 * mul((float3x3)unity_ObjectToWorld, transpose(mul(unity_WorldToObject, unity_MatrixInvV)) [2].xyz);

                // Rotate cameraDirection about axis, to simulate spinning
                vector <float, 3> rotatedTransform;
                RotateAboutAxis_Radians_float(cameraDirection, float3(0, 1, 0), rotateAmount, rotatedTransform);

                // Rotation towards ??? (I'm guessing (0, 0, 1) in world space) in radians
                float artanned = atan2(rotatedTransform.x, rotatedTransform.z);

                // Map direction to spritesheet position
                float remappedAngle;
                Remap_float(atan2(rotatedTransform.x, rotatedTransform.z), float2 (-3.141593, 3.141593), float2 (1, 0), remappedAngle);

                float direction = _AnimFrameCount * round(_SideCount * remappedAngle);

                // Sprite sheet sample
                float tile = animation + direction;

                float2 flipbookUV;
                Flipbook_float(i.uv, _AnimFrameCount, _SideCount, tile , float2 (0, 1 ), flipbookUV);
                fixed4 col = tex2D(_MainTex, flipbookUV);

                // apply fog
                UNITY_APPLY_FOG(i.fogCoord, col);

                return col;
            }
            ENDCG
        }
    }
}

So I did some more research and wrote some test shaders to see what I could do. I managed to write a super simple shader that gets the objects rotation, and displays it as the color in the range of [0,1] It looks like this

struct v2f
{
    float2 uv : TEXCOORD0;
    UNITY_FOG_COORDS(1)
    float4 vertex : SV_POSITION;
};

sampler2D _MainTex;
float4 _MainTex_ST;

v2f vert (appdata v)
{
    v2f o;
    o.vertex = UnityObjectToClipPos(v.vertex);
    o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    UNITY_TRANSFER_FOG(o,o.vertex);
    return o;
}

float MapRotationTo01(float radians) {
    return (radians + PI) / (2.0 * PI);
}

fixed4 frag (v2f i) : SV_Target
{
    // object's forward vector (local +Z direction)
    float3 objWorldForward = unity_ObjectToWorld._m02_m12_m22;
    //get objects current Y rotation from its rotation matrix in radians
    float objWorldHeading = atan2(-objWorldForward.z, objWorldForward.x);

    float3 color = MapRotationTo01(objWorldHeading);

    return fixed4(color, 1.0);
}

But with this I also learned why I am having trouble with my particle. So particles apparently have no knowledge about where they are in space and they are always at world root (As I understand it). Hence I started figuring out how to use custom vertex streams, but I can’t figure it out even when implementing it into my simple rotation shader
9542257--1347685--upload_2023-12-21_17-37-58.png
The particle billboard just stays gray no matter the rotation

are you using #define UNITY_PARTICLE_INSTANCE_DATA?

my personal case looks like this

            #define UNITY_PARTICLE_INSTANCE_DATA MyParticleInstanceData
            #define UNITY_PARTICLE_INSTANCE_DATA_NO_ANIM_FRAME
            struct MyParticleInstanceData
            {
                float3x4 transform;

                uint color;

                float lifetime;
            };