Студопедия Главная Случайная страница Обратная связь

Разделы: Автомобили Астрономия Биология География Дом и сад Другие языки Другое Информатика История Культура Литература Логика Математика Медицина Металлургия Механика Образование Охрана труда Педагогика Политика Право Психология Религия Риторика Социология Спорт Строительство Технология Туризм Физика Философия Финансы Химия Черчение Экология Экономика Электроника

Перспективно-корректное





Этот метод основан на приближении u, v кусочно-линейными функциями. Кратко говоря, при рисовании каждая строка разбивается на куски (обычно несколько кусков длиной 8/16/32 пикселов и один оставшийся произвольной длины), в начале и конце каждого куска считаются точные значения u, v, а на куске они интерполируется линейно.

Точные значения u и v, в принципе, можно считать по формулам из 4.1, но обычно используют более простой путь. Он основан на том факте, что значения 1/Z, u/Z и v/Z зависят от sx, sy ЛИНЕЙНО. Доказательство этого факта пока опущено. Таким образом, достаточно для каждой вершины посчитать 1/Z, u/Z, v/Z и линейно их интерполировать - точно так же, как интерполируются u и v в 4.2. Причем, так как эти значения зависят от sx, sy строго линейно, то интерполяция дает не сильно приближенные результаты, а абсолютно точные!

Сами же точные значения u, v считаются как

u = (u/Z) / (1/Z),

v = (v/Z) / (1/Z).

Дальше все становится совсем просто. При рисовании треугольника, на ребрах интерполируем не u и v, как в 4.2, а 1/Z, u/Z, v/Z. Кроме того, заранее считаем d(u/Z)/dsx, d(v/Z)/dsx, d(1/Z)/dsx (то есть, изменений этих самых u/Z, v/Z, 1/Z соотвествующих шагу по dsx на 1) так, как считали du/dsx – это будет нужно для быстрого вычисления точных значений u, v. Каждую линию рисуем кусками по 8/16/32 пикселов (на самом деле, кусками любой длины; просто если длина - степень двойки, то при вычислении du/dx и dv/dx для текущего куска можно деление на длину куска заменить сдвигом вправо) и, если надо, рисуем оставшийся хвостик. Для расчета точных значений u, v в конце каждого куска пользуемся посчитанными (ага!) значениями d(u/Z)/dsx, d(v/Z)/dsx, d(1/Z)/dsx; раз значения u/Z, v/Z, 1/Z в начале куска известны, меняются они линейно и длина куска известна (либо 16 пикселов, либо длина остатка), то в конце куска они считаются все это до боли просто:

uZ_b = uZ_a + length * duZ_dsx; // расчет u/Z, v/Z, 1/Z в конце куска

vZ_b = vZ_a + length * dvZ_dsx;

Z1_b = Z1_a + length * dZ1_dsx;

Все вместе выглядеть это будет примерно так:

//...

current_sx = x_start;

length = x_end - x_start;

// расчет u/Z, v/Z, 1/Z, u, v в начале самого первого куска

uZ_a = uZ_start;

vZ_a = vZ_start;

Z1_a = Z1_start; // это 1/Z

u_a = uZ_a / Z1_a;

v_a = vZ_a / Z1_a;

// рисуем куски по 16 пикселов

while (length >= 16) {

uZ_b = uZ_a + 16 * duZ_dsx; // расчет u/Z, v/Z, 1/Z, u, v в конце куска

vZ_b = vZ_a + 16 * dvZ_dsx;

Z1_b = Z1_a + 16 * dZ1_dsx;

u_b = uZ_b / Z1_b;

v_b = vZ_b / Z1_b;

u = u_a; // начинаем текстурирование с начала куска

v = v_a;

du = (u_b - u_a) / 16; // можно сделать >> 4, используя fixedpoint

dv = (v_b - v_a) / 16; // можно сделать >> 4, используя fixedpoint

// рисуем 16 пикселов старым добрым "аффинным" методом

len = 16;

while (len--) {

putpixel(current_sx, current_sy, texture[(int)v][(int)u]);

u += du;

v += dv;

current_sx++;

}

length -= 16;

// конец куска становится началом следующего куска

uZ_a = uZ_b;

vZ_a = vZ_b;

Z1_a = Z1_b;

u_a = u_b;

v_a = v_b;

}

