回答編集履歴

3

Unlit版を追記

2021/01/20 20:47

投稿

Bongo
Bongo

スコア10807

test CHANGED
@@ -24,177 +24,177 @@
24
24
 
25
25
  {
26
26
 
27
- [SerializeField][Min(0.0f)] private float planeWidth = 4.0f;
28
-
29
- [SerializeField][Min(0.0f)] private float planeHeight = 3.0f;
30
-
31
- [SerializeField][Min(0.0f)] private float hemisphereRadius = 1.0f;
32
-
33
- [SerializeField][Min(1)] private int divisions = 8;
34
-
35
-
36
-
37
- private void OnWizardCreate()
38
-
39
- {
40
-
41
- var bottomLeft = new Vector3(-this.planeWidth * 0.5f, -this.planeHeight * 0.5f, 0.0f);
42
-
43
- var texelWidth = 0.5f / this.divisions;
44
-
45
- var texelHeight = 0.5f / this.divisions;
46
-
47
- var deltaX = this.planeWidth * texelWidth;
48
-
49
- var deltaY = this.planeHeight * texelHeight;
50
-
51
- var vertexCountX = (this.divisions * 2) + 1;
52
-
53
- var vertexCountY = (this.divisions * 2) + 1;
54
-
55
- var planeVertices = Enumerable.Range(0, vertexCountY).SelectMany(
56
-
57
- j => Enumerable.Range(0, vertexCountX).Select(
58
-
59
- i => bottomLeft + new Vector3(i * deltaX, j * deltaY, 0.0f))).ToArray();
60
-
61
- var planeNormals = planeVertices.Select(_ => Vector3.back).ToArray();
62
-
63
- var planeTangents = planeVertices.Select(_ => new Vector4(1.0f, 0.0f, 0.0f, -1.0f)).ToArray();
64
-
65
- var planeUvs = Enumerable.Range(0, vertexCountY).SelectMany(
66
-
67
- j => Enumerable.Range(0, vertexCountX).Select(
68
-
69
- i => new Vector2(i * texelWidth, j * texelHeight))).ToArray();
70
-
71
- var quadTriangles = new[]
72
-
73
- {
74
-
75
- 0, vertexCountX, 1, vertexCountX + 1, 1, vertexCountX
76
-
77
- };
78
-
79
- var planeTriangles = Enumerable.Range(0, vertexCountY - 1).SelectMany(
80
-
81
- j => Enumerable.Range(0, vertexCountX - 1).SelectMany(
82
-
83
- i => quadTriangles.Select(k => i + (j * vertexCountX) + k))).ToArray();
84
-
85
- var hemisphereNormals = planeUvs.Select(
86
-
87
- uv =>
88
-
89
- {
90
-
91
- var angleH = (uv.x + 0.5f) * Mathf.PI;
92
-
93
- var angleV = (uv.y - 0.5f) * Mathf.PI;
94
-
95
- var sinH = Mathf.Sin(angleH);
96
-
97
- var cosH = Mathf.Cos(angleH);
98
-
99
- var sinV = Mathf.Sin(angleV);
100
-
101
- var cosV = Mathf.Cos(angleV);
102
-
103
- return new Vector3(-sinH * cosV, sinV, cosH * cosV);
104
-
105
- }).ToArray();
106
-
107
- var hemisphereTangents = planeUvs.Select(
108
-
109
- uv =>
110
-
111
- {
112
-
113
- var angleH = (uv.x + 0.5f) * Mathf.PI;
114
-
115
- var sinH = Mathf.Sin(angleH);
116
-
117
- var cosH = Mathf.Cos(angleH);
118
-
119
- return new Vector4(-cosH, 0.0f, -sinH, -1.0f);
120
-
121
- }).ToArray();
122
-
123
- var hemisphereVertices = hemisphereNormals.Select(normal => normal * this.hemisphereRadius).ToArray();
124
-
125
- var mesh = new Mesh
126
-
127
- {
128
-
129
- name = "PlaneToHemisphere",
130
-
131
- vertices = planeVertices,
132
-
133
- normals = planeNormals,
134
-
135
- tangents = planeTangents,
136
-
137
- uv = planeUvs,
138
-
139
- triangles = planeTriangles
140
-
141
- };
142
-
143
- mesh.AddBlendShapeFrame(
144
-
145
- "Deformation",
146
-
147
- 100.0f,
148
-
149
- planeVertices.Zip(
150
-
151
- hemisphereVertices,
152
-
153
- (planeVertex, hemisphereVertex) => hemisphereVertex - planeVertex).ToArray(),
154
-
155
- planeNormals.Zip(
156
-
157
- hemisphereNormals,
158
-
159
- (planeNormal, hemisphereNormal) => hemisphereNormal - planeNormal).ToArray(),
160
-
161
- planeTangents.Zip(
162
-
163
- hemisphereTangents,
164
-
165
- (planeTangent, hemisphereTangent) => (Vector3)hemisphereTangent - (Vector3)planeTangent).ToArray());
166
-
167
- mesh.RecalculateNormals();
168
-
169
- mesh.RecalculateTangents();
170
-
171
- var cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
172
-
173
- var newObject = new GameObject(mesh.name);
174
-
175
- var skinnedMeshRenderer = newObject.AddComponent<SkinnedMeshRenderer>();
176
-
177
- skinnedMeshRenderer.sharedMesh = mesh;
178
-
179
- skinnedMeshRenderer.sharedMaterial = cube.GetComponent<Renderer>().sharedMaterial;
180
-
181
- DestroyImmediate(cube);
182
-
183
- ProjectWindowUtil.CreateAsset(mesh, $"{mesh.name}.asset");
184
-
185
- }
186
-
187
-
188
-
189
- [MenuItem("Assets/Create/Plane to Hemisphere")]
190
-
191
- private static void OpenWizard()
192
-
193
- {
194
-
195
- DisplayWizard<PlaneToHemisphereWizard>("Plane to Hemisphere");
196
-
197
- }
27
+ [SerializeField][Min(0.0f)] private float planeWidth = 4.0f;
28
+
29
+ [SerializeField][Min(0.0f)] private float planeHeight = 3.0f;
30
+
31
+ [SerializeField][Min(0.0f)] private float hemisphereRadius = 1.0f;
32
+
33
+ [SerializeField][Min(1)] private int divisions = 8;
34
+
35
+
36
+
37
+ private void OnWizardCreate()
38
+
39
+ {
40
+
41
+ var bottomLeft = new Vector3(-this.planeWidth * 0.5f, -this.planeHeight * 0.5f, 0.0f);
42
+
43
+ var texelWidth = 0.5f / this.divisions;
44
+
45
+ var texelHeight = 0.5f / this.divisions;
46
+
47
+ var deltaX = this.planeWidth * texelWidth;
48
+
49
+ var deltaY = this.planeHeight * texelHeight;
50
+
51
+ var vertexCountX = (this.divisions * 2) + 1;
52
+
53
+ var vertexCountY = (this.divisions * 2) + 1;
54
+
55
+ var planeVertices = Enumerable.Range(0, vertexCountY).SelectMany(
56
+
57
+ j => Enumerable.Range(0, vertexCountX).Select(
58
+
59
+ i => bottomLeft + new Vector3(i * deltaX, j * deltaY, 0.0f))).ToArray();
60
+
61
+ var planeNormals = planeVertices.Select(_ => Vector3.back).ToArray();
62
+
63
+ var planeTangents = planeVertices.Select(_ => new Vector4(1.0f, 0.0f, 0.0f, -1.0f)).ToArray();
64
+
65
+ var planeUvs = Enumerable.Range(0, vertexCountY).SelectMany(
66
+
67
+ j => Enumerable.Range(0, vertexCountX).Select(
68
+
69
+ i => new Vector2(i * texelWidth, j * texelHeight))).ToArray();
70
+
71
+ var quadTriangles = new[]
72
+
73
+ {
74
+
75
+ 0, vertexCountX, 1, vertexCountX + 1, 1, vertexCountX
76
+
77
+ };
78
+
79
+ var planeTriangles = Enumerable.Range(0, vertexCountY - 1).SelectMany(
80
+
81
+ j => Enumerable.Range(0, vertexCountX - 1).SelectMany(
82
+
83
+ i => quadTriangles.Select(k => i + (j * vertexCountX) + k))).ToArray();
84
+
85
+ var hemisphereNormals = planeUvs.Select(
86
+
87
+ uv =>
88
+
89
+ {
90
+
91
+ var angleH = (uv.x + 0.5f) * Mathf.PI;
92
+
93
+ var angleV = (uv.y - 0.5f) * Mathf.PI;
94
+
95
+ var sinH = Mathf.Sin(angleH);
96
+
97
+ var cosH = Mathf.Cos(angleH);
98
+
99
+ var sinV = Mathf.Sin(angleV);
100
+
101
+ var cosV = Mathf.Cos(angleV);
102
+
103
+ return new Vector3(-sinH * cosV, sinV, cosH * cosV);
104
+
105
+ }).ToArray();
106
+
107
+ var hemisphereTangents = planeUvs.Select(
108
+
109
+ uv =>
110
+
111
+ {
112
+
113
+ var angleH = (uv.x + 0.5f) * Mathf.PI;
114
+
115
+ var sinH = Mathf.Sin(angleH);
116
+
117
+ var cosH = Mathf.Cos(angleH);
118
+
119
+ return new Vector4(-cosH, 0.0f, -sinH, -1.0f);
120
+
121
+ }).ToArray();
122
+
123
+ var hemisphereVertices = hemisphereNormals.Select(normal => normal * this.hemisphereRadius).ToArray();
124
+
125
+ var mesh = new Mesh
126
+
127
+ {
128
+
129
+ name = "PlaneToHemisphere",
130
+
131
+ vertices = planeVertices,
132
+
133
+ normals = planeNormals,
134
+
135
+ tangents = planeTangents,
136
+
137
+ uv = planeUvs,
138
+
139
+ triangles = planeTriangles
140
+
141
+ };
142
+
143
+ mesh.AddBlendShapeFrame(
144
+
145
+ "Deformation",
146
+
147
+ 100.0f,
148
+
149
+ planeVertices.Zip(
150
+
151
+ hemisphereVertices,
152
+
153
+ (planeVertex, hemisphereVertex) => hemisphereVertex - planeVertex).ToArray(),
154
+
155
+ planeNormals.Zip(
156
+
157
+ hemisphereNormals,
158
+
159
+ (planeNormal, hemisphereNormal) => hemisphereNormal - planeNormal).ToArray(),
160
+
161
+ planeTangents.Zip(
162
+
163
+ hemisphereTangents,
164
+
165
+ (planeTangent, hemisphereTangent) => (Vector3)hemisphereTangent - (Vector3)planeTangent).ToArray());
166
+
167
+ mesh.RecalculateNormals();
168
+
169
+ mesh.RecalculateTangents();
170
+
171
+ var cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
172
+
173
+ var newObject = new GameObject(mesh.name);
174
+
175
+ var skinnedMeshRenderer = newObject.AddComponent<SkinnedMeshRenderer>();
176
+
177
+ skinnedMeshRenderer.sharedMesh = mesh;
178
+
179
+ skinnedMeshRenderer.sharedMaterial = cube.GetComponent<Renderer>().sharedMaterial;
180
+
181
+ DestroyImmediate(cube);
182
+
183
+ ProjectWindowUtil.CreateAsset(mesh, $"{mesh.name}.asset");
184
+
185
+ }
186
+
187
+
188
+
189
+ [MenuItem("Assets/Create/Plane to Hemisphere")]
190
+
191
+ private static void OpenWizard()
192
+
193
+ {
194
+
195
+ DisplayWizard<PlaneToHemisphereWizard>("Plane to Hemisphere");
196
+
197
+ }
198
198
 
199
199
  }
