|
ТЕКСТУРИРОВАНИЕ Этот метод основан на приближении u, v квадратичными функциями - параболами, то есть. Для каждой строки строится приближающие u, v квадратичные функции, дальше с их помощью они интерполируются по строке. Для этого нам понадобятся точные значения u, v в трех точках - начале, середине и конце строки. Их считаем точно так же, как в 4.3. Итак, пусть у нас есть точные значения u в начале, середине и конце строки, то есть на расстоянии 0, length/2 и length пикселов от начала этой строки, обозначим их как ua, ub, и uc соответственно. Мы пытаемся приблизить u квадратичной функцией, то есть полагаем, что u = A*x*x + B*x + C, где x - расстояние от текущей точки до начала строки. Тогда, подставив в формулу ua, ub, uc и соответствующие им x, получаем: ua = C, Т.о. C = ua, а для A и B имеем систему уравнений: A*(length*length)/4 + B*length/2 = ub - ua, Умножим первое уравнение на четыре, вычтем из него второе: 4*A*(length*length)/4 + 4*B*length/2 -
A*(length*length - B*length = Умножим первое уравнение на два, вычтем его из второго: A*(length*length) + B*length -
2*A*(length*length)/4 - 2*B*length/2 = Получили формулы для A, B, C. Найдем теперь du и ddu. Для текущей точки x имеем: du(x) = u(x+1) - u(x), Т.о., начальные значения u, du, ddu будут равны u = C, А по известным начальным значениям u, du, ddu последовательно вычисляем значения u в любой точке: u(0), du(0), ddu - известны Для v все делается полностью аналогично. Таким образом, рисование строки будет выглядеть примерно так: // ... // считаем u, v для начала, середины и конца строки ua = uz_start / z1_start; va = vz_start / z1_start; ub = (uz_start + uz_end) / (z1_start + z1_end); vb = (vz_start + vz_end) / (z1_start + z1_end); uc = uz_end / z1_end; vc = vz_end / z1_end; // считаем начальное du и ddu pa = 2 * ((uc - ua) - 2 * (ub - ua)) / (length * length); pb = (4 * (ub - ua) - (uc - ua)) / length; pc = ua; u = pc; du = pa + pb; ddu = 2 * pa; // считаем начальное dv и ddv pa = 2 * ((vc - va) - 2 * (vb - va)) / (length * length); pb = (4 * (vb - va) - (vc - va)) / length; pc = v_a; v = pc; dv = pa + pb; ddv = 2 * pa; // рисуем кусок while (length--) { putpixel(current_sx, current_sy, texture[v][u]); u += du; v += dv; du += ddu; dv += ddv; } // ... По сравнению с перспективно-корректным текстурированием имеем более медленный внутренний цикл, но меньшее для длинных строк количество делений. Расчет ua, va и иже с ними можно сделать с помощью трех делений, деления на length и (length*length) можно заменить умножениями на 1/length и 1/(length*length), беря эти значения из заранее посчитанной таблички. Т.о., на строку приходится три деления независимо от ее длины. Качество более-менее приемлемое; а для коротких строк можно использовать обычную линейную интерполяцию, точно так же, как и в случае с перспективно-корректным текстурированием. Получаем вполне конкурентоспособный метод текстурирования. |
|