How to save generated normal texture?

Hi, I want to use normal texture created from two others with lerp and BW mask,
all works fine in one shader, but when result of mixing is saved to texture I got different result sampling it.
Here is how it looks:

The generated texture was created this way:

And was saved this way:

public static Texture2D RenderToTexture(this Material material, int width, int height)
{
    RenderTexture renderTexture = new RenderTexture(width, height, 24, RenderTextureFormat.ARGB32);
    RenderTexture.active = renderTexture;

    Graphics.Blit(null, renderTexture, material, 0);

    Texture2D newTexture = new Texture2D(width, height, TextureFormat.RGBA32, false);
    newTexture.ReadPixels(new Rect(0, 0, width, height), 0, 0);

    RenderTexture.active = null;
    if (Application.isPlaying) GameObject.Destroy(renderTexture);
    else GameObject.DestroyImmediate(renderTexture);

    return newTexture;
}

Whan am i doing wrong?

The process of unpacking a normal map converts the data from the 0-1 range to a -1 to 1 range. Most texture formats store values in the 0-1 range, but normal data is a vector so the x, y, and z values need to be in the range of -1 to 1. That’s why it has to go through the unpacking process - to expand the data’s range. This range expanding is done automatically when you set the sampler to Type: Normal, and it’s done by the Normal Unpack node when you use that.

If you save the unpacked normal out as a texture, in order to capture the expanded range, you need to use a texture format that’s signed - or that supports storing negative values. (Otherwise, all of the negative values will get clamped to 0 - which might explain the differences you’re seeing.) Since this isn’t something that’s done very frequently, I don’t know if these formats are supported - but I’ll try to find out and post again when I know more.

On line 3 of your script above, you have set the texture format to ARGB32. The doc says that format is 0-1 - so I think that is your problem. The only format I could see in the list that’s explicitly called out as “signed” is EAC_RG_Signed which appears to be only supported in GL ES 3.0.

I think you may be better off setting the Sampler Type to Default when you save out the texture to keep it in the 0-1 range, and then unpack it after you need to sample the saved-out version later. Is there a reason that solution doesn’t work for you?