teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

2

実サイズを考慮するオプションを追加、字数削減のため旧コードを削除

2020/05/13 08:30

投稿

Bongo
Bongo

スコア10816

answer CHANGED
@@ -22,66 +22,7 @@
22
22
  たとえば下記のようなシェーダーを用意しておいて...
23
23
 
24
24
  ```ShaderLab
25
- Shader "Hidden/OverSampling"
26
- {
27
- Properties
28
- {
29
- _MainTex ("Texture", 2D) = "white" {}
30
- }
31
- SubShader
32
- {
33
- Cull Off ZWrite Off ZTest Always
34
-
35
- Pass
36
- {
37
- CGPROGRAM
38
- #pragma vertex vert
39
- #pragma fragment frag
40
-
41
- #include "UnityCG.cginc"
42
-
43
- struct appdata
44
- {
45
- float4 vertex : POSITION;
46
- float2 uv : TEXCOORD0;
47
- };
48
-
49
- struct v2f
50
- {
51
- float2 uv : TEXCOORD0;
52
- float4 vertex : SV_POSITION;
53
- };
54
-
55
- v2f vert(appdata v)
56
- {
57
- v2f o;
58
- o.vertex = UnityObjectToClipPos(v.vertex);
59
- o.uv = v.uv;
60
- return o;
61
- }
62
-
63
- sampler2D _MainTex;
64
- int _LoopCount;
65
-
66
- float4 frag (v2f i) : SV_Target
67
- {
68
- float2 texelSize = fwidth(i.uv);
69
- float2 deltaUV = texelSize / _LoopCount;
70
- float2 uv0 = i.uv + ((deltaUV - texelSize) * 0.5);
25
+ // 字数節約のため削除しました...削除前のコードは編集履歴をご参照ください
71
- float4 col = 0.0;
72
- for (int j = 0; j < _LoopCount; j++)
73
- {
74
- for (int i = 0; i < _LoopCount; i++)
75
- {
76
- col += tex2D(_MainTex, uv0 + (float2(i, j) * deltaUV));
77
- }
78
- }
79
- return col / (_LoopCount * _LoopCount);
80
- }
81
- ENDCG
82
- }
83
- }
84
- }
85
26
  ```
86
27
 
87
28
  ご質問者さんのスクリプトを下記のように改変して実行したところ...