200
200
 
@@ -226,159 +226,159 @@
226
226
 
227
227
  {
228
228
 
229
- Properties
230
-
231
- {
232
-
233
- _Color ("Color", Color) = (1, 1, 1, 1)
234
-
235
- _MainTex ("Albedo (RGB)", 2D) = "white" {}
236
-
237
- _Glossiness ("Smoothness", Range(0, 1)) = 0.5
238
-
239
- _Metallic ("Metallic", Range(0, 1)) = 0.0
240
-
241
- _SphereRadius ("Sphere Radius", Range(0, 10)) = 1.0
242
-
243
- _Deformation ("Deformation", Range(0, 1)) = 0.0
244
-
245
- }
246
-
247
- SubShader
248
-
249
- {
250
-
251
- Tags { "RenderType"="Opaque" }
252
-
253
-
254
-
255
- Cull Off
256
-
257
-
258
-
259
- CGPROGRAM
260
-
261
- #pragma surface surf Standard fullforwardshadows vertex:vert
262
-
263
- #pragma target 3.0
264
-
265
-
266
-
267
- sampler2D _MainTex;
268
-
269
- half _Glossiness;
270
-
271
- half _Metallic;
272
-
273
- fixed4 _Color;
274
-
275
- float _SphereRadius;
276
-
277
- float _Deformation;
278
-
279
-
280
-
281
- struct Input
282
-
283
- {
284
-
285
- float2 uv_MainTex;
286
-
287
- };
288
-
289
-
290
-
291
- #define EPSILON 0.000001
292
-
293
-
294
-
295
- void vert(inout appdata_full v)
296
-
297
- {
298
-
299
- if (_Deformation < EPSILON)
300
-
301
- {
302
-
303
- return;
304
-
305
- }
306
-
307
-
308
-
309
- // 法線、接線はブレンドシェイプ版と同じ線形モーフィングでも
310
-
311
- // 粗が目立たなかったためブレンドシェイプ版と同様に補間した
312
-
313
- float sinH;
314
-
315
- float cosH;
316
-
317
- float sinV;
318
-
319
- float cosV;
320
-
321
- sincos(v.texcoord.x * 2.0 * UNITY_PI, sinH, cosH);
322
-
323
- sincos((v.texcoord.y - 0.5) * UNITY_PI, sinV, cosV);
324
-
325
- float3 sphereNormal = float3(-sinH * cosV, sinV, cosH * cosV);
326
-
327
- float3 sphereTangent = float3(cosH, 0.0, sinH) * v.tangent.w;
328
-
329
- v.normal = lerp(v.normal, sphereNormal, _Deformation);
330
-
331
- v.tangent.xyz = lerp(v.tangent.xyz, sphereTangent, _Deformation);
332
-
333
-
334
-
335
- // 頂点座標の水平成分を円弧に沿った補間とすることで見苦しさを軽減する
336
-
337
- // 垂直成分は線形補間でもさほど違和感はなさそうだった
338
-
339
- float sinTheta;
340
-
341
- float cosTheta;
342
-
343
- float geographicCoord = (2.0 * v.texcoord.x - 1.0) * UNITY_PI;
344
-
345
- sincos(_Deformation * geographicCoord, sinTheta, cosTheta);
346
-
347
- float3 arcPosition = float3(sinTheta, 0.0, 1.0 - cosTheta) * _SphereRadius / _Deformation;
348
-
349
- arcPosition.yz += float2(lerp(v.vertex.y, sphereNormal.y * _SphereRadius, _Deformation), lerp(0.0, -_SphereRadius, _Deformation));
350
-
351
- arcPosition.x *= lerp(max(abs(v.vertex.x), EPSILON) / max(abs(_SphereRadius * geographicCoord), EPSILON), 1.0, _Deformation);
352
-
353
- arcPosition.xz *= lerp(1.0, cosV, _Deformation);
354
-
355
- v.vertex.xyz = arcPosition;
356
-
357
- }
358
-
359
-
360
-
361
- void surf(Input IN, inout SurfaceOutputStandard o)
362
-
363
- {
364
-
365
- fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
366
-
367
- o.Albedo = c.rgb;
368
-
369
- o.Metallic = _Metallic;
370
-
371
- o.Smoothness = _Glossiness;
372
-
373
- o.Alpha = c.a;
374
-
375
- }
376
-
377
- ENDCG
378
-
379
- }
380
-
381
- FallBack "Diffuse"
229
+ Properties
230
+
231
+ {
232
+
233
+ _Color ("Color", Color) = (1, 1, 1, 1)
234
+
235
+ _MainTex ("Albedo (RGB)", 2D) = "white" {}
236
+
237
+ _Glossiness ("Smoothness", Range(0, 1)) = 0.5
238
+
239
+ _Metallic ("Metallic", Range(0, 1)) = 0.0
240
+
241
+ _SphereRadius ("Sphere Radius", Range(0, 10)) = 1.0
242
+
243
+ _Deformation ("Deformation", Range(0, 1)) = 0.0
244
+
245
+ }
246
+
247
+ SubShader
248
+
249
+ {
250
+
251
+ Tags { "RenderType"="Opaque" }
252
+
253
+
254
+
255
+ Cull Off
256
+
257
+
258
+
259
+ CGPROGRAM
260
+
261
+ #pragma surface surf Standard fullforwardshadows vertex:vert
262
+
263
+ #pragma target 3.0
264
+
265
+
266
+
267
+ sampler2D _MainTex;
268
+
269
+ half _Glossiness;
270
+
271
+ half _Metallic;
272
+
273
+ fixed4 _Color;
274
+
275
+ float _SphereRadius;
276
+
277
+ float _Deformation;
278
+
279
+
280
+
281
+ struct Input
282
+
283
+ {
284
+
285
+ float2 uv_MainTex;
286
+
287
+ };
288
+
289
+
290
+
291
+ #define EPSILON 0.000001
292
+
293
+
294
+
295
+ void vert(inout appdata_full v)
296
+
297
+ {
298
+
299
+ if (_Deformation < EPSILON)
300
+
301
+ {
302
+
303
+ return;
304
+
305
+ }
306
+
307
+
308
+
309
+ // 法線、接線はブレンドシェイプ版と同じ線形モーフィングでも
310
+
311
+ // 粗が目立たなかったためブレンドシェイプ版と同様に補間した
312
+
313
+ float sinH;
314
+
315
+ float cosH;
316
+
317
+ float sinV;
318
+
319
+ float cosV;
320
+
321
+ sincos(v.texcoord.x * 2.0 * UNITY_PI, sinH, cosH);
322
+
323
+ sincos((v.texcoord.y - 0.5) * UNITY_PI, sinV, cosV);
324
+
325
+ float3 sphereNormal = float3(-sinH * cosV, sinV, cosH * cosV);
326
+
327
+ float3 sphereTangent = float3(cosH, 0.0, sinH) * v.tangent.w;
328
+
329
+ v.normal = lerp(v.normal, sphereNormal, _Deformation);
330
+
331
+ v.tangent.xyz = lerp(v.tangent.xyz, sphereTangent, _Deformation);
332
+
333
+
334
+
335
+ // 頂点座標の水平成分を円弧に沿った補間とすることで見苦しさを軽減する
336
+
337
+ // 垂直成分は線形補間でもさほど違和感はなさそうだった
338
+
339
+ float sinTheta;
340
+
341
+ float cosTheta;
342
+
343
+ float geographicCoord = (2.0 * v.texcoord.x - 1.0) * UNITY_PI;
344
+
345
+ sincos(_Deformation * geographicCoord, sinTheta, cosTheta);
346
+
347
+ float3 arcPosition = float3(sinTheta, 0.0, 1.0 - cosTheta) * _SphereRadius / _Deformation;
348
+
349
+ arcPosition.yz += float2(lerp(v.vertex.y, sphereNormal.y * _SphereRadius, _Deformation), lerp(0.0, -_SphereRadius, _Deformation));
350
+
351
+ arcPosition.x *= lerp(max(abs(v.vertex.x), EPSILON) / max(abs(_SphereRadius * geographicCoord), EPSILON), 1.0, _Deformation);
352
+
353
+ arcPosition.xz *= lerp(1.0, cosV, _Deformation);
354
+
355
+ v.vertex.xyz = arcPosition;
356
+
357
+ }
358
+
359
+
360
+
361
+ void surf(Input IN, inout SurfaceOutputStandard o)
362
+
363
+ {
364
+
365
+ fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
366
+
367
+ o.Albedo = c.rgb;
368
+
369
+ o.Metallic = _Metallic;
370
+
371
+ o.Smoothness = _Glossiness;
372
+
373
+ o.Alpha = c.a;
374
+
375
+ }
376
+
377
+ ENDCG
378
+
379
+ }
380
+
381
+ FallBack "Diffuse"
382
382
 
383
383
  }
