Scale texture of a quad smoothly

Hi there!

For a project of mine I have to scale the texture (like a circle or star) of some textured quads from “covering the whole quad” to “not visible anymore”.
For example I got an image of a duck. First it has to cover the whole quad so that it looks rectangular and not like a duck at all. Then I scale down so the duck becomes visible. After further scaling I want the duck to disappear.

I do this by using SetTextureScale(“_MainTex”,…). The problem though is that scaling textures seems to be not linear since it uses the textures “tiling” property for that.
Unlike the “scale” of a GameObject which is 0 when the Object is not visible, “tiling” works the other ways round. When “tiling” is 0, the texture is very large and to make it so small that its not visible anymore “tiling” has to be a very large number like >200 depending on the source texture’s pixelsize.
What I want to achieve is that it takes a set amount of time (say 1 second) to go from fully covering the quad (scale = 0) to not visible (scale > 200) or the other way round.
The problem is that between a texture scale 0 to 3 the change in scale is quite apparent whereas going over 3 it becomes more and more unnoticeable. Between 3 and 200 each increment of scale only changes so much visually but only with a high enough scale the image really vanishes. I tried using something like this:


accumTime += Time.deltaTime;

scale = Mathf.Lerp(0f,200f, accumTime / 1f);

So that after 1 second it should be invisible. But this way the texture is only fully covering the quad a split second then becomes small very quickly but nevertheless takes the rest of the second to vanish completely.
What I want to say is that changing scale from say 0 to 1 is a huge difference visually whereas 100 to 101 is not noticeable at all. What I need is some lerp-like function that takes say half a second for 0 to 3 and the other half for 3 to 200. To simulate that I tried:

if(accumTime <= 0.5f)

scale = Mathf.Lerp(0,3, accumTime/0.5f);

else

scale = Mathf.Lerp(3,200, (accumTime-0.5f) / 0.5f);

But the result wasn’t smooth at all, since you could tell from the visuals that it changed the lerp.
My workaround now is that I scale the texture only the first half of the desired duration and after that scale down the GameObject itself. Scaling the GameObject seems to be linear unlike scaling a texture on a material.
This works but seems hacky and on a mobile device theres some stutter sometimes.

Is there a better way to achieve this?

I kinda solved it myself: Instead of using a simple lerp I use a custom one:

float powFourLerp(float start, float end, float value){
return Mathf.Lerp(start, end, Mathf.Pow(value,4));
}

This way the first part of the scaling is really slow so you can really see the actual image and speeds up against the end.

Now all I do is:

scale = powFourLerp(0f, 300f, accumTime/duration);

to scale from full to invisible.
For the other way round I use:

scale = powerFourLerp(0f, 300f, (duration - accumTime) / duration);

Hope that helps anyone with a similar problem.