@@ -252,34 +193,75 @@
252
193
  {
253
194
  private static Material overSamplingMaterial;
254
195
 
196
+ [SerializeField] private bool useActualSize;
197
+
255
198
  private void Start()
256
199
  {
257
200
  var texture2D = Resources.Load<Texture2D>("motogp");
258
201
 
202
+ // 目標サイズは200x200決め打ちではなく、Imageのサイズを見て決めることにする
203
+ var image = this.GetComponent<Image>();
204
+ var rectTransform = this.transform as RectTransform;
205
+ var sizeDelta = rectTransform.sizeDelta;
206
+ var toWidth = Mathf.RoundToInt(sizeDelta.x);
207
+ var toHeight = Mathf.RoundToInt(sizeDelta.y);
208
+
209
+ // インスペクターの「Use Actual Size」がオンの場合
210
+ // 目標サイズを最終的な表示サイズに合わせて調整する
211
+ if (this.useActualSize)
212
+ {
213
+ var canvas = image.canvas;
214
+ var canvasCamera = canvas.renderMode == RenderMode.ScreenSpaceOverlay ? null : canvas.worldCamera;
215
+ var corners = new Vector3[4];
216
+ rectTransform.GetWorldCorners(corners);
217
+ var bottomLeft = RectTransformUtility.WorldToScreenPoint(canvasCamera, corners[0]);
218
+ var topRight = RectTransformUtility.WorldToScreenPoint(canvasCamera, corners[2]);
219
+ var actualSize = topRight - bottomLeft;
220
+ toWidth = Mathf.RoundToInt(Mathf.Abs(actualSize.x));
221
+ toHeight = Mathf.RoundToInt(Mathf.Abs(actualSize.y));
222
+ }
223
+
259
- // まず元のテクスチャから切り出すべき領域を求める
224
+ // 元のテクスチャから切り出すべき領域を求める
260
- // テクスチャの中心からなるべく大きな正方形を切り出したいので
225
+ // テクスチャの中心からなるべく大きな形を切り出したいので
226
+ // まずテクスチャの高さに縦横比を掛けて希望切り出し幅を求める
261
- // 正方形一辺の長さはと高さのうち小さい方であり起点のズレ
227
+ // テクスチャの幅が希望切り出し幅よりも小さい場合切り出し幅
228
+ // テクスチャ幅とし、代わりに切り出し高さを切り詰める
262
- // 余白の大きさの半分ということになる
229
+ // 起点のズレは余白の大きさの半分ということになる
230
+ var toAspect = (float)toWidth / toHeight;
263
231
  var width = texture2D.width;
264
232
  var height = texture2D.height;
265
- var size = width > height ? height : width;
233
+ var expectedWidth = Mathf.RoundToInt(height * toAspect);
234
+ var fromWidth = Mathf.Min(width, expectedWidth);
235
+ var fromHeight = expectedWidth > width ? Mathf.RoundToInt(width / toAspect) : height;
266
- var offsetX = (width - size) / 2;
236
+ var offsetX = (width - fromWidth) / 2;
267
- var offsetY = (height - size) / 2;
237
+ var offsetY = (height - fromHeight) / 2;
268
238
 
239
+ // 確認のため、リサイズ前とリサイズ後のサイズをコンソールに表示してみる
240
+ Debug.LogFormat("({0}, {1}) -> [({2}, {3}), ({4}, {5})] -> ({6}, {7})",
241
+ width, height,
242
+ offsetX, offsetY, fromWidth, fromHeight,
243
+ toWidth, toHeight);
244
+
269
- // 切り出された領域を200x200に縮小して最終的なテクスチャとする
245
+ // 切り出された領域をリサイズして最終的なテクスチャとする
270
246
  // ちなみに、ご質問者さんが作成された方のGetResizedも残してありますので、
271
- // 引数を元テクスチャと縮小後サイズだけに省略するとそちらが使われます
247
+ // 引数を元テクスチャと目標サイズだけに省略するとそちらが使われます
272
248
  // そちらに切り替えてみると、トリミング処理の有無による違いやぼけ具合の
273
249
  // 比較ができるかと思います
274
- var resizedTexture = GetResized(texture2D, offsetX, offsetY, size, size, 200, 200);
250
+ var resizedTexture = GetResized(texture2D, offsetX, offsetY, fromWidth, fromHeight, toWidth, toHeight);
275
251
  //var resizedTexture = GetResized(texture2D, 200, 200);
276
252
 
253
+ // 最終的に表示される位置・サイズによっては、小数点以下のズレのため
254
+ // ぼやけやImage外周部に反対側の辺の色が乗る現象が起こる可能性がある
255
+ // そこで、それらを回避するようにテクスチャの設定を変更する
256
+ resizedTexture.filterMode = FilterMode.Point;
257
+ resizedTexture.wrapMode = TextureWrapMode.Clamp;
258
+
277
259
  // リサイズ後のテクスチャをもとにスプライトを作成し、Imageにセット
278
260
  var sprite = Sprite.Create(
279
261
  resizedTexture,
280
262
  new Rect(0, 0, resizedTexture.width, resizedTexture.height),
281
263
  new Vector2(0.5f, 0.5f));
282
- this.GetComponent<Image>().sprite = sprite;
264
+ image.sprite = sprite;
283
265
  }
284
266
 
285
267
  // 元のテクスチャから(fromX, fromY)を起点とする幅fromWidth、高さfromHeightの領域を
@@ -288,7 +270,8 @@
288
270
  Texture2D texture,
289
271
  int fromX, int fromY, int fromWidth, int fromHeight,
290
272
  int toWidth, int toHeight,
291
- int loopCount = 16)
273
+ int loopCount = 16,
274
+ bool generateMipmaps = false)
292
275
  {
293
276
  if (overSamplingMaterial == null)
294
277
  {
@@ -309,15 +292,17 @@
309
292
  overSamplingMaterial.SetVector(
310
293
  "_TilingAndOffset",
311
294
  new Vector4(
312
- (float)fromWidth / sourceWidth, (float)fromHeight / sourceHeight,
295
+ (float)fromWidth / sourceWidth,
313
- (float)fromX / sourceWidth, (float)fromY / sourceHeight));
296
+ (float)fromHeight / sourceHeight,
297
+ (float)fromX / sourceWidth,
298
+ (float)fromY / sourceHeight));
314
299
  overSamplingMaterial.SetInt("_LoopCount", Mathf.Max(loopCount, 1));