384
384
 
@@ -391,3 +391,185 @@
391
391
 
392
392
 
393
393
  ![図2](8dcb1af3be096053addce20e4e12a6db.gif)
394
+
395
+
396
+
397
+ ##Unlit版
398
+
399
+
400
+
401
+ ```ShaderLab
402
+
403
+ Shader "Unlit/PlaneToSphere"
404
+
405
+ {
406
+
407
+ Properties
408
+
409
+ {
410
+
411
+ _MainTex ("Texture", 2D) = "white" {}
412
+
413
+ _SphereRadius ("Sphere Radius", Range(0, 10)) = 1.0
414
+
415
+ _Deformation ("Deformation", Range(0, 1)) = 0.0
416
+
417
+ }
418
+
419
+
420
+
421
+ SubShader
422
+
423
+ {
424
+
425
+ Tags { "RenderType"="Opaque" }
426
+
427
+
428
+
429
+ Cull Off
430
+
431
+
432
+
433
+ Pass
434
+
435
+ {
436
+
437
+ CGPROGRAM
438
+
439
+ #pragma vertex vert
440
+
441
+ #pragma fragment frag
442
+
443
+ #pragma multi_compile_fog
444
+
445
+
446
+
447
+ #include "UnityCG.cginc"
448
+
449
+
450
+
451
+ struct appdata
452
+
453
+ {
454
+
455
+ float4 vertex : POSITION;
456
+
457
+ float2 uv : TEXCOORD0;
458
+
459
+ };
460
+
461
+
462
+
463
+ struct v2f
464
+
465
+ {
466
+
467
+ float2 uv : TEXCOORD0;
468
+
469
+ UNITY_FOG_COORDS(1)
470
+
471
+ float4 vertex : SV_POSITION;
472
+
473
+ };
474
+
475
+
476
+
477
+ sampler2D _MainTex;
478
+
479
+ float4 _MainTex_ST;
480
+
481
+ float _SphereRadius;
482
+
483
+ float _Deformation;
484
+
485
+
486
+
487
+ #define EPSILON 0.000001
488
+
489
+
490
+
491
+ void deform(inout appdata v)
492
+
493
+ {
494
+
495
+ if (_Deformation < EPSILON)
496
+
497
+ {
498
+
499
+ return;
500
+
501
+ }
502
+
503
+
504
+
505
+ // Unlitなら法線、接線は不要なはずなので簡略化した
506
+
507
+ float sinV;
508
+
509
+ float cosV;
510
+
511
+ sincos((v.uv.y - 0.5) * UNITY_PI, sinV, cosV);
512
+
513
+ float sinTheta;
514
+
515
+ float cosTheta;
516
+
517
+ float geographicCoord = (2.0 * v.uv.x - 1.0) * UNITY_PI;
518
+
519
+ sincos(_Deformation * geographicCoord, sinTheta, cosTheta);
520
+
521
+ float3 arcPosition = float3(sinTheta, 0.0, 1.0 - cosTheta) * _SphereRadius / _Deformation;
522
+
523
+ arcPosition.yz += float2(lerp(v.vertex.y, sinV * _SphereRadius, _Deformation), lerp(0.0, -_SphereRadius, _Deformation));
524
+
525
+ arcPosition.x *= lerp(max(abs(v.vertex.x), EPSILON) / max(abs(_SphereRadius * geographicCoord), EPSILON), 1.0, _Deformation);
526
+
527
+ arcPosition.xz *= lerp(1.0, cosV, _Deformation);
528
+
529
+ v.vertex.xyz = arcPosition;
530
+
531
+ }
532
+
533
+
534
+
535
+ v2f vert(appdata v)
536
+
537
+ {
538
+
539
+ v2f o;
540
+
541
+ deform(v);
542
+
543
+ o.vertex = UnityObjectToClipPos(v.vertex);
544
+
545
+ o.uv = TRANSFORM_TEX(v.uv, _MainTex);
546
+
547
+ UNITY_TRANSFER_FOG(o,o.vertex);
548
+
549
+ return o;
550
+
551
+ }
552
+
553
+
554
+
555
+ fixed4 frag(v2f i) : SV_Target
556
+
557
+ {
558
+
559
+ fixed4 col = tex2D(_MainTex, i.uv);
560
+
561
+ UNITY_APPLY_FOG(i.fogCoord, col);
562
+
563
+ return col;
564
+
565
+ }
566
+
567
+ ENDCG
568
+
569
+ }
570
+
571
+ }
572
+
573
+ }
574
+
575
+ ```

