Но давайте предположим, что нам необходимо нарисовать объект сложной геометрии и со сложной текстурой. Например, какой-нибудь замысловатый музейный эспонат или дерево с листьями. Или целый лес. Полигональное моделирование потребует очень много затрат, ведь необходимо создать сетку, которая будет содержать как минимум десятки тысяч треугольников, потом задать текстурные координаты и т.д. А откуда взять саму текстуру? Таким образом, процесс моделирования усложняется в несколько раз.
Допустим, он благополучно завершился и мы имеем полигональную модель. Передав ее в OpenGL, мы обнаруживаем, что для моделирования всех шероховатостей и неровностей поверхности, а также всяких мелких выступающих деталей нам потребовалось намного больше полигонов, чем для создания основой структуры объекта! В результате - медленная визуализация, при которой большинство исходных треугольников проецируются в точку на экране, если вообще видны. Конечно, существуют подходы к решению этой проблемы. Например, LOD (Level Of Details) . Однако они не только не решают проблему моделирования реальных объектов, а в некоторых случаях даже усложняют ее.
Существует принципиально другой путь, под названием Image-Based Modeling and Rendering (далее IMBR). Основной идеей этого подхода к моделированию и визуализации является работа с заранее полученными изображениями, например, фотографиями. Самым простым и примитивным воплощением этой идеи являются текстуры, которые, как известно, призваны заменить моделирование сложных отражающих свойств материалов объектов. Однако текстуры не избавляют от необходимости работать со сложными сетками, процесс получения которых как правило слабо автоматизирован.
Главная идея IBR в том, чтобы используя набор изображений одного и того же объекта, сделанных с различных точек, получить вид этого объекта из произвольной точки положения наблюдателя. Таким образом, значительно упрощается моделирование, а рендеринг становится качественным по определению, потому что используются изображения реальных объектов.
Данное задание предполагает реализацию одного из методов IBR.
Быстрое развитие в последнее время средств трехмерного сканирования (range scanners) позволяет получать такого рода информацию в виде карт глубины.
Предположим, что имеется устройство позволяющее измерять расстояние по нормали от некоторой базовой плоскости до интересующего нас объекта, выдавая результат в виде полутонового изображения, яркость в каждой точке которого соответствует расстоянию до объекта (чем точка дальше, тем она темнее). Также пусть оно умеет определять цвет каждой точки, выдавая результат в виде изображения, соответствующего карте глубины (см. рисунок).
Данной информации достаточно, чтобы воспроизвести трехмерную форму объекта как она будет видна с произвольной точки. Осталось только разработать соответствующие преобразования.
Будем считать, что устройство сканирования использует ортогональную камеру для сканирования и, следовательно, получившиеся рисунки сделаны в ортографической проекции. Определим (с избыточностью) эту ортогональную камеру (см. рис.) как четверку (C, a, b, f) .

