接線ベクトル

提供: MonoBook
ナビゲーションに移動 検索に移動

接線ベクトルとは、2DのUV座標を3Dのローカル座標に変換したものです。

  • U軸を3D変換したものは「Tangentベクトル」
  • V軸は3D変換したものは「Binormalベクトル」
  • そしてZ軸は「Normalベクトル(法線ベクトル)」と呼ばれます。

計算式[編集 | ソースを編集]

TangentベクトルとBinormalベクトルの計算については、あらかじめUV座標と法線ベクトルはわかっている(頂点データとして保持している)前提となっているのが一般的です。

Tangentベクトルの計算:Normalベクトルを使う方法[編集 | ソースを編集]

大雑把に1行で書くと以下のようになります。NormalベクトルとUpベクトルのクロス積を取ればTangentベクトルになります。

Vector3 tangent = Vector3.Cross(normal, Vector3.UnitY);

しかし、上記の計算式にはNormalベクトルとUpベクトルが完全一致する場合にゼロを返すという欠点があります。 この問題の回避策として2種類のUpベクトルで計算して都合の良さそうな方を採用するという方法があります。

Vector3 tangent;
Vector3 c1 = Vector3.Cross(normal, Vector3.UnitY);
Vector3 c2 = Vector3.Cross(normal, Vector3.UnitZ);
if (Vector3.Length(c2) < Vector3.Length(c1))
   tangent = Vector3.Normalize(c1);
else
   tangent = Vector3.Normalize(c2);

Tangentベクトルの計算については、わりと重めの処理であり、かつ頻繁に変化する値でもないので、あらかじめCPU上で計算しておき、頂点データのひとつとして保持する方法が主流です。

Tangentベクトルの計算:頂点座標とUV座標を使う方法[編集 | ソースを編集]

// 頂点エッジ
Vector3 edge1 = v1 - v0;
Vector3 edge2 = v2 - v1;
// UVエッジ
Vector2 delta1 = u1 - u0;
Vector2 delta2 = u2 - u0;
// 接線ベクトル
Vector3 tangent = normalize( (delta2.Y * edge1 - delta1.Y * edge2) / (delta1.X * delta2.Y - delta2.X * delta1.Y) );

Binormalの計算式[編集 | ソースを編集]

NormalベクトルとTangentベクトルの2つがわかっているならば、その2つのクロス積を取るだけです。

Vector3 binormal = Vector3.Normalize(Vector3.Cross(normal, tangent));

Binormalベクトルの計算については、わりと軽めの処理なので、頂点データを節約すべく、GPU上でリアルタイムに計算する方法が主流です。

ただGPUが貧弱なモバイル環境などではTangentベクトルと同様に事前にCPU上で計算しておいても良いと思います。モバイル向けのローポリゴンで頂点データのサイズが問題になることはまずないと思います。