Обчислити норму з вершинних позицій досить просто, використовуючи векторний поперечний добуток.
Векторний добуток двох векторіву і v (відмічено u × vабо іноді u ∧ v) - вектор, перпендикулярний до у і v, довжини | | u×v | | = | | u | | ⋅ | | v | | sin(θ), с θ кут між у і v. Напрямок вектора буде залежати від порядку множення:u × v є протилежністю v × u (два напрямки, перпендикулярні площині).
Якщо ви не знайомі з крос-продуктом, я пропоную вам ознайомитись з ним та отримати задоволення від нього. Звичайні норми будуть здаватися простими.
Норма плоских відтінків
Якщо у вас є трикутник А Б С, A B × A C- вектор, перпендикулярний трикутнику і довжиною, пропорційною його площі. Оскільки нормальним є одиничний вектор, перпендикулярний площині трикутника, норма можна отримати за допомогою:
N=A B × A C| | 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
Зауважте, що це передбачає, що вершини не поділяються між трикутниками. Я не знайомий з API Kinect; цілком можливо, що вони є спільними, і в цьому випадку вам доведеться їх дублювати або перейти до наступного рішення:
Норма гладкого затінення
Після освітлення нормалями, обчисленими вище, ви помітите, що краї трикутника є видимими. Якщо це не бажано, ви можете замість цього обчислити гладкі норми, враховуючи всі грані, які мають однакову вершину.
Ідея полягає в тому, що якщо однакова вершина ділиться на три трикутники Т1, Т2 і Т3 наприклад, нормальний N буде середнім N1, N2 і N3. Причому, якщоТ1 - великий трикутник і Т2 це крихітний, напевно, ви хочете N піддаватися більше впливу N1 ніж мимо N2.
Пам’ятайте, наскільки поперечний продукт пропорційний площі? Якщо скласти перехресні продукти, то нормалізувати суму, це зробить саме зважену суму, яку ми хочемо. Тож алгоритм стає:
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)
Ця методика більш докладно пояснюється в цій статті Іньїго Кілеса: розумна нормалізація сітки .
Детальніше про норми див. Також:
x
є перехресним продуктом)