「接線ベクトル」の版間の差分
ナビゲーションに移動
検索に移動
Administrator (トーク | 投稿記録) |
Administrator (トーク | 投稿記録) |
||
(同じ利用者による、間の3版が非表示) | |||
5行目: | 5行目: | ||
* そしてZ軸は「Normalベクトル([[法線ベクトル]])」と呼ばれます。 | * そしてZ軸は「Normalベクトル([[法線ベクトル]])」と呼ばれます。 | ||
+ | == 計算式 == | ||
TangentベクトルとBinormalベクトルの計算については、あらかじめUV座標と法線ベクトルはわかっている(頂点データとして保持している)前提となっているのが一般的です。 | TangentベクトルとBinormalベクトルの計算については、あらかじめUV座標と法線ベクトルはわかっている(頂点データとして保持している)前提となっているのが一般的です。 | ||
− | == | + | === Tangentベクトルの計算:Normalベクトルを使う方法 === |
大雑把に1行で書くと以下のようになります。NormalベクトルとUpベクトルのクロス積を取ればTangentベクトルになります。 | 大雑把に1行で書くと以下のようになります。NormalベクトルとUpベクトルのクロス積を取ればTangentベクトルになります。 | ||
Vector3 tangent = Vector3.Cross(normal, Vector3.UnitY); | Vector3 tangent = Vector3.Cross(normal, Vector3.UnitY); | ||
23行目: | 24行目: | ||
Tangentベクトルの計算については、わりと重めの処理であり、かつ頻繁に変化する値でもないので、あらかじめCPU上で計算しておき、頂点データのひとつとして保持する方法が主流です。 | Tangentベクトルの計算については、わりと重めの処理であり、かつ頻繁に変化する値でもないので、あらかじめCPU上で計算しておき、頂点データのひとつとして保持する方法が主流です。 | ||
− | == Binormalの計算式 == | + | === 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つのクロス積を取るだけです。 | NormalベクトルとTangentベクトルの2つがわかっているならば、その2つのクロス積を取るだけです。 | ||
Vector3 binormal = Vector3.Normalize(Vector3.Cross(normal, tangent)); | Vector3 binormal = Vector3.Normalize(Vector3.Cross(normal, tangent)); | ||
Binormalベクトルの計算については、わりと軽めの処理なので、頂点データを節約すべく、GPU上でリアルタイムに計算する方法が主流です。 | Binormalベクトルの計算については、わりと軽めの処理なので、頂点データを節約すべく、GPU上でリアルタイムに計算する方法が主流です。 | ||
+ | |||
+ | ただGPUが貧弱なモバイル環境などではTangentベクトルと同様に事前にCPU上で計算しておいても良いと思います。モバイル向けの[[ローポリゴン]]で頂点データのサイズが問題になることはまずないと思います。 |
2023年7月10日 (月) 02:39時点における最新版
接線ベクトルとは、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上で計算しておいても良いと思います。モバイル向けのローポリゴンで頂点データのサイズが問題になることはまずないと思います。