Пусть пользователь находится в точке P и обозревает наш объект через перспективную камеру. Хотя для математической корректности рассуждений следовало бы расписать параметры камеры, в дальнейшем мы увидим, что нам потребудется только положение наблюдателя P.
МакМиллан в своей диссертации [2] показал, как при известных параметрах исходной камеры, координат точки на базовой плоскости этой камеры, и расстоянии до точки (глубине) получить координаты этой точки на базовой плоскости произвольной камеры. Это формула вида xt = f(xs, d, Cs, Cd) Она позволяет таким образом исказить (warp) исходное изображение, что с данного положения и при данных параметрах камеры наблюдателя объект будет выглядеть корректно, с учетом параллакса, перспективного и модельных преобразований. Эта формула (несмотря на то, что она достаточна проста, приводить я ее здесь не буду, чтобы не уходить в сторону от темы) называется формулой трехмерного ворпинга изображений (3-D image-warping equation). Процесс такого преобразования называется прямой трехмерный ворпинг (forward 3-D image warp)
В 2000-м году Мартин Оливейра [1, 3] развил работу МакМиллана, сделав возможным аппаратную поддержку ворпинга с помощью обычных ускорителей трехмерной графики.
Чтобы прояснить ситуацию, рассмотрим визуальные эффекты, которые создают эффект трехмерности объекта. Это:
Оливейра показал, что можно. Это делается путем факторизации формулы трехмерного ворпинга на две части (так называемый serial warp - последовательный ворпинг), одна из которых отвечает за параллакс, а другая - за аффинное и перспективное преобразования. Первая часть выполняется программно и называется формула пре-ворпинга (pre-warping) (как мы потом увидим, она одномерна, т.е. очень простая), вторая же часть представляет из себя обычное текстурирование и делается с помощью OpenGL.
В реализации этого метода и состоит суть задания.
Простейший алгоритм такой:
P <-- Текущее положение наблюдателя (up, vp) <-- центр проекции на базовую плоскость Производим обход всех точек изображений Icolor, Idepth в правильном порядке(up,vp) для каждой точки (us,vs, Idepth(us, vs), Icolor(us, vs)) (ut, vt) = формула пре-ворпинга(us, vs, Idepth(us, vs), P) записываем точку в новое (целевое) изображение Itarg(ut, vt) <-- Icolor(us, vs)
Устанавливаем в OpenGL положение наблюдателя P и параметры камеры Передаем в OpenGL базовую плоскость с полученным изображением как текстуру
Другими словами, все что нужно сделать, это ко всем точкам исходной
пары изображений цвет+глубина применить формулу, которая преобразует x,y,depth
--> x',y' и записать в пиксель x', y' нового изображения цвет исходного
из точки с координатами x,y. Затем это новое изображение накладывается
как текстура на базовую плоскость, представленную четырехугольником и передается
в OpenGL для визуализации. Эта схема показана на рисунке ниже. (так же
там показана разница между forward 3-D image warp и комбинации pre-warp
+ texture mapping)
Вид этого процесса в 2D-проекции. Информацию про реконструкцию (reconstruction) можно найти в разделе *Продвинутые вопросы: интерполирование и сплаттинг

Вот код, получающий координаты камеры из текущей модельной матрицы OpenGL:
double x_cam, y_cam, z_cam; double m[16]; // matrix glGetDoublev(GL_MODELVIEW_MATRIX, m);
x_cam = -m[12] * m[0] - m[13] * m[1] - m[14] * m[2]; y_cam = -m[12] * m[4] - m[13] * m[5] - m[14] * m[6]; z_cam = -m[12] * m[8] - m[13] * m[9] - m[14] * m[10];В качестве дополнительного упражнения предлагается получить эту формулу самостоятельно.
Центр проекции вычисляется следующим очевидным образом:
c = P - С
up =c a
vp = c b
, где
P - положение наблюдателя
С - верхний левый угол базовой плоскости
up,vp - координаты точки проекции
Обход делается так (см. рисунок):
Изображение разбивается центром проекции up, vp (epipole на рисунке) максимум на четыре части. Для каждой части пиксели ворпируются в порядке от границы к центру проекции.Существует теорема, которая говорит о том, что при таком обходе исходного изображение всегда получается правильный порядок пикселей в результирующем изображении, т.е. более близкие к наблюдателю закрывают более дальние.