315
300
 
316
301
  // あとは以前と同様にリサイズし、結果を返す
317
302
  var rt = RenderTexture.GetTemporary(toWidth, toHeight);
318
303
  Graphics.Blit(sourceRT, rt, overSamplingMaterial);
319
304
  RenderTexture.active = rt;
320
- var ret = new Texture2D(toWidth, toHeight);
305
+ var ret = new Texture2D(toWidth, toHeight, TextureFormat.ARGB32, generateMipmaps);
321
306
  ret.ReadPixels(new Rect(0, 0, toWidth, toHeight), 0, 0);
322
307
  ret.Apply();
323
308
  RenderTexture.active = preRT;

1

正方形トリミング案を追記

2020/05/13 08:30

投稿

Bongo
Bongo

スコア10816

answer CHANGED
@@ -24,63 +24,63 @@
24
24
  ```ShaderLab
25
25
  Shader "Hidden/OverSampling"
26
26
  {
27
- Properties
27
+ Properties
28
- {
28
+ {
29
- _MainTex ("Texture", 2D) = "white" {}
29
+ _MainTex ("Texture", 2D) = "white" {}
30
- }
30
+ }
31
- SubShader
31
+ SubShader
32
- {
32
+ {
33
- Cull Off ZWrite Off ZTest Always
33
+ Cull Off ZWrite Off ZTest Always
34
34
 
35
- Pass
35
+ Pass
36
- {
36
+ {
37
- CGPROGRAM
37
+ CGPROGRAM
38
- #pragma vertex vert
38
+ #pragma vertex vert
39
- #pragma fragment frag
39
+ #pragma fragment frag
40
40
 
41
- #include "UnityCG.cginc"
41
+ #include "UnityCG.cginc"
42
42
 
43
- struct appdata
43
+ struct appdata
44
- {
44
+ {
45
- float4 vertex : POSITION;
45
+ float4 vertex : POSITION;
46
- float2 uv : TEXCOORD0;
46
+ float2 uv : TEXCOORD0;
47
- };
47
+ };
48
48
 
49
- struct v2f
49
+ struct v2f
50
- {
50
+ {
51
- float2 uv : TEXCOORD0;
51
+ float2 uv : TEXCOORD0;
52
- float4 vertex : SV_POSITION;
52
+ float4 vertex : SV_POSITION;
53
- };
53
+ };
54
54
 
55
- v2f vert(appdata v)
55
+ v2f vert(appdata v)
56
- {
56
+ {
57
- v2f o;
57
+ v2f o;
58
- o.vertex = UnityObjectToClipPos(v.vertex);
58
+ o.vertex = UnityObjectToClipPos(v.vertex);
59
- o.uv = v.uv;
59
+ o.uv = v.uv;
60
- return o;
60
+ return o;
61
- }
61
+ }
62
62
 
63
- sampler2D _MainTex;
63
+ sampler2D _MainTex;
64
- int _LoopCount;
64
+ int _LoopCount;
65
65
 
66
- float4 frag (v2f i) : SV_Target
66
+ float4 frag (v2f i) : SV_Target
67
- {
67
+ {
68
- float2 texelSize = fwidth(i.uv);
68
+ float2 texelSize = fwidth(i.uv);
69
- float2 deltaUV = texelSize / _LoopCount;
69
+ float2 deltaUV = texelSize / _LoopCount;
70
- float2 uv0 = i.uv + ((deltaUV - texelSize) * 0.5);
70
+ float2 uv0 = i.uv + ((deltaUV - texelSize) * 0.5);
71
- float4 col = 0.0;
71
+ float4 col = 0.0;
72
- for (int j = 0; j < _LoopCount; j++)
72
+ for (int j = 0; j < _LoopCount; j++)
73
- {
73
+ {
74
- for (int i = 0; i < _LoopCount; i++)
74
+ for (int i = 0; i < _LoopCount; i++)
75
- {
75
+ {
76
- col += tex2D(_MainTex, uv0 + (float2(i, j) * deltaUV));
76
+ col += tex2D(_MainTex, uv0 + (float2(i, j) * deltaUV));
77
- }
77
+ }
78
- }
78
+ }
79
- return col / (_LoopCount * _LoopCount);
79
+ return col / (_LoopCount * _LoopCount);
80
- }
80
+ }
81
- ENDCG
81
+ ENDCG
82
- }
82
+ }
83
- }
83
+ }
84
84
  }
85
85
  ```
