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

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

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






Этот метод основан на приближении 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; просмотров: 359. Нарушение авторских прав; Мы поможем в написании вашей работы!



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

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

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

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

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

Типовые примеры и методы их решения. Пример 2.5.1. На вклад начисляются сложные проценты: а) ежегодно; б) ежеквартально; в) ежемесячно Пример 2.5.1. На вклад начисляются сложные проценты: а) ежегодно; б) ежеквартально; в) ежемесячно. Какова должна быть годовая номинальная процентная ставка...

Выработка навыка зеркального письма (динамический стереотип) Цель работы: Проследить особенности образования любого навыка (динамического стереотипа) на примере выработки навыка зеркального письма...

Стресс-лимитирующие факторы Поскольку в каждом реализующем факторе общего адаптацион­ного синдрома при бесконтрольном его развитии заложена потенци­альная опасность появления патогенных преобразований...

ТЕОРИЯ ЗАЩИТНЫХ МЕХАНИЗМОВ ЛИЧНОСТИ В современной психологической литературе встречаются различные термины, касающиеся феноменов защиты...

Этические проблемы проведения экспериментов на человеке и животных В настоящее время четко определены новые подходы и требования к биомедицинским исследованиям...

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