回答編集履歴
1
ジオメトリーシェーダーを使わない案を追記
test
CHANGED
@@ -100,3 +100,136 @@
|
|
100
100
|

|
101
101
|
|
102
102
|
ただしこの方法ですと、「[ジオメトリシェーダ・コンピュートシェーダのモバイル対応状況【Unity】|アマガミナブログ](https://amagamina.jp/blog/geometry-compute-mobile/)」で挙げられているような一部環境(たとえばグラフィックスシステムにMetalが使われているような)では動かないかと思います。その場合は別の手を考えてみようと思いますが、おそらくメッシュの作り方にも手を加える必要があるように予想されますので、メッシュを作る部分のスクリプトもご提示いただけると参考になりそうです。
|
103
|
+
|
104
|
+
## 追記
|
105
|
+
|
106
|
+
まず、メッシュ生成部分を下記のようにしてみました。
|
107
|
+
|
108
|
+
```C#
|
109
|
+
// CreateLineMeshの引数のthicknessは廃止し、マテリアル側で設定することにする
|
110
|
+
public static Mesh CreateLineMesh(Vector3 center, float length)
|
111
|
+
{
|
112
|
+
var mesh = new Mesh();
|
113
|
+
var triangles = new int[6];
|
114
|
+
triangles[0] = 0;
|
115
|
+
triangles[1] = 1;
|
116
|
+
triangles[2] = 2;
|
117
|
+
triangles[3] = 2;
|
118
|
+
triangles[4] = 3;
|
119
|
+
triangles[5] = 0;
|
120
|
+
var vertices = new Vector3[4];
|
121
|
+
|
122
|
+
// bottomとtopはcenter.yとし、現時点では太さのない潰れた長方形の状態にしておく
|
123
|
+
var left = center.x - length / 2.0f;
|
124
|
+
var right = center.x + length / 2.0f;
|
125
|
+
var bottom = center.y;
|
126
|
+
var top = center.y;
|
127
|
+
|
128
|
+
vertices[0] = new Vector3(left, bottom, center.z);
|
129
|
+
vertices[1] = new Vector3(left, top, center.z);
|
130
|
+
vertices[2] = new Vector3(right, top, center.z);
|
131
|
+
vertices[3] = new Vector3(right, bottom, center.z);
|
132
|
+
|
133
|
+
var nornals = vertices.ToArray();
|
134
|
+
|
135
|
+
// 各頂点に追加情報を埋め込む
|
136
|
+
// まずXYZには線分の逆末端の座標をいれておく
|
137
|
+
// (left側頂点にはright側の、right側頂点にはleft側の座標)
|
138
|
+
var otherVertices = new Vector4[vertices.Length];
|
139
|
+
for (var i = 0; i < otherVertices.Length; i++)
|
140
|
+
{
|
141
|
+
otherVertices[i] = vertices[vertices.Length - i - 1];
|
142
|
+
}
|
143
|
+
|
144
|
+
// そしてWには0~3の数値を入れておく
|
145
|
+
// これは各頂点が4隅のうちどれであるかを特定する目的のもので、さしあたり
|
146
|
+
// 1ビット目がbottomかtopかを、2ビット目がleftかrightかを示すことにした
|
147
|
+
otherVertices[0].w = 0;
|
148
|
+
otherVertices[1].w = 1;
|
149
|
+
otherVertices[2].w = 3;
|
150
|
+
otherVertices[3].w = 2;
|
151
|
+
|
152
|
+
mesh.SetVertices(vertices);
|
153
|
+
mesh.SetTriangles(triangles, 0);
|
154
|
+
mesh.SetNormals(nornals);
|
155
|
+
|
156
|
+
// 追加情報の埋め込み先はUVを使わせてもらうことにした
|
157
|
+
mesh.SetUVs(0, otherVertices);
|
158
|
+
|
159
|
+
mesh.RecalculateBounds();
|
160
|
+
|
161
|
+
return mesh;
|
162
|
+
}
|
163
|
+
```
|
164
|
+
|
165
|
+
そしてマテリアルは下記のようにしました。
|
166
|
+
|
167
|
+
```ShaderLab
|
168
|
+
Shader "Unlit/Line"
|
169
|
+
{
|
170
|
+
Properties
|
171
|
+
{
|
172
|
+
_Color ("Color", Color) = (1.0, 1.0, 1.0, 1.0)
|
173
|
+
_Thickness ("Thickness", Range(0.0, 128.0)) = 4.0
|
174
|
+
}
|
175
|
+
SubShader
|
176
|
+
{
|
177
|
+
Tags { "RenderType" = "Opaque" }
|
178
|
+
|
179
|
+
Pass
|
180
|
+
{
|
181
|
+
CGPROGRAM
|
182
|
+
#pragma vertex vert
|
183
|
+
#pragma fragment frag
|
184
|
+
#include "UnityCG.cginc"
|
185
|
+
|
186
|
+
struct appdata
|
187
|
+
{
|
188
|
+
float4 vertex : POSITION;
|
189
|
+
float4 otherVertex : TEXCOORD0;
|
190
|
+
};
|
191
|
+
|
192
|
+
float _Thickness;
|
193
|
+
|
194
|
+
float4 vert(appdata v) : SV_POSITION
|
195
|
+
{
|
196
|
+
float4 p0 = UnityObjectToClipPos(v.vertex);
|
197
|
+
float4 p1 = UnityObjectToClipPos(float4(v.otherVertex.xyz, 1.0));
|
198
|
+
|
199
|
+
// 線分の両端の座標をスクリーン座標に変換する
|
200
|
+
float2 sp0 = (p0.xy * _ScreenParams.xy) * (0.5 / p0.w);
|
201
|
+
float2 sp1 = (p1.xy * _ScreenParams.xy) * (0.5 / p1.w);
|
202
|
+
|
203
|
+
// 線分に平行なベクトルを求めておく
|
204
|
+
// このとき、頂点がleftかrightかによって向きを調整する
|
205
|
+
float2 tangent = (sp0 - sp1) * (((int)v.otherVertex.w & 2) - 1);
|
206
|
+
float sqrLength = dot(tangent, tangent);
|
207
|
+
if (sqrLength > 0.0)
|
208
|
+
{
|
209
|
+
// tangentを90°回転してnormalとする
|
210
|
+
float2 normal = tangent.yx * float2(-1.0, 1.0);
|
211
|
+
|
212
|
+
// normalの長さを線幅の半分にして...
|
213
|
+
normal *= (_Thickness * 0.5) / sqrt(sqrLength);
|
214
|
+
|
215
|
+
// 頂点をnormalの方向にずらす
|
216
|
+
// このとき、頂点がbottomかtopかによって向きを調整する
|
217
|
+
p0.xy = (sp0 - normal * (((int)v.otherVertex.w & 1) * 2 - 1)) * p0.w * (_ScreenParams.zw - 1.0) * 2.0;
|
218
|
+
}
|
219
|
+
|
220
|
+
return p0;
|
221
|
+
}
|
222
|
+
|
223
|
+
fixed4 _Color;
|
224
|
+
|
225
|
+
fixed4 frag() : SV_Target
|
226
|
+
{
|
227
|
+
return _Color;
|
228
|
+
}
|
229
|
+
ENDCG
|
230
|
+
}
|
231
|
+
}
|
232
|
+
}
|
233
|
+
```
|
234
|
+
|
235
|
+

|