/ / OpenGL - Правильні поверхневі норми після проекції - opengl, transform, projection, normalals

OpenGL - Правильні поверхневі норми після проекції - opengl, transform, projection, normalals

В даний час я працюю над невеликою програмою для іграшокз OpenGL, який показує сцену в режимі перегляду кліпу, тобто він малює куб, щоб візуалізувати канонічний об'єм перегляду і всередині куба, малюється проективно перетворена модель. Щоб показати фрагмент коду для малюнка моделі:

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glScalef(1.0f, 1.0f, -1.0f);
glMultMatrixd(projectionMat);
glMultMatrixd(modelviewMat);
glEnable(GL_LIGHTING);
draw_model();
glDisable(GL_LIGHTING);

Так, природно, що намальована модель "спотворена"(що є бажаною поведінкою). Проте освітлення неправильне, оскільки нормальні поверхні також перетворюються на проекційну матрицю і, отже, не є ортогональними до їх поверхні після перетворення. Те, що я намагаюся виконати, це освітлення, яке є "правильним" в тому сенсі, що поверхні викривлених моделей мають правильні нормали.

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

Відповіді:

1 для відповіді № 1
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glScalef(1.0f, 1.0f, -1.0f);
glMultMatrixd(projectionMat);

Матриця проекції переходить в glMatrixMode(GL_PROJECTION);. Перетворення нормалей відбувається з зворотним транспонуванням моделі перегляду. Якщо в модельному огляді є проекційна складова, це ускладнює ваше нормальне перетворення.

Правильний код буде

glMatrixMode(GL_PROJECTION);
glLoadMatrixd(projectionMat);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glScalef(1.0f, 1.0f, -1.0f);
glMultMatrixd(modelviewMat);
glEnable(GL_LIGHTING);
draw_model();
glDisable(GL_LIGHTING);

0 для відповіді № 2

Якщо ви використовуєте фіксовану функцію, ви повинні поставити все це у свою матрицю проекції. В тому числі масштаб, переклад та обертання, які відбуваються після проекції:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glScalef(1.0f, 1.0f, -1.0f);
glMultMatrixd(projectionMat);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMultMatrixd(modelviewMat);
glEnable(GL_LIGHTING);
draw_model();
glDisable(GL_LIGHTING);

Це працює тому, що позиції (тобто, що ви бачите) перетворюються як на матриці проекції, так і на модель, але на фіксоване освітлення виконується тільки в просторі (тобто: після перегляду моделі, але раніше проекція)

По суті, саме тому фіксована функція GL має різницю між двома матрицями.