頂点位置から法線を計算することは、ベクトル外積を使用すると非常に簡単です。
外積 2つのベクトルのは、および(注意、または時々のベクトルに垂直である)及び長さの、、はと間の角度。ベクトルの方向は乗算の次数に依存しますは反対です(平面に垂直な2つの方向)。あなたvu×vu∧vuv||u×v||=||u||⋅||v||sin(θ)θuvu×vv×u
クロス積に慣れていない場合は、それについて読んで、慣れることをお勧めします。すると法線は単純に見えます。
フラットシェーディング法線
三角形がある場合、は三角形に垂直なベクトルで、その面積に比例する長さです。法線は三角形の平面に垂直な単位ベクトルなので、次のようにして法線を取得できます。ABCAB×AC
N=AB×AC||AB×AC||
コードでは、これはn = normalize(cross(b-a, c-a))
たとえば次のようになります。これをすべての顔に適用すると、顔ごとに法線ができます。
For each triangle ABC
n := normalize(cross(B-A, C-A))
A.n := n
B.n := n
C.n := n
これは、頂点が三角形間で共有されていないことを前提としています。Kinect APIに詳しくありません。それらが共有されている可能性は十分にあります。その場合、それらを複製するか、次のソリューションに進む必要があります。
スムーズシェーディング法線
上記のように計算された法線でライティングした後、三角形のエッジがはっきりと見えることに気づくでしょう。これが望ましくない場合は、同じ頂点を共有するすべての面を考慮することにより、代わりにスムーズな法線を計算できます。
たとえば、同じ頂点が3つの三角形、、で共有されている場合、法線は、、平均になります。場合また、大きな三角形で、小さなものです、あなたはおそらくしたいより多くの影響を受けなければよりも、。T 2 T 3 N N 1 N 2 N 3 T 1 T 2 N N 1 N 2T1T2T3NN1N2N3T1T2NN1N2
外積が面積に比例することを覚えていますか?外積を合計してから合計を正規化すると、必要な加重合計が正確に実行されます。したがって、アルゴリズムは次のようになります。
For each vertex
vertex.n := (0, 0, 0)
For each triangle ABC
// compute the cross product and add it to each vertex
p := cross(B-A, C-A)
A.n += p
B.n += p
C.n += p
For each vertex
vertex.n := normalize(vertex.n)
このテクニックについては、IñigoQuilezの記事「メッシュの巧妙な正規化」で詳しく説明しています。
法線の詳細については、次も参照してください。
x
クロス積)