That’s not how shaders work.
Shaders take data you give it and run ever frame, for every pixel on screen. The output is the image on screen, and all other data is thrown away and calculated again for each pixel, each frame.
That seems wasteful, but it works well with how GPUs function. They’re massively parallel processors that can be fed relatively small amounts of data and return a color value. The cost of moving data around can actually be more expensive (in terms of how long it takes) than recalculating something over and over again for every pixel, so they do that instead of calculating it once and then passing that data along. That’s especially true for mobile where the GPUs are quickly getting faster and faster at raw calculation, but the memory bandwidth isn’t increasing at the same speed. Now there’s the split between vertex and fragment shaders that does allow you to calculate something once and pass it to the fragment shaders, but that’s because this happens in different steps.
And yes, I know I just said it’s expensive to do normal map scaling in my previous post, and then said it’s faster to calculate everything every frame in this one. It’s a balancing act, send as little data as possible and do as little calculation as possible, and try to make smart decisions about which to use when you have to. In the case of a normal map the cost of sending one normal map or another that happens to be a scaled version is the same, so doing the work to scale it in the shader is almost always a loss.
If you want to know more you should read up on rasterization and shaders. This is a good place to start:
http://www.alanzucconi.com/2015/06/10/a-gentle-introduction-to-shaders-in-unity3d/
Now if you want to modify a normal map at runtime you can totally do that, even with a shader, but you’d need a shader that explicitly takes a normal map and outputs the modified version that you then save and store. But on mobile that can be expensive as textures are usually stored in a compressed form (again, because moving data around is slow), and if you use a shader the resulting texture is not compressed. Moreover to compress the texture on a PC can take several seconds to even minutes depending on the size and format; compressing on a mobile device can take hours(!) so they don’t even bother supporting that. Instead you’re left with an uncompressed copy of a texture you already have in memory taking up more memory and slowing down rendering.
So your best option is to modify the texture before hand. Either do it in your 2d graphics tool of choice, or you can write a tool to do it in the Unity Editor and output a new texture asset.
The last alternative is write a custom surface shader that does the normal scaling. The main thing that’s expensive about normal map scaling is actually when scaling it up and not when scaling it down / smoothing it out. If you only ever want to scale down normal maps that’s much cheaper.
o.Normal = lerp(half(0,0,1), UnpackNormal(tex2D(_BumpMap, IN.uv_MainTex)), _NormalMapScale);