86
86
 
@@ -93,67 +93,67 @@
93
93
 
94
94
  public static class TextureResizer
95
95
  {
96
- private static Material overSamplingMaterial;
96
+ private static Material overSamplingMaterial;
97
97
 
98
- [MenuItem("Utility/Resize Selected Texture to 200 x 200")]
98
+ [MenuItem("Utility/Resize Selected Texture to 200 x 200")]
99
- public static void ResizeTextureTo200x200()
99
+ public static void ResizeTextureTo200x200()
100
- {
100
+ {
101
- const int newWidth = 200;
101
+ const int newWidth = 200;
102
- const int newHeight = 200;
102
+ const int newHeight = 200;
103
- const int loopCount = 16;
103
+ const int loopCount = 16;
104
- var targetTexture = Selection.activeObject as Texture2D;
104
+ var targetTexture = Selection.activeObject as Texture2D;
105
- if (targetTexture == null)
105
+ if (targetTexture == null)
106
- {
106
+ {
107
- return;
107
+ return;
108
- }
108
+ }
109
109
 
110
- var targetPath = AssetDatabase.GetAssetPath(targetTexture);
110
+ var targetPath = AssetDatabase.GetAssetPath(targetTexture);
111
- if (string.IsNullOrEmpty(targetPath))
111
+ if (string.IsNullOrEmpty(targetPath))
112
- {
112
+ {
113
- return;
113
+ return;
114
- }
114
+ }
115
115
 
116
- var targetDirectory = Path.GetDirectoryName(targetPath);
116
+ var targetDirectory = Path.GetDirectoryName(targetPath);
117
- var targetName = Path.GetFileNameWithoutExtension(targetPath);
117
+ var targetName = Path.GetFileNameWithoutExtension(targetPath);
118
- var targetExtension = Path.GetExtension(targetPath);
118
+ var targetExtension = Path.GetExtension(targetPath);
119
- var newName = $"{targetName}({newWidth}x{newHeight})";
119
+ var newName = $"{targetName}({newWidth}x{newHeight})";
120
- var newPath = $"{targetDirectory}{Path.DirectorySeparatorChar}{newName}{targetExtension}";
120
+ var newPath = $"{targetDirectory}{Path.DirectorySeparatorChar}{newName}{targetExtension}";
121
- var newTexture = GetResized(targetTexture, newWidth, newHeight, loopCount);
121
+ var newTexture = GetResized(targetTexture, newWidth, newHeight, loopCount);
122
- File.WriteAllBytes(newPath, newTexture.EncodeToPNG());
122
+ File.WriteAllBytes(newPath, newTexture.EncodeToPNG());
123
- AssetDatabase.ImportAsset(newPath);
123
+ AssetDatabase.ImportAsset(newPath);
124
- }
124
+ }
125
125
 
126
- private static Texture2D GetResized(Texture2D texture, int width, int height, int loopCount)
126
+ private static Texture2D GetResized(Texture2D texture, int width, int height, int loopCount)
127
- {
127
+ {
128
- // オーバーサンプリング用マテリアルを作成する
128
+ // オーバーサンプリング用マテリアルを作成する
129
- if (overSamplingMaterial == null)
129
+ if (overSamplingMaterial == null)
130
- {
130
+ {
131
- overSamplingMaterial = new Material(Shader.Find("Hidden/OverSampling"));
131
+ overSamplingMaterial = new Material(Shader.Find("Hidden/OverSampling"));
132
- }
132
+ }
133
133
 
134
- // まず元と同じサイズのRenderTextureに書き込む
134
+ // まず元と同じサイズのRenderTextureに書き込む
135
- var sourceRT = RenderTexture.GetTemporary(texture.width, texture.height);
135
+ var sourceRT = RenderTexture.GetTemporary(texture.width, texture.height);
136
- Graphics.Blit(texture, sourceRT);
136
+ Graphics.Blit(texture, sourceRT);
137
137
 
138
- // filterModeをPointにしておき、サンプリング時に注目点以外の色が混じらないようにしておく
138
+ // filterModeをPointにしておき、サンプリング時に注目点以外の色が混じらないようにしておく
139
- sourceRT.filterMode = FilterMode.Point;
139
+ sourceRT.filterMode = FilterMode.Point;
140
140
 
141
- // リサイズ後のサイズを持つRenderTextureを作成して、オーバーサンプリングマテリアルを使って書き込む
141
+ // リサイズ後のサイズを持つRenderTextureを作成して、オーバーサンプリングマテリアルを使って書き込む
142
- var rt = RenderTexture.GetTemporary(width, height);
142
+ var rt = RenderTexture.GetTemporary(width, height);
143
- overSamplingMaterial.SetInt("_LoopCount", Mathf.Max(loopCount, 1));
143
+ overSamplingMaterial.SetInt("_LoopCount", Mathf.Max(loopCount, 1));
144
- Graphics.Blit(sourceRT, rt, overSamplingMaterial);
144
+ Graphics.Blit(sourceRT, rt, overSamplingMaterial);
145
145
 
146
- // リサイズ後のサイズを持つTexture2Dを作成してRenderTextureから書き込む
146
+ // リサイズ後のサイズを持つTexture2Dを作成してRenderTextureから書き込む
147
- var preRT = RenderTexture.active;
147
+ var preRT = RenderTexture.active;
148
- RenderTexture.active = rt;
148
+ RenderTexture.active = rt;
149
- var ret = new Texture2D(width, height);
149
+ var ret = new Texture2D(width, height);
150
- ret.ReadPixels(new Rect(0, 0, width, height), 0, 0);
150
+ ret.ReadPixels(new Rect(0, 0, width, height), 0, 0);
151
- ret.Apply();
151
+ ret.Apply();
152
- RenderTexture.active = preRT;
152
+ RenderTexture.active = preRT;
153
- RenderTexture.ReleaseTemporary(rt);
153
+ RenderTexture.ReleaseTemporary(rt);
154
- RenderTexture.ReleaseTemporary(sourceRT);
154
+ RenderTexture.ReleaseTemporary(sourceRT);
155
- return ret;
155
+ return ret;
156
- }
156
+ }
157
157
  }
