1
+ using System . Collections . Generic ;
2
+ using UnityEngine ;
3
+ using System . Threading . Tasks ;
4
+
5
+ namespace Gameframe . Procgen
6
+ {
7
+ // Only works on ARGB32, RGB24 and Alpha8 textures that are marked readable
8
+ public static class TextureScale
9
+ {
10
+ public class TaskData
11
+ {
12
+ public int start ;
13
+ public int end ;
14
+
15
+ public TaskData ( int s , int e )
16
+ {
17
+ start = s ;
18
+ end = e ;
19
+ }
20
+ }
21
+
22
+ public static async Task PointAsync ( Texture2D tex , int newWidth , int newHeight )
23
+ {
24
+ await ThreadedScaleAsync ( tex , newWidth , newHeight , false ) ;
25
+ }
26
+
27
+ public static async Task BilinearAsync ( Texture2D tex , int newWidth , int newHeight )
28
+ {
29
+ await ThreadedScaleAsync ( tex , newWidth , newHeight , true ) ;
30
+ }
31
+
32
+ private static async Task ThreadedScaleAsync ( Texture2D tex , int newWidth , int newHeight , bool useBilinear )
33
+ {
34
+ var texColors = tex . GetPixels ( ) ;
35
+ var newColors = new Color [ newWidth * newHeight ] ;
36
+
37
+ float ratioX ;
38
+ float ratioY ;
39
+ if ( useBilinear )
40
+ {
41
+ ratioX = 1.0f / ( ( float ) newWidth / ( tex . width - 1 ) ) ;
42
+ ratioY = 1.0f / ( ( float ) newHeight / ( tex . height - 1 ) ) ;
43
+ }
44
+ else
45
+ {
46
+ ratioX = ( ( float ) tex . width ) / newWidth ;
47
+ ratioY = ( ( float ) tex . height ) / newHeight ;
48
+ }
49
+
50
+ var width = tex . width ;
51
+
52
+ var cores = Mathf . Min ( SystemInfo . processorCount , newHeight ) ;
53
+ var slice = newHeight / cores ;
54
+
55
+ var tasks = new List < Task > ( ) ;
56
+
57
+ if ( cores > 1 )
58
+ {
59
+ for ( var i = 0 ; i < cores ; i ++ )
60
+ {
61
+ var taskData = new TaskData ( slice * i , slice * ( i + 1 ) ) ;
62
+ var task = Task . Run ( ( ) =>
63
+ {
64
+ if ( useBilinear )
65
+ {
66
+ BilinearScale ( taskData , texColors , newColors , width , newWidth , ratioX , ratioY ) ;
67
+ }
68
+ else
69
+ {
70
+ PointScale ( taskData , texColors , newColors , width , newWidth , ratioX , ratioY ) ;
71
+ }
72
+ } ) ;
73
+ tasks . Add ( task ) ;
74
+ }
75
+ await Task . WhenAll ( tasks ) ;
76
+ }
77
+ else
78
+ {
79
+ var taskData = new TaskData ( 0 , newHeight ) ;
80
+ await Task . Run ( ( ) =>
81
+ {
82
+ if ( useBilinear )
83
+ {
84
+ BilinearScale ( taskData , texColors , newColors , width , newWidth , ratioX , ratioY ) ;
85
+ }
86
+ else
87
+ {
88
+ PointScale ( taskData , texColors , newColors , width , newWidth , ratioX , ratioY ) ;
89
+ }
90
+ } ) ;
91
+ }
92
+
93
+ tex . Resize ( newWidth , newHeight ) ;
94
+ tex . SetPixels ( newColors ) ;
95
+ tex . Apply ( ) ;
96
+ }
97
+
98
+ private static void BilinearScale ( TaskData taskData , Color [ ] texColors , Color [ ] newColors , int width , int newWidth , float ratioX , float ratioY )
99
+ {
100
+ for ( var y = taskData . start ; y < taskData . end ; y ++ )
101
+ {
102
+ int yFloor = ( int ) Mathf . Floor ( y * ratioY ) ;
103
+ var y1 = yFloor * width ;
104
+ var y2 = ( yFloor + 1 ) * width ;
105
+ var yw = y * newWidth ;
106
+
107
+ for ( var x = 0 ; x < newWidth ; x ++ )
108
+ {
109
+ int xFloor = ( int ) Mathf . Floor ( x * ratioX ) ;
110
+ var xLerp = x * ratioX - xFloor ;
111
+ newColors [ yw + x ] = ColorLerpUnclamped (
112
+ ColorLerpUnclamped ( texColors [ y1 + xFloor ] , texColors [ y1 + xFloor + 1 ] , xLerp ) ,
113
+ ColorLerpUnclamped ( texColors [ y2 + xFloor ] , texColors [ y2 + xFloor + 1 ] , xLerp ) ,
114
+ y * ratioY - yFloor ) ;
115
+ }
116
+ }
117
+ }
118
+
119
+ private static void PointScale ( TaskData taskData , Color [ ] texColors , Color [ ] newColors , int width , int newWidth , float ratioX , float ratioY )
120
+ {
121
+ for ( var y = taskData . start ; y < taskData . end ; y ++ )
122
+ {
123
+ var thisY = ( int ) ( ratioY * y ) * width ;
124
+ var yw = y * newWidth ;
125
+ for ( var x = 0 ; x < newWidth ; x ++ )
126
+ {
127
+ newColors [ yw + x ] = texColors [ ( int ) ( thisY + ratioX * x ) ] ;
128
+ }
129
+ }
130
+ }
131
+
132
+ private static Color ColorLerpUnclamped ( Color c1 , Color c2 , float value )
133
+ {
134
+ return new Color ( c1 . r + ( c2 . r - c1 . r ) * value ,
135
+ c1 . g + ( c2 . g - c1 . g ) * value ,
136
+ c1 . b + ( c2 . b - c1 . b ) * value ,
137
+ c1 . a + ( c2 . a - c1 . a ) * value ) ;
138
+ }
139
+
140
+ }
141
+ }
0 commit comments