Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Kompyuternaya_grafika.doc
Скачиваний:
16
Добавлен:
07.09.2019
Размер:
674.3 Кб
Скачать

Лекция 7. Основы 3d графики Задание объектов и сцен

Покажем здесь достаточно распространенную схему задания 3D объектов и сцен. Подобная схема, кстати, используется, в 3D Studio.

Каждая сцена представляет собой следующее:

  • набор объектов

  • набор источников света

  • набор текстур

  • набор камер (хотя обычно используется одна)

Каждый объект задается следующим:

  • Набор вершин

Вершина определяется своими 3D координатами и соответствующими ей координатами в текстуре.

  • Набор граней

Грань определяется тремя вершинами и текстурой (вообще говоря, не текстурой, а материалом: кроме текстуры могут быть заданы, например, коэффициенты рассеивания и отражения света).

  • Поведение объекта

Т.е., расположение (смещение, ось поворота, угол поворота, коэффициент масштабирования и т.д.) в зависимости от номера кадра; обычно задается в нескольких ключевых точках и интерполируется между ними с помощью сплайнов.

Каждый источник света задается следующим:

  • положение

  • ориентация (точка, в которую направлен этот источник, target)

  • тип (фоновый/направленный/ненаправленный)

  • цвет (обычно RGB)

Каждая текстура представляет собой прямоугольную 2D картинку, часто бывает фиксированных размеров (например, 64x64, 128x128, 256x256).

Каждая камера задается следующим:

  • положение (location)

  • направление (точнее, точкой, в которую направлена эта камера; target)

  • угол зрения (FOV)

  • угол поворота относительно своей оси (roll)

П ерспективное проецирование

Используемая система 3D координат на рис. 7.1.

Здесь буквами x, y, z обозначены положительные направления осей Ox, Oy и Oz соответственно. Также предполагается, что камера неподвижна и находится в точке (*) с координатами (0,0,-dist), ось зрения камеры направлена по оси Oz, а именно в точку (0,0,0) (т.е. camera target = (0,0,0)), ось Ox с точки зрения камеры направлена слева направо, ось Oy - снизу вверх, ось Oz - вглубь экрана. Размер экрана - xSize на ySize пикселов.

Проецирование на плоскость экрана в этом случае будет осуществляться по формулам

sx = xSize/2+x*dist/(z+dist),

sy = ySize/2-y*dist/(z+dist).

Здесь и далее используются обозначения:

sx, sy

координаты проекции точки на экране

x, y, z

3D координаты точки,

dist

расстояние от камеры (она находится в точке (0,0,-dist)) до начала координат,

u, v

координаты в текстуре (u - по горизонтали, v – по вертикали).

Работа с произвольной камерой

Рассмотрим любую камеру как точку - центр проецирования и экран - плоский прямоугольник в 3D пространстве, на плоскость которого идет проецирование. Наша стандартная камера, например, задается точкой (0,0,-dist) и экраном с вершинами (-xSize/2,ySize/2), ..., (xSize/2,-ySize/2). Можно задать эту систему тремя векторами, задающими с точки зрения камеры направления вперед, вправо и вверх; вектор "вперед" соединяет центр проецирования и центр экрана, вектор "вправо" соединяет центр экрана и правую его границу, вектор "вверх", соответственно, центр экрана и верхнюю его границу. Обозначим эти вектора как p, q и r соответственно, а центр проецирования за s. Вот пример для стандартной камеры.

Здесь (для стандартной камеры; обозначим ее вектора как Sp, Sq, Sr, Ss)

Sp = p = (0,0,dist)

Sq = q = (xSize/2,0,0)

Sr = r = (0,ySize/2,0)

Ss = s = (0,0,-dist)

Любые три взаимно перпендикулярных вектора и точка - центр координат задают в 3D пространстве систему координат. Так что объект мы можем рассматривать в системе обычных координат (x,y,z), в системе координат стандартной камеры (Sp,Sq,Sr) или в системе (p,q,r), соответствующей какой-то произвольной камере. В любом случае, если (a,b,c) - координаты точки в системе координат камеры (точнее, в системе координат с центром в точке s и базисом (p,q,r)), то координаты проекции точки на экране равны

screenX = xSize/2 + xSize/2 * a/c

screenY = ySize/2 - ySize/2 * b/c

В случае стандартной камеры переход от обычной системы координат к системе координат камеры очевиден:

a = x / (xSize/2)

b = y / (ySize/2)

c = (z + dist) / dist

