Обертання 3D-камери


9

Пробачте, пробачте, але мені потрібна допомога, і я вже кілька тижнів зациклювався на цьому, я не досягаю прогресу, і всюди я йду, і я бачу іншу відповідь, все, що я намагаюся, не працює. У мене було достатньо порад та порад, зараз мені справді потрібен хтось, який дасть мені відповідь, щоб я працював назад, тому що я не можу цього зрозуміти.

Найбільш заплутаною проблемою є те, як кожен користується різним набором конвенцій чи правил, а їх відповіді ґрунтуються на власних конвенціях, не визначаючи, що вони є.

Отже, ось набір конвенцій, які я сформував на основі того, що, як видається, є найпоширенішим та логічним:

  1. Правило правої руки для осі.
  2. Позитивний Y вгору, Позитивний Z - до глядача, Позитивний X - праворуч.
  3. Ряд мажорних матриць, переміщених при надсиланні в шейдери.
    • Крок: обертання навколо осі X
    • Коса: обертання навколо осі y
    • Рулон: обертання навколо осі z
  4. Порядок обертання: нахил, нахил, нахил (чи правильно це? Чи може хтось перевірити мене на цьому?)
  5. Позитивні значення обертання, дивлячись вниз від позитивного кінця осі, призводять до обертання за годинниковою стрілкою.
  6. За замовчуванням напрямок 0 обертання по всій осі є вектором, що вказує вниз на мінус Y.

.. з огляду на ці умовності (яправда виправте мене, якщо вони помиляються!), як це зробити:

  • Написати функцію LookAt? (lookAt (векторне положення, векторний фокус, вектор вгору))
  • Обчисліть матрицю обертання. (обертання (x, y, z))

Я намагався відповісти на ці два питання щонайменше протягом останніх 3 тижнів, я переписав свою функцію LookAt & Rotation Matrix щонайменше 30 разів, я протестував десятки методів і прочитав матеріал, який я бачив на сотні веб-сайтів і прочитали багато відповідей на запитання, скопіювали код інших людей, і нічого, що я зробив до цього часу, не працювало, все дало неправильний результат. Деякі з яких створили деякі дивно химерні виходи, навіть не близькі до правильного обертання.

Я працював над цим щовечора, за винятком минулої ночі, тому що я настільки засмучувався повторною невдачею, що мені довелося зупинитися і перерватися.

Будь ласка, просто покажіть мені, що таке правильний метод, щоб я міг працювати від цього і зрозуміти, як він працює, я просто не отримую правильної відповіді, і це зводить мене з розуму!

Я пишу на Java, але візьму код, написаний будь-якою мовою, більшість моїх кодів 3D-рендерінгу насправді працює досить блискуче, це лише математика, яку я не можу зрозуміти.

ОНОВЛЕННЯ: РІШЕНО

Дякую за твою допомогу! Зараз у мене є робоча функція LookAt, яку я насправді розумію, і я не міг бути щасливішим (якщо хтось хотів би це побачити всіма силами, запитав).

Я спробував ще раз створити матрицю обертання на основі змінних крок / поступово / нахил, і це, здавалося, не вдалося, але я вирішив скинути спробу використовувати кути ейлера для камери вільного огляду, оскільки, здається, непридатний для Роль, натомість я збираюся створити клас кватерніона, можливо, пощастить спуститись по цьому шляху, інакше я вдадусь до використання кроку / пронизування як сферичних координат і покладусь на нову робочу функцію LookAt для обертання.

Якщо хтось ще стикається з подібною проблемою і хоче задати мені питання, сміливо.

Принаймні я більше не застряг, дякую за допомогу!


Ви вирішили свою проблему, я також зіткнувся з подібною проблемою, можете, будь ласка, запитати, як її вирішити? Дякую!
xiao xiao

Відповіді:


15

Що ви шукаєте, можна знайти в цьому дуже хорошому поясненні: http://www.songho.ca/opengl/gl_transform.html

Але оскільки я вважаю це заплутаним, не тримаючи руки, я спробую це пояснити тут.

На цьому етапі потрібно розглянути 5 систем координат і те, як вони співвідносяться одна з одною. Це координати вікон, нормалізовані координати пристрою, координати очей, координати світу та координати об'єкта.

Координати вікон можуть розглядатися як "фізичні" пікселі на вашому екрані. Вони є координатами, на які посилається система вікон, і якщо ви працюєте в нативної роздільної здатності моніторів, це фактично окремі пікселі. Система координат вікна - це 2D цілі числа і відносно вашого вікна. Тут ліворуч х +, а y + внизу, з початком у верхньому лівому куті. Ви стикаєтесь з ними, коли, наприклад, телефонуєте glViewport.

