У меня есть перспективная проекция. Когда пользователь нажимает на экран, я хочу вычислить луч между ближней и дальней плоскостями, которые проецируются из точки мыши, чтобы я мог сделать некоторый код пересечения лучей с моим миром.
Я использую свои собственные классы матриц, векторов и лучей, и все они работают как положено.
Однако, когда я пытаюсь преобразовать луч в мировые координаты, мой дальний всегда заканчивается как 0,0,0, и поэтому мой луч проходит от щелчка мыши к центру пространства объекта, а не через него. (Координаты x и y ближнего и дальнего координат идентичны, они отличаются только координатами z, где они отрицательны друг от друга)
GLint vp[4];
glGetIntegerv(GL_VIEWPORT,vp);
matrix_t mv, p;
glGetFloatv(GL_MODELVIEW_MATRIX,mv.f);
glGetFloatv(GL_PROJECTION_MATRIX,p.f);
const matrix_t inv = (mv*p).inverse();
const float
unit_x = (2.0f*((float)(x-vp[0])/(vp[2]-vp[0])))-1.0f,
unit_y = 1.0f-(2.0f*((float)(y-vp[1])/(vp[3]-vp[1])));
const vec_t near(vec_t(unit_x,unit_y,-1)*inv);
const vec_t far(vec_t(unit_x,unit_y,1)*inv);
ray = ray_t(near,far-near);
Что я не так понял? (Как вы снимаете проекцию мышки?)
Ответы:
Я недавно должен был решить это сам для приложения WebGL. Я приложил полный исходный код, но если он не работает сразу, вот несколько советов по отладке:
Кроме того, чтобы ответить на некоторые комментарии выше, вы почти никогда не хотите использовать API выбора OpenGL. Это помогает вам выбирать существующие элементы, как, например, если вы создавали меню, однако не может выполнять большинство реальных сценариев, таких как редактирование 3D-моделей. Где вам нужно добавить геометрию в результате клика.
Вот моя реализация. Здесь нет ничего волшебного. Просто JavaScript и библиотека Google Closure.
gluUnProject
использование
источник
Я не вижу никаких проблем с вашим кодом. Так что у меня есть только несколько предложений:
И пытается изменить матрицу умножения на
(p*mv).inverse();
. Просто потому, что glMatrices полностью перенесены в память. (это один большой, может быть, извините)Еще одна
лучевая передача Unprojecting - это не только способ получить луч от пикселя. Это мой код для Raycaster:
Вы можете получить cameraRight, Up и Direction из матрицы просмотра (что наиболее полезно в шейдерах). Просмотр матрицы в opengl
Выбор цвета Выбор
цвета - это метод, при котором каждый объект, на который можно щелкнуть, отображается другим (сплошным) цветом, а затем считывается значение цвета в точке нажатия. GL_SELECTION это работало в opengl. Но это устарело сейчас. Но выбор цвета легко закодировать как 1 дополнительный проход рендеринга.
Используйте буфер кадров и визуализируйте в текстуру с тем же разрешением, что и разрешение экрана, используйте простой шейдер, который просто возвращает цвет во фрагментном шейдере. После «прохода цвета» прочитайте значение из адресации текстуры с помощью clickedPoint x и y. Найдите объект с цветом, который вы прочитали. Легко и довольно быстро.
источник