Как создать эффект объектива "рыбий глаз" с помощью openGL?
Я пытаюсь создать эффект "рыбий глаз" на изображении с помощью openGL. Я новичок в openGL, я должен использовать кубическое отображение и рыбий глаз? Есть ли открытый источник, на который я могу сослаться? Благодарю.
2 ответа
Вы можете нарисовать один квадрат с изображением, текстурированным на нем, и использовать фрагментный шейдер, чтобы деформировать координату текстуры для каждого пикселя по своему желанию. Вы должны будете сделать всю математику самостоятельно, но похоже, что предыдущий пост здесь может быть хорошей отправной точкой.
Использование заголовка вопроса, не влияющего на изображение, для создания «настоящих» изображений «рыбий глаз», т. Е. полезное поле зрения 180+ градусов ...
Есть два немного разных метода адаптации существующих конвейеров к представлению «рыбий глаз» (с помощью «простого» OpenGL). Оба требуют визуализации сцены до 6 раз - для каждой стороны «коробки», которая будет проецироваться на плоский экран. Каждая сторона / поверхность должна быть квадратной - или должна быть, в зависимости от метода - и, вероятно, меньше, чем исходное полное окно просмотра.
Требуемое количество сторон зависит от требуемой ширины поля зрения «рыбий глаз». В типичном FPS для FOV 130 достаточно трех сторон. Для поля зрения до 220 - пять сторон.
Метод 1 - текстура кубической карты (GL_ARB_texture_cube_map)
- инициализируйте один раз, для определенного FOV, предварительно рассчитайте таблицу перевода 2d экранных координат в 3d координаты текстуры кубической карты, сетки 16x16 для всего экрана должно быть достаточно
- настроить область просмотра и расположить камеру соответственно для рендеринга сторон бокса, выполнить обычный рендеринг
- привяжите стороны к текстуре GL_TEXTURE_CUBE_MAP_ARB
- перебирать экран, излучающий (прямоугольные) GL_QUAD_STRIP-s, используя таблицу перевода и кубическую карту.
Метод 2 - 2d или прямоугольные текстуры (GL_NV_texture_rectangle)
- инициализируйте один раз, для определенного FOV, предварительно вычислите таблицу "лучей" текстуры + 2d текстурные координаты до 2d экранных координат
- как в методе 1, настройте область просмотра и поместите камеру соответственно для рендеринга сторон блока, выполните обычный рендеринг.
- привяжите стороны к текстурам GL_TEXTURE_RECTANGLE_NV или GL_TEXTURE_2D
- перебирать текстуры, испускающие (трапециевидные) GL_QUAD_STRIP-ы на экране, используя таблицу "лучей".
Метод 1 проще и дает лучшие результаты.
Попытки:
- установить обтекание текстуры кубической карты на GL_CLAMP_TO_EDGE
- в типичном FPS вид игрока - это не только тангаж и рыскание, но и крен - рассчитайте ориентацию камеры для каждой стороны с помощью правильного поворота
- если цикл рендеринга объединен с прогрессом / физикой / искусственным интеллектом, повторный рендеринг сцены может сбить с толку существующие внутренние компоненты.
Все это конечно зависит от специфики конкретного двигателя. Я не уверен, насколько хорошо это применимо к базовому профилю OpenGL 3.3+, но идея должна быть такой же.
Можно нарисовать мир в виде «рыбьего глаза» за один проход, выполнив преобразование «рыбий глаз» в вершинном шейдере. Но! для этого требуется, чтобы исходная геометрия была достаточно (предварительно) мозаичной. Или можно использовать шейдер геометрии и / или шейдеры тесселяции для организации обратной связи тесселяции / преобразования на графическом процессоре. Последнюю, возможно, следует встроить в рендер с нуля.
В качестве хорошо изолированного примера с использованием движка Quake 1 см. Fisheye и Panorama OpenGL FPS и конкретно это различие . К сожалению, пример вершинного шейдера утерян.