Обчислення дотичного та бідотичного векторів
Всім привіт! Я написав блог-пост про те, як вивести формули для обчислення дотичного та бідотичного векторів, використовуючи дані у вершинах трикутника (положення, UV, нормаль). Не знаю чи це вам буде корисним, але поділюся ним тут.
Було питання на твіттері щодо того, як обчислити дотичний/tangent та бідотичний/bitangent вектори, знаючи тільки положення UV та нормалю кожної вершини трикутника. У цьому пості я виведу формулу для вирішення цього задання. Ці вектори часто використовуються для відображення нормалей/normal mapping.
По-перше, що таке дотичний/бідотичний вектори? Це вектори, які разом із нормаллю утворюють систему координат. Нормаль вектор виходить від поверхні об’єкта, а дотичний/бідотичний вектори рухаються поверхнею об’єкта.
Дотичними/бідотичними вектором можуть бути будь-які вектори, які перпендикулярні та направлені вздовж поверхні об’єкта. Проте в графіці ми вже зберігаємо UV координати для кожної вершини, а UV координати утворюють двовимірну систему координат, яка орієнтована вздовж поверхні об’єкта. Тому ми зазвичай визначаємо дотичний вектор так, щоб його напрямок був таким самим як U, а бідотичний вектор як V.
Отже, трикутник фактично існує у двох просторах одночасно: у просторі світу (коли використовуємо положення кожної вершини), та у дотичному просторі (коли використовуємо UV координати кожної вершини, це той самий простір, що і UV space):
Ми знаємо, що напрямки векторів U та V такі самі, як напрямки дотичного/бідотичного векторів, але ми хочемо знайти ці напрямки у просторі світу (у дотичному просторі вони просто дорівнюють U=(1,0), V=(0,1)).
Наприклад, положення вершини у просторі світу є перетвореним положенням вершини у просторі UV (і це саме хочемо знайти для цих двох векторів). Тому зараз, виведемо формулу, яка обчислить вектор U та V, у дотичному просторі, і перетворимо цю формулу так, щоб результат був у просторі світу.
Дані змінні:
UV0, UV1, UV2— це положення кожної вершини у дотичному просторі
P0, P1, P2 — це положення кожної вершини у світовому просторі
T — це дотичний вектор у дотичному просторі
B — це бідотичний вектор у бідотичному просторі
Те, що шукаємо:
T′ — це дотичний вектор у світовому просторі
B′ — це бідотичний вектор у світовому просторі
Відтепер, якщо змінна має апостроф (наприклад T′), то це означає, що ця змінна знаходиться у світовому просторі. А якщо апострофа немає, то змінна у дотичному просторі. Тепер давайте зосередимося на трикутника у дотичному просторі:
Якщо обчислимо дельту UV координат між вершинами UV0 та UV1, то отримаємо △U1 та △V1. Ми бачимо, що triangleU1 має цей сам напрямок як T, а △V1 має той сам напрямок, що й B. Можемо це формалізувати у цьому рівнянні:
де △U1 і △V1 це скаляри.
Уявімо, що ми не знаємо до чого T та B дорівнюють у цьому просторі. Тоді, у нас рівняння з двома невідомими змінними, тому нам потрібно отримати ще одне рівняння, щоб обчислити ці дві змінні. Ми можемо обчислити нове рівняння застосовуючи цей самий метод, що і попередньо, але тепер між UV2 та UV1:
Тепер у нас два рівняння та дві змінні, які ми хочемо обчислити:
Є багато способів розв’язання цих двох змінних (метод підстановки, метод усунення), але я виведу формули для цих змінних, застосовуючи метод матриць. Спочатку перемінимо обидва верхні рівняння в одне матричне рівняння:
Ми хочемо отримати формулу, де права матриця залишається сама з одного боку рівняння, а всі інші матриці знаходяться з другого боку. Щоб так змінити цю формулу, обчислимо обернену матрицю наших дельт і помножимо обидва боки рівняння на неї:
І ось так, ми можемо обчислити дотичний/бідотичний вектори! Але ця формула обчислюється у дотичному просторі, а ми хочемо обчислити ці вектори у світовому просторі.
Якщо ми перетворимо обидва боки цього рівняння до простору світу, то побачимо, що нам слід перемінити всі вектори до світового простору (отже E1, E2 перетворюються до E′1, E′2, а всі скаляри залишаються такими самими). Таким чином, ми отримаємо нашу кінцеву формулу. Якщо вас цікавить, як перетворити обидва боки цього рівняння до простору світу, то решта того посту покаже вам, як це зробити, та як вивести остаточні формули. А якщо ні, кінцева формула знаходиться в кінці.
Ми знаємо що перетворення між дотичним простором та світовим простором є лінійним перетворенням (множення на матрицю). А лінійне перетворення задовольняє ці аксіоми:
(1) Адитивність: L(u+v)=L(u)+L(v)
(2) Гомогенність:L(ku)=kL(u) для всіх скалярів k
де L це лінійне перетворення, а u, v це вектори.
Таким чином, скажімо, що функція L — це лінійне перетворення від дотичного простору до простору світу. Викорисуємо її для перетворення наших рівнянь до простору світу. Тільки зауважте, у нас є матриці, а наші аксіоми визначаються тільки для скалярів або векторів. Тому спочатку я розмножу матриці з правого боку рівняння, а після напишу векторну форму нашого рівняння для T та B:
Тепер, перемінимо наше матричне рівняння до векторної форми:
Я змінив вектори на стовпчикові вектори, щоб все помістити у блог-пост :P.
Ці дві формули разом створюють матричну формулу, але у такій формі можна застосовувати аксіоми лінійного перетворення. Почнемо перетворювати рівняння для T до простору світу:
через те, що T′ - це T, але у просторі світу.
застосовуючи гомогенність (2) (перший термін це скаляр).
застосовуючи адитивність (1).
застосовуючи гомогенність (2) (△V1 та △V2- це скаляри).
Тепер, як ми можемо обчислити перетворення змінних E1 та E2? Ну, ми маємо формули для цих змінних, які просто віднімають точки у дотичному просторі, отже ми також можемо відобразити їх з перетворенням L:
застосовуючи адитивність (2)
тому що P0 та P1 — це ті самі точки, але у просторі світу, до якого L відображає. Подібну формулу можемо отримати для E2:
Це перетворює нашу формулу для Т′ у наступне:
І, як бачите, з правої сторони рівняння, ми використовуємо положення вершин у просторі світу (щоб обчислити E′1, E′2) та UV координати, щоб обчислити змінні дельти, які є величинами, які нам відомі! І ця формула обчислює дотичний вектор у просторі світу, що є саме тим, що ми шукаємо! Подібну формулу можемо отримати для бідотичного вектора. Отже, ось остаточні формули:
де
І ось так, ми вивели формули, які обчислюють дотичний та бідотичний вектори, використовуючи дані у вершинах трикутника :)
16 коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів