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?