Текстурирование граней

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

Текстурирование в общем случае

Рассмотрим текстурирование в общем случае. Результатом решения задачи текстурирования грани является соотношение, по которому можно вычислить значение параметров текстур в зависимости от координат какого-либо пикселя на экране, соответствующего некоторой точке грани. Параметрами текстуры (обозначаются u и v) являются соответственно горизонтальное и вертикальное смещения от левого верхнего угла текстуры. Для формирования цвета пикселя на экране, соответствующего той или иной точке грани, сначала вычисляются параметры текстуры, а затем по соответствующим смещениям из текстуры берётся её элемент - тексель - и цвет пикселя на экране приравнивается цвету текселя.

Рассмотрим произвольную грань (рис. 1), заданную в пространстве своими вершинами - P1, P2, P3, P4. Пусть грань является прямоугольной. Определим несколько векторов, которые потребуются для дальнейших расчётов:

a = P1;
e1 = P2 - P1;
e2 = P4 - P1;
Рис. 1

Нормаль к грани определяется векторным произведением n = [e1, e2]. Пока будем считать, что перспективное преобразование определяется следующими соотношениями: X = x / z, Y = y / z. Где X и Y определяют положение точки на экране, а x, y и z задают положение точки в пространстве.

Найдём координаты произвольной точки p грани, считая, что параметры текстуры u и v в точках P2 и P4 равны 1, а в точках P1 и P3 - 0: p = a + ue1 + ve2. Теперь, пользуясь перспективным преобразованием, описанным выше, определим координаты этой точки на экране:

Но нам нужно определить не её координаты на экране, а параметры текстуры, соответствующие этим координатам. Для этого разрешим предыдущее соотношение относительно u и v. Выполнив необходимые преобразования, получим систему линейных уравнений относительно u и v:

Для решения этой системы воспользуемся формулами Крамера:

где:

векторы m и l определяются следующими векторными произведениями:

Для удобства можно записать все эти соотношения в матричной форме:

Эти соотношения соответствуют перспективному преобразованию, задаваемому формулами X = x / z, Y = y / z. Но в общем случае перспективное проецирование задаётся следующими формулами:

Можно записать эти формулы в матричной форме:

Тогда для определения параметров текстуры в общем случае перспективного проектирования можно воспользоваться следующей матричной записью соотношений:

Таким образом решается задача о получении параметров текстуры в зависимости координат пикселя, соответствующего какой-либо точке грани. На практике, чаще всего вместо квадратных граней используются треугольные. В этом случае такой гране будут соответствовать вершины P1, P2 и P4 (см. рис. 1).

Возникает следующая проблема: указанные соотношения требуют выполнения достаточно большого количества вычислений для определения параметров текстуры, соответствующих одной точке. В этом случае точное решение задачи заменяется приближённым, причём точность приближённого решения и математические методы для его реализации выбираются в зависимости от качества требуемого результата. Если требуется получить изображения среднего качества, то в качестве приближённого решения обычно выбирается линейная интерполяция - координаты текстуры сначала вычисляются для всех вершин грани, а промежуточные значения сначала линейно интерполируются по рёбрам, а затем между рёбрами (аналог закрашивания Гуро). При этом возникают сильные искажения изображения на линиях стыка граней (рис. 2). Более качественное изображение можно получить, используя квадратичную интерполяцию. При этом значение неизвестного параметра текстуры задаётся формулой u(x) = a0 + a1x + a2x?, где a0, a1 и a2 - параметры интерполяции. Пусть требуется произвести квадратичную интерполяцию на отрезке [x1, x2]. Для определения параметров интерполяции сначала точно вычисляются координаты текстуры в точках x1 и x2, а также в промежуточной точке x3. Например, x3 = (x1 + x2) / 2. Тогда параметры квадратичной интерполяции вычисляются по формулам:

Эти формулы можно немного упростить если считать, что x1 = 0, а x2 = 1. Само же значение x будет изменяться от x1 до x2 на шаг h = 1 / (x2 - x1). Тогда полученные формулы можно записать в виде:

Для вычисления параметра текстуры в промежуточных точках между x1 и x2 можно воспользоваться следующими рекуррентными соотношениями:

Для повышения качества получаемого изображения также можно использовать кубическую интерполяцию вида:

Для вычисления параметров кубической интерполяции сначала необходимо вычислить значения парметра текстуры в двух промежуточных точках:

Далее для определения параметров кубической интерполяции необходимо составить систему линейных уравнений относительно a0, a1, a2, a3 и a4:

Можно использовать интерполяцию и более высокого порядка, но тогда значительно возрастает количество вычислений, а качество изображения улучшается не на много. Вообще, при использовании интерполяции n-го порядка и соответствующих рекуррентных сотношений, для расчёта параметров текстуры для одного пикселя потребуется выполнения n операций сложения.

Существуют альтернативные пути решения проблемы возрастания количества вычислений при выборе качества изображения. Один из таких подходов позволяет получить среднее качество изображения при учёте того, что среднее значение глубины грани не намного отличается от глубин её вершин. При этом подходе значения параметров текстуры вычичисляются точно на рёбрах грани, а между рёбрами используется линейная интерполяция. Можно использовать этот подход для улучшения качества изображения и использовать не линейную, а квадратичную интерполяцию. Существует ещё один довольно эффективный подход, который позволяет получить довольно высокое качество изображения при минимальном количестве вычислений. Этот подход используется в игре Quake и Quake II. Значения параметров текстуры вычисляются точно через каждые 8 или 16 точек по горизонтали и вертикали, а промежуточные значения получаются путём применения линейной интерполяции.