158
158
  ```
159
159
 
@@ -169,4 +169,184 @@
169
169
 
170
170
  ![図7](830198f126de168c40362776a29031ee.png)
171
171
 
172
- となりました。だいぶ精密さが向上したんじゃないかと思いますが、いかがでしょうか?
172
+ となりました。だいぶ精密さが向上したんじゃないかと思いますが、いかがでしょうか?
173
+
174
+ **正方形トリミングについて**
175
+
176
+ まずシェーダーコードは下記のように変更して、UV座標を操作することで画像切り出し範囲を調整できるようにしておきます。
177
+
178
+ ```ShaderLab
179
+ Shader "Hidden/OverSampling"
180
+ {
181
+ Properties
182
+ {
183
+ _MainTex ("Texture", 2D) = "white" {}
184
+ }
185
+ SubShader
186
+ {
187
+ Cull Off ZWrite Off ZTest Always
188
+
189
+ Pass
190
+ {
191
+ CGPROGRAM
192
+ #pragma vertex vert
193
+ #pragma fragment frag
194
+
195
+ #include "UnityCG.cginc"
196
+
197
+ struct appdata
198
+ {
199
+ float4 vertex : POSITION;
200
+ float2 uv : TEXCOORD0;
201
+ };
202
+
203
+ struct v2f
204
+ {
205
+ float2 uv : TEXCOORD0;
206
+ float4 vertex : SV_POSITION;
207
+ };
208
+
209
+ sampler2D _MainTex;
210
+ float4 _TilingAndOffset;
211
+ int _LoopCount;
212
+
213
+ v2f vert(appdata v)
214
+ {
215
+ v2f o;
216
+ o.vertex = UnityObjectToClipPos(v.vertex);
217
+ o.uv = (v.uv * _TilingAndOffset.xy) + _TilingAndOffset.zw;
218
+ return o;
219
+ }
220
+
221
+ float4 frag (v2f i) : SV_Target
222
+ {
223
+ float2 texelSize = fwidth(i.uv);
224
+ float2 deltaUV = texelSize / _LoopCount;
225
+ float2 uv0 = i.uv + ((deltaUV - texelSize) * 0.5);
226
+ float4 col = 0.0;
227
+ for (int j = 0; j < _LoopCount; j++)
228
+ {
229
+ for (int i = 0; i < _LoopCount; i++)
230
+ {
231
+ col += tex2D(_MainTex, uv0 + (float2(i, j) * deltaUV));
232
+ }
233
+ }
234
+ return col / (_LoopCount * _LoopCount);
235
+ }
236
+ ENDCG
237
+ }
238
+ }
239
+ }
240
+ ```
241
+
242
+ そして制御用のスクリプトは下記のようにしました。
243
+ ご追記のスクリーンショットを拝見しますに、どうやらImageを使って縮小後のテクスチャを表示している様子ですね。表示用のスプライトはどのように用意していますでしょうか?私の場合はさしあたり縮小後のテクスチャを使ったスプライトを新規作成し、それを`Image`コンポーネントにセットしてやることにしました。
244
+ スクリプトはサイズ200×200のImageオブジェクトにアタッチして使うことを想定しており、`Start`内で元テクスチャをロード・縮小テクスチャを生成・スプライトを作成して`Image`にセット...の処理を行っています。
245
+
246
+ ```C#
247
+ using UnityEngine;
248
+ using UnityEngine.UI;
249
+
250
+ [RequireComponent(typeof(Image))]
251
+ public class ResizedImageLoader : MonoBehaviour
252
+ {
253
+ private static Material overSamplingMaterial;
254
+
255
+ private void Start()
256
+ {
257
+ var texture2D = Resources.Load<Texture2D>("motogp");
258
+
259
+ // まず元のテクスチャから切り出すべき領域を求める
260
+ // テクスチャの中心からなるべく大きな正方形を切り出したいので
261
+ // 正方形の一辺の長さは幅と高さのうち小さい方であり、起点のズレは
262
+ // 余白の大きさの半分ということになる
263
+ var width = texture2D.width;
264
+ var height = texture2D.height;
265
+ var size = width > height ? height : width;
266
+ var offsetX = (width - size) / 2;
267
+ var offsetY = (height - size) / 2;
268
+
269
+ // 切り出された領域を200x200に縮小して最終的なテクスチャとする
270
+ // ちなみに、ご質問者さんが作成された方のGetResizedも残してありますので、
271
+ // 引数を元テクスチャと縮小後サイズだけに省略するとそちらが使われます
272
+ // そちらに切り替えてみると、トリミング処理の有無による違いやぼけ具合の
273
+ // 比較ができるかと思います
274
+ var resizedTexture = GetResized(texture2D, offsetX, offsetY, size, size, 200, 200);
275
+ //var resizedTexture = GetResized(texture2D, 200, 200);
276
+
277
+ // リサイズ後のテクスチャをもとにスプライトを作成し、Imageにセット
278
+ var sprite = Sprite.Create(
279
+ resizedTexture,
280
+ new Rect(0, 0, resizedTexture.width, resizedTexture.height),
281
+ new Vector2(0.5f, 0.5f));
282
+ this.GetComponent<Image>().sprite = sprite;
283
+ }
284
+
285
+ // 元のテクスチャから(fromX, fromY)を起点とする幅fromWidth、高さfromHeightの領域を
286
+ // 切り出し、それを幅toWidth、高さtoHeightにリサイズしたテクスチャを生成する
287
+ private static Texture2D GetResized(
288
+ Texture2D texture,
289
+ int fromX, int fromY, int fromWidth, int fromHeight,
290
+ int toWidth, int toHeight,
291
+ int loopCount = 16)
292
+ {
293
+ if (overSamplingMaterial == null)
294
+ {
295
+ overSamplingMaterial = new Material(Shader.Find("Hidden/OverSampling"));
296
+ }
297
+
298
+ // まずは以前同様に元テクスチャをRenderTextureに写し取り、FilterModeをPointにしておく
299
+ var preRT = RenderTexture.active;
300
+ var sourceWidth = texture.width;
301
+ var sourceHeight = texture.height;
302
+ var sourceRT = RenderTexture.GetTemporary(sourceWidth, sourceHeight);
303
+ Graphics.Blit(texture, sourceRT);
304
+ sourceRT.filterMode = FilterMode.Point;
305
+
306
+ // マテリアルの設定を行う
307
+ // 元のテクスチャから起点(fromX, fromY)、サイズ(fromWidth, fromHeight)の部分を
308
+ // 切り出すということは、UV座標のタイリング・オフセットは下記のようになる
309
+ overSamplingMaterial.SetVector(
310
+ "_TilingAndOffset",
311
+ new Vector4(
312
+ (float)fromWidth / sourceWidth, (float)fromHeight / sourceHeight,
313
+ (float)fromX / sourceWidth, (float)fromY / sourceHeight));
314
+ overSamplingMaterial.SetInt("_LoopCount", Mathf.Max(loopCount, 1));
315
+
316
+ // あとは以前と同様にリサイズし、結果を返す
317
+ var rt = RenderTexture.GetTemporary(toWidth, toHeight);
318
+ Graphics.Blit(sourceRT, rt, overSamplingMaterial);
319
+ RenderTexture.active = rt;
320
+ var ret = new Texture2D(toWidth, toHeight);
321
+ ret.ReadPixels(new Rect(0, 0, toWidth, toHeight), 0, 0);
322
+ ret.Apply();
323
+ RenderTexture.active = preRT;
324
+ RenderTexture.ReleaseTemporary(rt);
325
+ RenderTexture.ReleaseTemporary(sourceRT);
326
+ return ret;
327
+ }
328
+
329
+ // ご質問者さんの方法によるGetResized
330
+ private static Texture2D GetResized(Texture2D texture, int width, int height)
331
+ {
332
+ var rt = RenderTexture.GetTemporary(width, height);
333
+ Graphics.Blit(texture, rt);
334
+ var preRT = RenderTexture.active;
335
+ RenderTexture.active = rt;
336
+ var ret = new Texture2D(width, height);
337
+ ret.ReadPixels(new Rect(0, 0, width, height), 0, 0);
338
+ ret.Apply();
339
+ RenderTexture.active = preRT;
340
+ RenderTexture.ReleaseTemporary(rt);
341
+ return ret;
342
+ }
343
+ }
344
+ ```
345
+
346
+ 当初の方法だと、縦長の画像が正方形に縮小されることで縦に潰れてしまっていたのが...
347
+
348
+ ![図8](351996976c3d2f50999f0da22b088b1d.png)
349
+
350
+ 正方形に切り出す処理が加わることで、被写体が潰れないようになりました。
351
+
352
+ ![図9](2aa29ffc694b1eb86d5f4552e091c20a.png)