Example #1
0
        private static Packer.Block[] ComputePack(IList <Texture2D> textures, out int width, out int height)
        {
            int num = textures.Count;

            Packer.Block[] blocks = new Packer.Block[num];
            for (int i = 0; i < num; i++)
            {
                Texture2D tex = textures[i];
                blocks[i] = new Packer.Block()
                {
                    w = tex.width, h = tex.height, x = 0, y = 0, i = i,
                };
            }
            Array.Sort(blocks, new BlockComparer());

            Packer packer = new Packer();

            packer.Fit(blocks, out width, out height);

            return(blocks);
        }
Example #2
0
        public static Rect[] PackTexturesCompute(out Texture result, IList <Texture2D> textures,
                                                 int maximumAtlasSize = 2048)
        {
            int width;
            int height;

            Packer.Block[] blocks = ComputePack(textures, out width, out height);

            if (width < height)
            {
                throw new Exception("error");
            }

            float scale = 1;

            if (width > maximumAtlasSize)
            {
                scale  = (float)maximumAtlasSize / width;
                width  = maximumAtlasSize;
                height = (int)(height * scale);
            }
            width  = PowerOfTwo(width);
            height = PowerOfTwo(height);

            RenderTexture rt = new RenderTexture(width, height, 0)
            {
                enableRandomWrite = true,
                useMipMap         = true,
                autoGenerateMips  = false
            };

            rt.Create();

            ComputeShader cs = _computeShader;

            cs.SetTexture(_kernelId, "Target", rt);
            cs.SetFloat("Scale", 1 / scale);
            int len = textures.Count;

            Rect[] ret = new Rect[len];
            for (int i = 0; i < len; i++)
            {
                Packer.Block block = blocks[i];
                Texture2D    tex   = textures[block.i];
                cs.SetTexture(_kernelId, "Pixels", tex);
                block *= scale;
                cs.SetInts("Offset", block.x, block.y);
                cs.Dispatch(_kernelId, block.w / 8, block.h / 8, 1);
                ret[block.i] = new Rect(block.x / (float)width, block.y / (float)height, block.w / (float)width,
                                        block.h / (float)height);
            }

            rt.GenerateMips();
            result = rt;

            //result = new Texture2D(width, height);
            //RenderTexture tmp = RenderTexture.active;
            //RenderTexture.active = rt;
            ////TODO: !!!
            //result.ReadPixels(new Rect(0, 0, width, height), 0, 0);
            //UnityEngine.Profiling.Profiler.BeginSample("ReadPixels");
            //result.Apply(false, true);
            //UnityEngine.Profiling.Profiler.EndSample();
            //RenderTexture.active = tmp;


            return(ret);
        }