- Home /
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
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?
Answer by delstrega · Jun 13, 2012 at 12:15 PM
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.
Your answer
Follow this Question
Related Questions
GameObject stuttering on the same spot when trying to lerp 1 Answer
Can the insides of a gameObject affect its transform? 0 Answers
GameObject's scale gets 0 after being parented in editor 1 Answer
How do I scale a 2D sprite over time? 2 Answers
How can I LERP the X position to the X position of the player 2 Answers