2

シェーダー上で変形する案を追記

2021/01/20 20:47

投稿

Bongo
Bongo

スコア10807

test CHANGED
@@ -208,4 +208,186 @@
208
208
 
209
209
 
210
210
 
211
- ![図](7475e7e017b757ce310931dcb227e964.gif)
211
+ ![図1](7475e7e017b757ce310931dcb227e964.gif)
212
+
213
+
214
+
215
+ ##シェーダー上で変形する案
216
+
217
+
218
+
219
+ 下記のようなマテリアルを使用したところ...
220
+
221
+
222
+
223
+ ```ShaderLab
224
+
225
+ Shader "Custom/PlaneToSphere"
226
+
227
+ {
228
+
229
+ Properties
230
+
231
+ {
232
+
233
+ _Color ("Color", Color) = (1, 1, 1, 1)
234
+
235
+ _MainTex ("Albedo (RGB)", 2D) = "white" {}
236
+
237
+ _Glossiness ("Smoothness", Range(0, 1)) = 0.5
238
+
239
+ _Metallic ("Metallic", Range(0, 1)) = 0.0
240
+
241
+ _SphereRadius ("Sphere Radius", Range(0, 10)) = 1.0
242
+
243
+ _Deformation ("Deformation", Range(0, 1)) = 0.0
244
+
245
+ }
246
+
247
+ SubShader
248
+
249
+ {
250
+
251
+ Tags { "RenderType"="Opaque" }
252
+
253
+
254
+
255
+ Cull Off
256
+
257
+
258
+
259
+ CGPROGRAM
260
+
261
+ #pragma surface surf Standard fullforwardshadows vertex:vert
262
+
263
+ #pragma target 3.0
264
+
265
+
266
+
267
+ sampler2D _MainTex;
268
+
269
+ half _Glossiness;
270
+
271
+ half _Metallic;
272
+
273
+ fixed4 _Color;
274
+
275
+ float _SphereRadius;
276
+
277
+ float _Deformation;
278
+
279
+
280
+
281
+ struct Input
282
+
283
+ {
284
+
285
+ float2 uv_MainTex;
286
+
287
+ };
288
+
289
+
290
+
291
+ #define EPSILON 0.000001
292
+
293
+
294
+
295
+ void vert(inout appdata_full v)
296
+
297
+ {
298
+
299
+ if (_Deformation < EPSILON)
300
+
301
+ {
302
+
303
+ return;
304
+
305
+ }
306
+
307
+
308
+
309
+ // 法線、接線はブレンドシェイプ版と同じ線形モーフィングでも
310
+
311
+ // 粗が目立たなかったためブレンドシェイプ版と同様に補間した
312
+
313
+ float sinH;
314
+
315
+ float cosH;
316
+
317
+ float sinV;
318
+
319
+ float cosV;
320
+
321
+ sincos(v.texcoord.x * 2.0 * UNITY_PI, sinH, cosH);
322
+
323
+ sincos((v.texcoord.y - 0.5) * UNITY_PI, sinV, cosV);
324
+
325
+ float3 sphereNormal = float3(-sinH * cosV, sinV, cosH * cosV);
326
+
327
+ float3 sphereTangent = float3(cosH, 0.0, sinH) * v.tangent.w;
328
+
329
+ v.normal = lerp(v.normal, sphereNormal, _Deformation);
330
+
331
+ v.tangent.xyz = lerp(v.tangent.xyz, sphereTangent, _Deformation);
332
+
333
+
334
+
335
+ // 頂点座標の水平成分を円弧に沿った補間とすることで見苦しさを軽減する
336
+
337
+ // 垂直成分は線形補間でもさほど違和感はなさそうだった
338
+
339
+ float sinTheta;
340
+
341
+ float cosTheta;
342
+
343
+ float geographicCoord = (2.0 * v.texcoord.x - 1.0) * UNITY_PI;
344
+
345
+ sincos(_Deformation * geographicCoord, sinTheta, cosTheta);
346
+
347
+ float3 arcPosition = float3(sinTheta, 0.0, 1.0 - cosTheta) * _SphereRadius / _Deformation;
348
+
349
+ arcPosition.yz += float2(lerp(v.vertex.y, sphereNormal.y * _SphereRadius, _Deformation), lerp(0.0, -_SphereRadius, _Deformation));
350
+
351
+ arcPosition.x *= lerp(max(abs(v.vertex.x), EPSILON) / max(abs(_SphereRadius * geographicCoord), EPSILON), 1.0, _Deformation);
352
+
353
+ arcPosition.xz *= lerp(1.0, cosV, _Deformation);
354
+
355
+ v.vertex.xyz = arcPosition;
356
+
357
+ }
358
+
359
+
360
+
361
+ void surf(Input IN, inout SurfaceOutputStandard o)
362
+
363
+ {
364
+
365
+ fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
366
+
367
+ o.Albedo = c.rgb;
368
+
369
+ o.Metallic = _Metallic;
370
+
371
+ o.Smoothness = _Glossiness;
372
+
373
+ o.Alpha = c.a;
374
+
375
+ }
376
+
377
+ ENDCG
378
+
379
+ }
380
+
381
+ FallBack "Diffuse"
382
+
383
+ }
384
+
385
+ ```
386
+
387
+
388
+
389
+ 下図のような変形の仕方になりました。マテリアルの`_Deformation`をスクリプトから操作すれば平面から球体へ変形できるかと思います。
390
+
391
+
392
+
393
+ ![図2](8dcb1af3be096053addce20e4e12a6db.gif)

1

変数名を修正

2021/01/20 14:03

投稿

Bongo
Bongo

スコア10807

test CHANGED
@@ -150,19 +150,19 @@
150
150
 
151
151
  hemisphereVertices,
152
152
 
153
- (planeVertex, sphereVertex) => sphereVertex - planeVertex).ToArray(),
153
+ (planeVertex, hemisphereVertex) => hemisphereVertex - planeVertex).ToArray(),
154
154
 
155
155
  planeNormals.Zip(
156
156
 
157
157
  hemisphereNormals,
158
158
 
159
- (planeNormal, sphereNormal) => sphereNormal - planeNormal).ToArray(),
159
+ (planeNormal, hemisphereNormal) => hemisphereNormal - planeNormal).ToArray(),
160
160
 
161
161
  planeTangents.Zip(
162
162
 
163
163
  hemisphereTangents,
164
164
 
165
- (planeTangent, sphereTangent) => (Vector3)sphereTangent - (Vector3)planeTangent).ToArray());
165
+ (planeTangent, hemisphereTangent) => (Vector3)hemisphereTangent - (Vector3)planeTangent).ToArray());
166
166
 
167
167
  mesh.RecalculateNormals();
168
168