[ShaderForge] Atlas UV map vs. Local UV map

Hi Uniteers, I am struggling with the current.
I wish to add a glow to my sprite using the UV coordinates, but problem is, if the sprite originates from an atlas created by Unity’s sprite packer, then the UV aren’t normalized from 0 to 1, but from and to two arbitrary values. How do I normalize UV data for a single sprite that resides in an atlas?


The hand to the left is a sprite. The hand on the right is a sprite from an atlas. I want the right hand to look the same as the hand on the left.

I am using the following shaderforge layout:

Hey! Reviving this year old thread, did you ever solve this? I keep been encountering the same problem over and over again.

I figured out a way to do this by encoding the atlased UV and the normalised UV into the same float2.

so, if the normal sprite atlased uv’s looked like this:

0.25,0.25
0.25,0.75
0.75,0.75
0.75,0.25

the equivalent new uv’s (with the normalised UV embedded) would look like this:

1.25,1.25
1.25,2.75
2.75,2.75
2.75,1.25

here is the code:

v2f vert(appdata_t IN)
{
v2f OUT;
UNITY_SETUP_INSTANCE_ID(IN);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
OUT.worldPosition = IN.vertex;
OUT.vertex = UnityObjectToClipPos(OUT.worldPosition);

float4 uvs = ExtractUVs(IN.texcoord); // Extract both UV and normalised UV from a single float2
OUT.texcoord = uvs.xy; // pass on the atlased UV to the pixel shader
OUT.normalisedtexcoord = uvs.zw; // pass on the normalised UV to the pixel shader
OUT.color = IN.color * _Color;
return OUT;
}

// Extract UV and Normalised UVs into a float4… :slight_smile:
float4 ExtractUVs(float2 uv0)
{
uv0 -= float2(1.0,1.0);
float4 uv1 = uv0.xyxy;
if (uv1.x > 1.0)
uv1.x -= 1.0;
if (uv1.y > 1.0)
uv1.y -= 1.0;
uv1.zw -= uv1.xy;
return uv1; // uv1.xy = UV and uv1.zw = NormalisedUVs
}

Enjoy.