Подставив это в формулы для screenX, screenY, получим как раз те самые формулы для проекции на стандартную камеру.

Поскольку со стандартной камерой нам достаточно удобно и понятно работать, для произвольной камеры мы должны сделаеть такое преобразование пространства, что как бы совместит произвольную камеру и стандартную камеру. То есть, такое преобразование, что вектора p, q, r перейдут в Sp, Sq, Sr, а точка s в точку Ss.

Посчитаем матрицу для *обратного* преобразования; оно должно переводить Sp, Sq, Sr, Ss в p, q, r, s. Преобразование, переводящее Ss в s (и наоборот) - это обычный паралелльный перенос; остается написать преобразование перевода Sp, Sq, Sr в p, q, r. Пусть у нас есть координаты p, q, r в системе координат (x,y,z):

p = (px,py,pz)

q = (qx,qy,qz)

r = (rx,ry,rz)

Для Sp, Sq, Sr координаты (в этой же системе) известны и равны следующему:

Sp = (0,0,dist)

Sq = (xSize/2,0,0)

Sr = (0,ySize/2,0)

Пусть T - искомая матрица перевода,

[ a b c ]

T = [ d e f ], a..i - какие-то неизвестные.

[ g h i ]

Поскольку T переводит Sp, Sq, Sr в p, q, r; то есть

p = T*Sp

q = T*Sq

r = T*Sr

то, подставляя, например, p и Sp, получаем:

[ px ] [ a b c ] [ 0 ] [ c*dist ]

[ py ] = [ d e f ] [ 0 ] = [ f*dist ], откуда

[ pz ] [ g h i ] [ dist ] [ i*dist ]

c = px/dist,

f = py/dist,

i = pz/dist.

Аналогично находим все остальные элементы матрицы T:

[ qx*2/xSize rx*2/ySize px/dist ]

T = [ qy*2/xSize ry*2/ySize py/dist ]

[ qz*2/xSize rz*2/ySize pz/dist ]

Но нас интересует обратное к этому преобразование. Оно задается обратной матрицей к T, то есть такой матрицей T1, что

[ 1 0 0 ]

T * T1 = T1 * T = [ 0 1 0 ]

[ 0 0 1 ]

Обратная матрица, вообще говоря, существует далеко не всегда, да и вычисление ее в общем случае - достаточно неприятная задача. Однако в данном случае из-за специального вида матрицы T (конкретнее, из-за того, что T - ортогональная матрица) она не только всегда существует, но и считается очень просто:

[ qx*2/xSize rx*2/ySize px/dist ] [ qx1 rx1 px1 ]

T = [ qy*2/xSize ry*2/ySize py/dist ] = [ qy1 ry1 py1 ]

[ qz*2/xSize rz*2/ySize pz/dist ] [ qz1 rz1 pz1 ]

[ qx1/lq qy1/lq qz1/lq ]

T1 = [ rx1/lr ry1/lr rz1/lr ]

[ px1/lp py1/lp pz1/lp ]

где

lp = px1*px1 + py1*py1 + pz1*pz1

lq = qx1*qx1 + qy1*qy1 + qz1*qz1

lr = rx1*rx1 + ry1*ry1 + rz1*rz1

Сделав сначала параллельный перенос, совмещающий s и Ss, а потом полученное преобразование, как раз и получим преобразование, переводящее произвольную камеру в стандартную.

Теперь надо выяснить, как, собственно посчитать координаты p, q, r через имеющиеся у нас характеристики: положение, направление, угол зрения и угол поворота. 3D Studio (и мы вслед за ней) рассчитывает эти вектора по такому алгоритму:

  1. Считаем p = target – location

  2. Если p.x == 0 и p.z == 0, то q = (0, 0, 1); иначе q = (p.z, 0, -p.x)

  3. Считаем r = crossProduct(p, q) - векторное произведение p на q

  4. Считаем lp = length(p) - длина p

  5. Приводим r и q к длине 2*lp*tan(FOV/2)

Здесь мы не учитываем поворот камеры вокруг своей оси, его удобнее сделать после перехода к стандартной камере - в этом случае получаем обычный поворот относительно оси z на угол roll.

Таким образом, окончательная матрица перевода должна представлять собой произведение матрицы параллельного переноса, матрицы T1 и матрицы поворота вокруг оси z на угол roll:

FinalCameraMatrix = RollMatrix * T1 * MoveMatrix

Расчет матриц RollMatrix и MoveMatrix очевиден.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]