float logdp = -log2(dp):

float ilogdp = floor(logdp):

float frequency = exp2(i1ogdp):

float sawtooth = fract(V * 16.0 * frequency): Сфера с большей частотой линий показана на рис. 15.2, б. Видно, что в нижней части сферы линии выглядят нормально, но на полюсе их слишком много. Внесем изменения в частоту линий, и получится, что по всей сфере полоски практически одинаковы (рис. 15.2, в). (Заметьте, как соотносятся рис. 15.2, а и в.)

Следующая особенность процедуры - сглаживание изменений, происходящих при смене частоты. Глаза видят явный край между этими переходами и нужно его как-нибудь смягчить. Можно использовать дробную часть 1 ogdp для задания плавного перехода между частотами. Это значение будет равно 0 в начале одной частоты и увеличится до 1,0 в точке изменения частоты: float transition = logdp - ilogdp: Полоски с двойной частотой можно получить с помощью формулы abs (2.0 * t -1.0). Можно использовать значение t га ns i t i on для линейной интерполяции между t и abs (2.0 * t - 1.0), вычислив выражение (1.0 - transition) * t + transition * abs(2.0*t -1.0) (это то же самое, что выражениеппх(аЬ5(2.0,Ч -1.0),t, transition)). Но вместо использования mix возьмем его эквивалент a bs((l. О - transition) * t - tran-siti on). Используя вычисленное ранее значение для основной частоты (t ri angl е), получим такой код:

triangle = abs((1.0 - transition) * triangle - transition); Результат рисования сферы с полосками одинаковой ширины и заостренными краями показан на рис. 15.2, г.

L5.1.5. Освещение

Чтобы имитировать освещение, нужно сделать темные штрихи более заметными в тени, а белые - более заметными в освещенных областях. Сделать это можно с помощью вычисленного значения интенсивности освещения, изменяя пороговое значение функции step. В освещенных областях пороговое значение уменьшается, и черные полоски будут тоньше, а в затененных областях, наоборот, пороговое значение увеличивается, и черные полоски будут шире:

const float edgew = 0.2; // ширина шага

float edgeO = clamp(Lightlntensity - edgew, 0.0, 1.0);

float edgel = clampdightlntensity. 0.0. 1.0);

float square = 1.0 - smoothstep(edgeO. edgel. triangle): Чтобы сглаживать переход, нужна функция smoothstep. Так как полоски в пространстве экрана приблизительно одинаковой ширины, можно использовать фильтр постоянной ширины. Результаты наложения освещения показаны на рис. 15.3.

Рис. 15.3. Наложение освещения на сферу: а - сфера освещена простым источником и на ней нет полосок; б- интенсивность освещения влияет на толщину полосок1

15.1.6. Имитация ручной работы

Если бы гравюра была выполнена не компьютером, а человеком, то штрихи не были бы идеально ровными. Нужно внести некоторое несовершенство в изображение с помощью шума, как описано в главе 12. Для этого шейдера не нужно придумывать ничего особенного: немного волнистости, частично разорванные линии. Трехмерная текстура с шумом Перлина вполне годится для этих целей.

Чтобы сделать штрихи волнистыми, можно изменить функцию float sawtooth = fract((V + noise * 0.1) * frequency * stripes):


⇐ вернуться назад | | далее ⇒