private IEnumerator SaveSheetCoroutine(List <Material> mats, string filename, int w, int h, IPlanet planet, int size)
    {
        var scale = size / base_width;

        base_width = base_height = size;
        var texture = Texture2D.whiteTexture;

        var renderTexture = RenderTexture.GetTemporary(base_width, base_height, 0);

        var tex = new Texture2D(base_width * w, base_height * h, TextureFormat.RGBA32, false);

        int index = 1;

        for (int y = 0; y < h; y++)
        {
            for (int x = 0; x < w; x++)
            {
                texture = Texture2D.whiteTexture;
                foreach (var mat in mats)
                {
                    Graphics.Blit(texture, renderTexture, mat);
                }
                RenderTexture.active = renderTexture;

                tex.ReadPixels(new Rect(0f, 0f, renderTexture.width, renderTexture.height), base_width * x, base_height * y);

                var atime = (float)index / (float)(w * h);
                var t     = Mathf.Lerp(0f, 1f, atime);
                planet.SetCustomTime(t);

                index++;
            }
        }

        // apply tex and write png file
        tex.Apply();
        var bytes = tex.EncodeToPNG();

        Object.DestroyImmediate(tex);
        RenderTexture.ReleaseTemporary(renderTexture);
        yield return(new WaitForEndOfFrame());

#if UNITY_WEBGL && !UNITY_EDITOR
        DownloadFile(gameObject.name, "OnFileDownload", filename + ".png", bytes, bytes.Length);
#else
        var path = StandaloneFileBrowser.SaveFilePanel("Save Sprite Sheets", "", filename, "png");
        File.WriteAllBytes(path, bytes);
#endif
    }