// дорисовываем "хвост" линии, если он непуст

if (length!= 0) {

uZ_b = uZ_a + length * duZ_dsx;

vZ_b = vZ_a + length * dvZ_dsx;

Z1_b = Z1_a + length * dZ1_dsx;

u_b = uZ_b / Z1_b;

v_b = vZ_b / Z1_b;

u = u_a; // начинаем текстурирование с начала куска

v = v_a;

du = (u_b - u_a) / length;

dv = (v_b - v_a) / length;

// рисуем остаток пикселов старым добрым "аффинным" методом

while (length--) {

putpixel(current_sx, current_sy, texture[v][u]);

u += du;

v += dv;

current_sx++;

}

}

//...

Как и в 4.2, пройдемся подобным куском кода по всем строкам грани, не забыв вместо "//..." вставить интерполяцию всяких там [u/v/1]Z_start, содранную с интерполяции u_start.. и - о чудо, текстурированная с учетом перспективы грань!

Осталось сказать еще пару слов о кое-какой оптимизации.

Во-первых, два деления при расчете u и v в цикле прорисовки можно (и нужно) заменить на одно - посчитать tmp = 1/Z, дальше u = uZ * tmp, v = vZ * tmp.

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

В-третьих, деление на length при дорисовке хвостика длиной от 1 до 15 пикселов можно заменить на умножение на 1/length, заранее посчитав табличку для значений 1/length.

И наконец, мелкие треугольники можно текстурировать аффинным методом, а большие - методом с коррекцией. Размер треугольника можно определять хотя бы по длине самой длинной горизонтальной линии:

x_start = A.sx+(B.sy-A.sy)*(C.sx-A.sx)/(C.sy-A.sy),

x_end = B.sx,

longest_length = x_end - x_start,

все равно мы ее считаем для расчета du_dsx или duZ_dsx и иже с ними.







Дата добавления: 2015-10-02; просмотров: 378. Нарушение авторских прав; Мы поможем в написании вашей работы!




Шрифт зодчего Шрифт зодчего состоит из прописных (заглавных), строчных букв и цифр...


Картограммы и картодиаграммы Картограммы и картодиаграммы применяются для изображения географической характеристики изучаемых явлений...


Практические расчеты на срез и смятие При изучении темы обратите внимание на основные расчетные предпосылки и условности расчета...


Функция спроса населения на данный товар Функция спроса населения на данный товар: Qd=7-Р. Функция предложения: Qs= -5+2Р,где...

Этапы трансляции и их характеристика Трансляция (от лат. translatio — перевод) — процесс синтеза белка из аминокислот на матрице информационной (матричной) РНК (иРНК...

Условия, необходимые для появления жизни История жизни и история Земли неотделимы друг от друга, так как именно в процессах развития нашей планеты как космического тела закладывались определенные физические и химические условия, необходимые для появления и развития жизни...

Метод архитекторов Этот метод является наиболее часто используемым и может применяться в трех модификациях: способ с двумя точками схода, способ с одной точкой схода, способ вертикальной плоскости и опущенного плана...

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

Тема 5. Анализ количественного и качественного состава персонала Персонал является одним из важнейших факторов в организации. Его состояние и эффективное использование прямо влияет на конечные результаты хозяйственной деятельности организации.

Билет №7 (1 вопрос) Язык как средство общения и форма существования национальной культуры. Русский литературный язык как нормированная и обработанная форма общенародного языка Важнейшая функция языка - коммуникативная функция, т.е. функция общения Язык представлен в двух своих разновидностях...

Studopedia.info - Студопедия - 2014-2025 год . (0.013 сек.) русская версия | украинская версия