Пирамидальное фильтрование (mip-mapping)

Предположим, имеется горизонтальная текстурированная плоскость и наблюдатель, находящийся на некотором расстоянии над этой плоскостью (рис. 2). Часть изображения на горизонте обведена квадратом. Бросается в глаза то, что чем ближе к горизонту, тем более случайными становятся параметры текстуры и, соответственно, цвета пикселей. Это объясняется тем, что на больших расстояниях одному пикселю экрана может соответствовать несколько текселей текстуры, а, так как смещение для текстуры является целым числом, то для каждоко пикселя выбирается ближайший к нему тексель.

Рис. 2

Для корректного отображения пикселей необходимо усреднять значения текселей, соответствующих этому пикселю. Однако это достаточно сложная операция чтобы производить её в реальном масштабе времени. Существует подход, позволяющий решить эту задачу приближённо, обеспечивая, тем не менее, довольно высокое качество получаемого изображения. Пусть текстура представлена в виде матрицы размером 64 на 64. Для этой текстуры строятся дополнительные текстуры с размерами 32, 16, 8, 4, 2 и 1 тексель соответственно по горизонтали и вертикали. Значения текселей для текстуры с размером 32 на 32, например, вычисляются следующим образом: тексели текстуры 64 на 64 объединяются в группы по 4 (2 на 2), затем усредняется их цвет и присваивается соответствующему текселю текстуры 32 на 32. Таким же образом определяются цвета текселей остальных дополнительных текстур. Результат подобного преобразования представлен на рис. 3.

Рис. 3

Таким образом, если имеется текстура размером 2^n на 2^n текселей, то для неё формируется n изображений размерами соответственно 2^n-1, 2^n-2, ... , 2^0 по каждому измерению. Получается пирамида, основанием которой является исходная текстура, а вершиной - текстура с размером 1 на 1. Теперь предположим, что требуется определить цвет пикселя, соответствующий сжатию исходного изображения в n раз (на этот пиксель приходится n на n пикселей). Если n больше размера исходной текстуры, то выбирается тексель из текстуры с размером 1 на 1, в противном случае выбирается тексель из текстуры с такого уровня i, что 2^i <= k <= 2^(i + 1). Таким образом усредняются несколько текселей, соответствующие одному пикселю. Пример изображения, полученного таким способом, показан на рис. 4.

Рис. 4

Однако, такой подход всё же имеет один недостаток: при переходе с одного уровня пирамиды (или mipmap-уровня) на другой заметны небольшие разрывы на границе перехода. Иными словами изображение является несколько "полосатым" - каждая полоса соответствует своему mipmap-уровню. Решением этой проблемы является интерполяция уровня пирамиды. Это обычно выполняется при помощи трилинейной интерполяции и применяется в некоторых современных ускорителях 3D графики.

Фильтрация текстур (textures filtering)

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

Рис. 5

Для устранения этого недостатка используется билинейная интерполяция. Для определения цвета пикселя, соответствующего тому или иному текселю значение цвета пикселя сначала интерполируется по вертикали между двумя соседними вертикальными текселями, а затем - по горизонтали между цветами, вычисленными при вертикальной интерполяции. Изображение, полученное таким образом, показано на рис. 6. В настоящее время данный метод используется во всех современных ускорителях 3D графики.

Рис. 6

Рассмотрим подробнее, как можно определить цвет произвольного пикселя в единичном квадрате, соответствующим тому текселю, которому соответствует данный пиксель (рис. 7).

Рис. 7

Буквами x и y обозначены координаты пикселя, которые являются дробными, так как квадрат, в которм находится пиксель является единичным. Символом t обозначена функция, возвращающая цвет текселя с округлёнными (по направлению к минус бесконечности) координатами x и y. Тогда цвет пикселя p задаётся следующими соотношениями:

Обычно, при вычислении этих соотношений, используются рекуррентные соотношения и инкрементальные методы, значительно сокращающие количество необходимых вычислений.

Рельефное текстурирование (bump mapping)

Другим интересным методом повышения детализации сцены, наряду с обычным текстурированием, является рельефное текстурирование. Суть метода состоит в том, что кроме обычной текстуры имеется карта высот, представляющая собой матрицу целых чисел - высот, или тукстуру в чёрно-белых тонах. При текстурировании грани методом рельефного текстурирования нормаль к поверхности грани вычисляется в результате интерполяции между элементами карты высот. То есть нормаль к поверхности грани определяется как если бы на этой гране были выпуклости, соответствующие карте высот. Этот метод позволяет показать рельеф поверхности, причём этот эффект очень хорошо проявляется при освещении источником света с разных сторон. В настоящее время рельефное текстурирование применяется в ряде современных 3D ускорителей, например в Matrox G400 и Voodoo5.

Возврат в раздел "Писанина"Возврат на Главную Страницу

Hosted by uCoz