Блестки на платье
Появилась задача – сделать платье с блестками для персонажа… Шейдер был сделан довольно быстро, но как показала практика он был далек от физической модели и как следствие смотрелся не очень…
Мой друг указал на ошибки и объяснил, почему появляются блики, и как следствие решение проблемы было сразу найдено и был написан шейдер бликов, а точнее 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