packing normalmaps

I’d like to pack both diffuse maps AND normalmaps to atlases so my bumped specular static environment could batch (1 diffuse atlas, 1 normalmap atlas - without any mixing).

I get it to pack, but the resulting look of objects differ with how objects look before packing.

Example project and two screenshots (“before” and “after”) are in the attachment.

The code that packs normalmap atlas:

Texture2D normal_packedTexture = (Texture2D)Instantiate(shaderToMaterial[key][0].GetTexture(normal_tex_name));
            //new Texture2D(packedTexture.width, packedTexture.height);
            if (normal_packedTexture.Resize(packedTexture.width, packedTexture.height))
            {
                Debug.Log("resized");
            }
            else
            {
                Debug.Log("not resized");
            }
           
            normal_packedTexture.Apply();

Texture2D[] normal_texs = new Texture2D[texs.Length];
            for (int i = 0; i < texs.Length; i++)
            {
                if (shaderToMaterial[key][i].HasProperty(normal_tex_name))
                {
                    normal_texs[i] = shaderToMaterial[key][i].GetTexture(normal_tex_name) as Texture2D;
                    if (normal_texs[i] == null)
                    {
                        Debug.Log("normal null!");
                    }
                    //setpixels32, make no longer readable
                    float x = (int)(uvs[i].x * packedTexture.width);
                    float y = (int)(uvs[i].y * packedTexture.height);
                    float width = (int)(uvs[i].width * packedTexture.width);
                    float height = (int)(uvs[i].height * packedTexture.height);
                    Debug.Log(string.Format("pack normal: {0},{1},{2},{3} ", x, y, width, height));
                   
                    Color[] colz = normal_texs[i].GetPixels();
                   
                    normal_packedTexture.SetPixels((int)x, (int)y, (int)width, (int)height, colz);


                }
                else
                {
                    Debug.Log("doesn't have property");
                }
            }
           
            normal_packedTexture.Apply(true, false);

I probably miss something simple.
What do you think?

thanks,
Slav

758821–27703–$packer_normals_issue1.7z (4.77 MB)
758821--27704--$do.jpg
758821--27705--$posle.jpg

Big thanks to Waruiyume!

The issue is solved by copying all mipmap levels:

for (int i = 0; i < texs.Length; i++)
            {
                if (shaderToMaterial[key][i].HasProperty(normal_tex_name))
                {
                    normal_texs[i] = shaderToMaterial[key][i].GetTexture(normal_tex_name) as Texture2D;

                    if (normal_texs[i] == null)
                    {
                        Debug.Log("normal null!");
                    }
                    Debug.Log(normal_texs[i].mipmapCount);
                    //setpixels32, make no longer readable
                    float x = (int)(uvs[i].x * packedTexture.width);
                    float y = (int)(uvs[i].y * packedTexture.height);
                    float width = (int)(uvs[i].width * packedTexture.width);
                    float height = (int)(uvs[i].height * packedTexture.height);
                    Debug.Log(string.Format("pack normal: {0},{1},{2},{3} ", x, y, width, height));

                    for (int ml = 0; ml < normal_texs[i].mipmapCount; ml++)
                    {
                        if(ml==0)
                        {
                            Color[] colz = normal_texs[i].GetPixels();
                            normal_packedTexture.SetPixels((int)x, (int)y, (int)width, (int)height, colz);
                        }
                        else
                        {

                                Color[] colz = normal_texs[i].GetPixels(ml);
                                normal_packedTexture.SetPixels((int)x>>ml,(int)y>>ml,
                                    (int)width >> ml, (int)height >> ml, colz, ml);
                        }
                   
                    }
                }
                else
                {
                    Debug.Log("doesn't have property");
                }
            }
           
            normal_packedTexture.Apply(false, false);

A more convenient project archive is in the attachment,
but the script there is a bit outdated in this piece of code I showed above.

761915–27839–$waruime_normal_packing__fix_nmu.7z (6.01 MB)