Другий набір - це нормовані координати пристрою. Вони стосуються налаштування місця через порт активного перегляду. Видима зона порту огляду переходить від -1 до +1 і, таким чином, має початок у центрі. Х + ліворуч, а y + вгору. У вас також z + є "поза" сцени. Це те, що ви описуєте в 1.

У вас немає контролю над тим, як дістатися від нормалізованих координат пристрою до координат вікна, це робиться для вас неявно. Єдиний контроль, який ви маєте, це через glViewportабо подібне.

Під час роботи з openGL ваш кінцевий результат завжди буде у нормалізованих координатах пристрою. Як результат, вам потрібно переживати, як зробити свою сцену в них. Якщо ви встановите матрицю проекції та матриці перегляду на матрицю ідентичності, ви можете безпосередньо намалювати ці координати. Це робиться, наприклад, при застосуванні ефектів на весь екран.

Далі - координати очей. Це світ, як видно з камери. В результаті походження знаходиться в камері і застосовуються ті самі осі, що і координати пристрою.

Щоб дістатися від координат очей до координат пристрою, ви будуєте матрицю проекції. Найпростішою є ортографічна проекція, яка просто масштабує значення відповідним чином. Перспективна проекція є більш складною і передбачає моделювання перспективи.

Нарешті у вас є світова система координат. Це система координат, в якій визначений ваш світ, і ваша камера є частиною цього світу. Тут важливо зазначити, що орієнтації на осі є такими, як ви їх визначаєте . Якщо ви віддаєте перевагу z + як вище, це абсолютно добре.

Щоб дістатися від світових координат до координат очей, ви визначаєте матрицю перегляду. Це можна зробити з чимось подібним lookAt. Ця матриця робить "переміщення" світу так, щоб камера стояла біля початку і дивилася вниз по осі z.

Щоб обчислити матрицю перегляду напрочуд просто, потрібно перетворити камеру. В основному вам потрібно сформулювати таку матрицю:

М=х[1]у[1]z[1]-p[1]х[2]у[2]z[2]-p[2]х[3]у[3]z[3]-p[3]0001

Вектори x, y і z можна безпосередньо знімати з камери. У випадку, коли ви дивитесь на вас, ви отримаєте їх від цільових, очних (центрів) та вище значень. Так:

z=ноrмалizе(еуе-таrгет)х=ноrмалizе(уp×z)у=zх

Але якщо у вас ці значення просто лежать навколо, ви можете прийняти їх такими, якими вони є.

Отримати p трохи складніше. Це не положення у світових координатах, а положення у координатах камери. Простий спосіб вирішити тут - ініціалізувати дві матриці, одну з лише x, y і z, а другу з -eye та помножити їх разом. Результат - матриця перегляду.

Як це може виглядати в коді:

mat4 lookat(vec3 eye, vec3 target, vec3 up)
{
    vec3 zaxis = normalize(eye - target);    
    vec3 xaxis = normalize(cross(up, zaxis));
    vec3 yaxis = cross(zaxis, xaxis);     

    mat4 orientation(
       xaxis[0], yaxis[0], zaxis[0], 0,
       xaxis[1], yaxis[1], zaxis[1], 0,
       xaxis[2], yaxis[2], zaxis[2], 0,
         0,       0,       0,     1);

    mat4 translation(
              1,       0,       0, 0,
              0,       1,       0, 0, 
              0,       0,       1, 0,
        -eye[0], -eye[1], -eye[2], 1);

    return orientation * translation;
}

повний код

І, нарешті, для повноти, ви також маєте систему координат об'єктів. Це система координат, в якій зберігаються сітки. За допомогою матриці моделі сітчасті координати перетворюються у світову систему координат. На практиці матриці моделі та перегляду об'єднуються в так звану матрицю перегляду моделі.


1
Якби я міг проголосувати цю відповідь сто разів, я би. Дякую за ретельну та повну відповідь, що стосується всього, що мене бентежив, а також постачав код та посилання! Я провів цілий день, читаючи книги з математики на цю тему, а також з вашою відповіддю та прикладом коду та пов’язаної сторінки, якщо цього мені недостатньо для того, щоб розібратися в цьому, то я повинен зараз кинути роботу. Якби я міг попросити лише одне уточнення, в цьому останньому зразку коду, я би мав рацію сказати, що ці матриці знаходяться в порядку основного стовпця, а вищевказаний - у рядку основного?
Грейді

Це трохи плутати, матриці є основними стовпцями, але стовпець знаходиться в рядку. Отже, щоб зіставити фактичну математику з кодом, вам потрібно перемістити матрицю. Перегляньте сторінку github.com/rioki/glm/blob/master/src/matrix.h#l72 Ця карта точно відкриваєтьсяGL і як це було б, якщо використовувати float[16].
rioki

Ах, я так думав, але просто хотів бути впевненим, ще раз дякую! Ви були величезною допомогою, я дуже ціную це.
Грейді
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.