, где
ui, vi - координаты точки в выходном изображение (которое затем должно быть передано как текстура в OpenGL)
us = 0..width - 1
vs = 0..height -1
displ(us,vs) = Idepth(us, vs)
Коэффициенты k1, k2 и k3 рассчитываются по следующим формулам (c = P - С)
Заметим, что преобразование по каждой из координат является одномерным, т.е. не зависит от другой координаты, а коэффициенты ki (i=1..3) не зависят от координат пикселя и постоянны для данного положения наблюдателя P
Эти формулы можно вывести, исходя из очень простых геометрических соображений.
Примем без доказательства следующую лемму:Лемма. Для данной конфигурации камер и данных значений координат и глубины пикселя, величина горизонтального (вертикального) сдвига независима от его координаты по вертикали (горизонтали).
Это позволяет нам рассматривать вычисление сдвига в двухмерном пространстве (на рисунке).
![]()
Задача в том, что если мы "видим" базовую плоскость из точки C, то для получения искомой координаты нам нужно виртуально соединить точку х (реальное положение в пространстве точки с координатой us) и точку С и найти координату пересечения с базовой плоскостью. Из рисунка (подобные треугольники):
![]()
, где
displ - глубина точки
us - коорд. пикселя в исходном изображении
ue - координата центра проекции
ui - искомая точкаЗаметим, что:
![]()
![]()
Используя это, получаем:
![]()
Умножая дробь на
, получаем точно искомую формулу при
![]()
Получение точного вида коэффициентов k1 и k2 можно (рекомендуется) найти в [3].
p1 = C p2 = C + a * width + b * height, где
! Обратите внимание, что в OpenGL началом отсчета для координат изображения считается левый нижний угол
Прежде всего важно число операций на одну точку исходного изображения. Это число можно уменьшить, воспользовавшись тем, что в постановке задачи фигурирует дискретная глубина. Число значений ограничено 255. При этом коэффициенты k1, k2 и k3 не зависят от координат и глубины конкретных пикселей.
Можно при изменении положения наблюдателя строить таблицы для каждого из коффициентов, умноженных на глубину. Таким образом можно избавиться от двух умножений и деления, заменив их на 2 индексации и умножение:
const int MAX_DEPTH = 255; double k1pr[MAX_DEPTH]; double k2pr[MAX_DEPTH]; double k3pr[MAX_DEPTH]; k1pr[i] = k1 * i; k2pr[i] = k2 * i; k3pr[i] = 1.0 / (1 + k3 * i);Тогда формула будет иметь следующий вид:
ud = (us + k1pr[d]) * k3pr[d]; vd = (vs + k2pr[d]) * k3pr[d];Также важно оптимизировать сам цикл обхода. Существует очень много различных техник оптимизации на самых разных уровнях.
Главная причина появления дырок - это сама природа алгоритмов визуализации, основанных на изображениях. Дырки является следствием недостатка информации, ведь мы не можем заглянуть "между пикселями" исходных изображений, а иногда это требуется.
Причины появления дырок более подробно:
1) Сплаттинг. Принимая во внимание, что сэмпл обладает конечным размером, можно аппроксимировать размер точки в конечном изображении, заменяя ее так называемым сплатом. Разработано множество эвристик для такого процесса, однако в рамках данного задания предлагается поэксперементировать только с размером сплата. Неплохих результатов можно достичь, просто заменяя каждую точки на квадрат 2x2 или 3x3.
2) Интерполяция. В работах Оливейры [1,3] предлагается другой метод, основанный чисто на работе с изображениями. Процесс пре-ворпинга разбивается на два этапа. На первом делается только горизонтальный (или вертикальный) проход, т.е. ко всем точкам применяется только горизонтальное (вертикальное) смещение. На втором проходе применяются оставшиеся преобразования, но при этом вычисляются расстояние в целевом изображении между текущим и предыдущим ворпированным пикселем и если оно больше 1, то промежуток заполняется интерполированными значениями цвета. Рекомендуется попробовать этот метод, тем более что он хорошо описан в предгалагаемой литературе. (особенно [1])
Изображение с глубиной гарантированно полутоновое, т.е. вы можете, например, работать только с одним каналом. Более высокая яркость точки соответствует меньшему значению глубины. Точка с яркостью 0 - прозрачная (нет объекта). 255 соответствует точке, лежащей на базовой плоскости. (Значения яркости переводятся в глубину так: глубина = 255 - яркость)
Далее на экран должна выводиться текстурированная грань, создавая иллюзию трехмерного объекта. Обязательно должна быть предусмотрена возможность интерактивного вращения. При любом допустимом размере входного изображения грань должна вписываться в окно программы.
Разрешается использовать как GLUT так и работать с Win32 (MFC и т.д.)
Развитый интерфейс приветствуется.
[1] Oliveira, M. et al. Relief Texture Mapping.
Siggraph'2000 conference proceedings
[2] McMillan, L. An
Image-Based Approach to Three-Dimensional Computer Graphics. Ph.D.
Dissertation. UNC Computer Science Technical Report TR97-013, University
of North Carolina, April 1997.
[3] Oliveira, M. Relief Texture Mapping.
Ph.D. Dissertation. UNC Computer Science Technical Report TR00-009. 2000.
Тестовые данные:
Спецкурс "Доп. главы машинной графики", 2001 4-ое задание: Image-based rendering / Relief textures [Фамилия] [Имя] [Отчество] Среда: Hardware: [напр. P4-1200 512M GeForce3] OS: [Win95 / Win98 / WinNT4 / Win2000 SP1 / WinXP / ?] Среда прогр.: [CBuilder / VS 6.0 / ?] Комментарии по реализации: [комментарии, что было сделано, какие возникали трудности] |
Вопросы по заданию и/или по OpenGL можно задать Алексею Игнатенко по
электронной почте (ignatenko@graphics.cs.msu.su)
или лично в лаборатории (703,77) предположительно в следующее время:
вт. 20.00-21.00
пт. 19.30-21.00
Результаты станут известны в течение полутора недель после крайнего срока сдачи.