Пример #1
0
        public static void BilinearScale(ThreadData threadData, ShaderJobData jobData)
        {
            for (var y = threadData.start; y < threadData.end; y++)
            {
                int yFloor = (int)math.floor(y * jobData.ratioY);
                var y1     = yFloor * jobData.w;
                var y2     = (yFloor + 1) * jobData.w;
                var yw     = y * jobData.w2;

                for (var x = 0; x < jobData.w2; x++)
                {
                    int xFloor = (int)math.floor(x * jobData.ratioX);
                    var xLerp  = x * jobData.ratioX - xFloor;
                    jobData.newColors[yw + x] = ColorLerpUnclamped(
                        ColorLerpUnclamped(
                            jobData.texColors[y1 + xFloor],
                            jobData.texColors[y1 + xFloor + 1],
                            xLerp
                            ),
                        ColorLerpUnclamped(
                            jobData.texColors[y2 + xFloor],
                            jobData.texColors[y2 + xFloor + 1],
                            xLerp
                            ),
                        y * jobData.ratioY - yFloor
                        );
                }
            }
        }
Пример #2
0
 public static void PointScale(ThreadData threadData, ShaderJobData jobData)
 {
     for (var y = threadData.start; y < threadData.end; y++)
     {
         var thisY = (int)(jobData.ratioY * y) * jobData.w;
         var yw    = y * jobData.w2;
         for (var x = 0; x < jobData.w2; x++)
         {
             jobData.newColors[yw + x] = jobData.texColors[(int)(thisY + jobData.ratioX * x)];
         }
     }
 }
Пример #3
0
        static async Task ThreadedScale(Texture2D texture, int newWidth, int newHeight, bool useBilinear)
        {
            //early check:
            if (texture.width == newWidth && texture.height == newHeight)
            {
                //unnecessary runs proved to produce invalid textures, so let's not do that
                return;
            }

            //
            using (ShaderJobData jobData = new ShaderJobData())
            {
                try
                {
                    jobData.texColors = texture.GetPixels();
                    jobData.newColors = new Color[newWidth * newHeight];
                    if (useBilinear)
                    {
                        jobData.ratioX = 1f / ((float)newWidth / (texture.width - 1));
                        jobData.ratioY = 1f / ((float)newHeight / (texture.height - 1));
                    }
                    else
                    {
                        jobData.ratioX = ((float)texture.width) / newWidth;
                        jobData.ratioY = ((float)texture.height) / newHeight;
                    }
                    jobData.w  = texture.width;
                    jobData.w2 = newWidth;
                    var cores = math.min(SystemInfo.processorCount, newHeight);
                    var slice = newHeight / cores;

                    if (cores > 1)
                    {
                        int i = 0;

                        //run tasks on other threads:
                        Task[] tasks = new Task[cores];
                        for (i = 0; i < cores; i++)
                        {
                            ThreadData threadData = new ThreadData(slice * i, slice * (i + 1));
                            tasks[i] = (
                                Task.Run(() => {
                                try
                                {
                                    if (useBilinear)
                                    {
                                        BilinearScale(threadData, jobData);
                                    }
                                    else
                                    {
                                        PointScale(threadData, jobData);
                                    }
                                }
                                catch (System.Exception ex) { Debug.LogException(ex); }
                            })
                                );
                        }

                        //wait until all other tasks completed:
                        await Task.WhenAll(tasks);
                    }
                    else
                    {
                        ThreadData threadData = new ThreadData(0, newHeight);
                        if (useBilinear)
                        {
                            BilinearScale(threadData, jobData);
                        }
                        else
                        {
                            PointScale(threadData, jobData);
                        }
                    }

                    texture.Resize(newWidth, newHeight);
                    texture.SetPixels(jobData.newColors);
                    texture.Apply();
                }
                catch (System.Exception ex)
                {
                    Debug.LogException(ex);
                }
            }
        }