Блестки на платье

Появилась задача – сделать платье с блестками для персонажа… Шейдер был сделан довольно быстро, но как показала практика он был далек от физической модели и как следствие смотрелся не очень…
Мой друг указал на ошибки и объяснил, почему появляются блики, и как следствие решение проблемы было сразу найдено и был написан шейдер бликов, а точнее Shading Component на спекуляры…

Для начала теория. Откуда появляются блестки на поверхности? Все просто – ткань покрыта небольшими «чешуйками» которые мы будем считать миниатюрными квадратиками для упрощения. Эти «чешуйки» зеркальные и лежат на поверхности хаотично, и имеют вектор нормали не совпадающий с вектором в данной точки поверхности. Как следствие при движении объекта или камеры или света – будет видна игра этих бликов на поверхности…

Задача:

1. сделать хаотичные квадратики на поверхности объекта
2. дать каждому квадратику свою нормаль отличную от N
3. использовать нормаль из п.2 для просвета спекуляров

То есть задача не выходит за рамки базовых знаний shading-languige. Приступим
Входящие параметры будут:

density – плотность точек. На практике количество ячеек на поверхности s,t и как следствие квадрат этого числа равен числу наших квадратиков
size – размер одного квадратика
pt_razbros – хаотичность разброса квадратиков
v_razbros – максимальное отклонение нормали квадратика от нормали повернхности

1. Хаотичные квадратики:

float cx = .5;
float cy = .5;

float ss = mod(s * density + seed, 1);
float tt = mod(t * density + seed, 1);

ss += (cellnoise(s * density + seed, t * density + seed) – .5) * pt_razbros;
tt += (cellnoise(s * density + seed, t * density + seed) – .5) * pt_razbros;

if < (size * density && (abs(tt-cy) < (size * density))) pt = color(1);
else pt = color(0);

Думаю комментарии излишни будут к коду – все довольно просто. Распределили кубики, чуть сместили их и нарисовали…
2. Нормаль для каждого элемента:

// делаем цветные ячейки по количеству квадратиков
color cell = cellnoise(s * density + seed, t * density + seed);
// делаем нормаль для квадратика смещением нормали поверхности
Nf += normal ((comp(cell,0)-.5)*v_razbros, (comp(cell,1)-.5)*v_razbros, (comp(cell,2)-.5)*v_razbros);
3. Спекуляры
// считаем новый спекуляр
Nf = faceforward( normalize(Nf), I );
result = (specular(Nf, V, roughness) * pt) * flick_color;

Вот собственно и все, дорогие мои.

ps. Shader снега с блестками уже был выложен на сайте, но прочитав его я понял, что он не отрабатывает физическую модель, и как следствие всего лишь эмулирует эффект, и причем куда сложнее чем описано выше…
©Nikopol.VFX

Leave a Reply

*
To prove you're a person (not a spam script), type the security word shown in the picture.
Anti-Spam Image

Protected by WP-Hashcash.