I found the solution with help of this thread: "Relative" texcoord when using sprite atlas - Unity Engine - Unity Discussions
You have to send the sprite bounds to the shader using scripting language.
Here’s the shader, if you have any tips to make it better, please, send me.
Shader "Sprites/ShinyDefault"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
_LightColor("LightColor", Color) = (1,1,1,1)
_ShineWidth("ShineWidth", Range(0,1)) = 0
_Rect ("Rect Display", Vector) = (0,0,1,1)
_StencilComp ("Stencil Comparison", Float) = 8
_Stencil ("Stencil ID", Float) = 0
_StencilOp ("Stencil Operation", Float) = 0
_StencilWriteMask ("Stencil Write Mask", Float) = 255
_StencilReadMask ("Stencil Read Mask", Float) = 255
_ColorMask ("Color Mask", Float) = 15
[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Stencil
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
Cull Off
Lighting Off
ZWrite Off
ZTest [unity_GUIZTestMode]
Blend SrcAlpha OneMinusSrcAlpha
ColorMask [_ColorMask]
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "UnityUI.cginc"
#pragma multi_compile __ UNITY_UI_ALPHACLIP
struct appdata_t
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 texcoord : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
half2 texcoord : TEXCOORD0;
float4 worldPosition : TEXCOORD1;
};
fixed4 _Color;
fixed4 _LightColor;
fixed4 _TextureSampleAdd;
fixed4 _Rect;
float4 _ClipRect;
half _ShineWidth;
v2f vert(appdata_t IN)
{
v2f OUT;
OUT.worldPosition = IN.vertex;
OUT.vertex = mul(UNITY_MATRIX_MVP, OUT.worldPosition);
OUT.texcoord = IN.texcoord;
#ifdef UNITY_HALF_TEXEL_OFFSET
OUT.vertex.xy += (_ScreenParams.zw-1.0)*float2(-1,1);
#endif
OUT.color = IN.color * _Color;
return OUT;
}
sampler2D _MainTex;
float4 _MainTex_TexelSize;
fixed4 frag(v2f IN) : SV_Target
{
const half v = 4;
half xVal = v*_MainTex_TexelSize.x*_ShineWidth;
half yVal = v*_MainTex_TexelSize.y*_ShineWidth;
half2 offX = half2(xVal, yVal);
half2 offY = half2(xVal, -yVal);
half colorGlow = (tex2D(_MainTex, clamp(IN.texcoord + offY, _Rect.xy, _Rect.zw))).a +
(tex2D(_MainTex, clamp(IN.texcoord - offY, _Rect.xy, _Rect.zw))).a +
(tex2D(_MainTex, clamp(IN.texcoord + offX, _Rect.xy, _Rect.zw))).a +
(tex2D(_MainTex, clamp(IN.texcoord - offX, _Rect.xy, _Rect.zw))).a;
const float C = 0.796;
colorGlow = saturate(2*sin(colorGlow*C));
half4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color;
color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
half2 centerPos = half2((_Rect.x+_Rect.z)/2, (_Rect.y+_Rect.w)/2);
half maxDist = sqrt(pow((_Rect.z-_Rect.x)/2,2) + pow((_Rect.w-_Rect.y)/2,2));
half shinestart = (1-_ShineWidth)*maxDist;
half dist = max(distance(IN.texcoord, centerPos)-shinestart,0);
half whitePower = color.a*(dist/((max(_ShineWidth,.01)*maxDist)));
color.rgb = lerp(color.rgb, _LightColor.rgb, whitePower);
color = lerp(color,_LightColor, colorGlow);
#ifdef UNITY_UI_ALPHACLIP
clip (color.a - 0.001);
#endif
return color;
}
ENDCG
}
}
}
And in the scripting language, you have to set the _Rect property. You have to set only when you chance the sprite image:
image = GetComponent<Image> ();
Sprite sprite = image.sprite;
Vector4 result = new Vector4(sprite.textureRect.min.x/sprite.texture.width,
sprite.textureRect.min.y/sprite.texture.height,
sprite.textureRect.max.x/sprite.texture.width,
sprite.textureRect.max.y/sprite.texture.height);
image.material.SetVector ("_Rect", result);
The result: