Hi, I’ve been wrestling for the past few days with making a shader that scales/rotates/translates sprites. This works fine for actual SpriteRenderers, but it’s also not very useful for them – however, because the object space for ParticleSystemRender isn’t always centered on the sprite, a number of challenges are introduced, some of which I’m having a very difficult time with. I was able to find the center of the sprite using the Custom Vertex Stream feature of the ParticleSystemRenderer, but I’m not sure how to match the viewspace billboarding of the renderer in my transformation function.
Here’s the function:
inline void Transform(inout float4 vertex, half2 effectUV, half3 center)
{
half o = GET_I(SpriteEffectProperties, _TransformValueOffset);
effectUV = effectUV.xy * GET_I(SpriteEffectProperties, _TransformMap_ST).xy + GET_I(SpriteEffectProperties, _TransformMap_ST).zw;
half3 amt = SPRITE_SAMPLE_LOD(_TransformMap, TRANSFORM_TEX_SPRITE_EFFECT(effectUV, _TransformMap).xy, 0).rgb + o;
float2 scale = (float2(GET_I(SpriteEffectProperties, _TransformScale).xy - 1) * amt.xy) + 1;
float2 translate = float2(GET_I(SpriteEffectProperties, _TransformTranslate).xy * amt.xy);
float3 cen = (center + float3(GET_I(SpriteEffectProperties, _TransformCenterOffset).xy, 0));
half c = cos(radians(GET_I(SpriteEffectProperties, _TransformRotate) * amt.z));
half s = sin(radians(GET_I(SpriteEffectProperties, _TransformRotate) * amt.z));
half4x4 rotation = Euler4x4(radians(GET_I(SpriteEffectProperties, _TransformSpaceRotation)));
float4 transformed = float4(vertex.xyz, 1);
transformed = mul(transformed, inverse(rotation));
transformed.xyz -= cen;
transformed.xy *= scale;
transformed.xy = half2(transformed.x * c - transformed.y * s, transformed.y * c + transformed.x * s);
transformed.xy += translate;
transformed.xyz += cen;
transformed = mul(transformed, (rotation));
vertex.xyz = transformed;
}
GET_I is just a define abstracting instancing code so I can use it across pipelines. Euler4x4 and invert are defined elsewhere – they should be doing basically what you’d expect, but I can include them if anyone thinks that would be helpful. What I have here almost works, but there’s two big issues: One, it requires the user to manually match the rotation of the particlesystem in the _TransformSpaceRotation property, and two it’s very difficult to actually center the particles so _TransformRotate doesn’t also move them around. Any idea what I’m doing wrong here?