|
|
|
|
## Патерни
|
|
|
|
|
|
|
|
|
|
Шейдерні програми виконуються попіксельно, тому незалежно від того скільки ви повторюєте якусь фігуру, кількість обчислень залишається незмінною. Це означає, що фрагментні шейдери добре підходять для створення патернів — візерунків, що повторюються.
|
|
|
|
|
|
|
|
|
|
[![Nina Warmerdam - The IMPRINT Project (2013)](warmerdam.jpg)](../edit.php#09/dots5.frag)
|
|
|
|
|
|
|
|
|
|
У цьому розділі ми збираємося застосувати дещо з попереднього матеріалу, щоб продублювати його кілька разів на полотні. Як і в попередніх розділах, наша стратегія базуватиметься на перемноженні просторових координат з діапазоном від 0.0 до 1.0, так щоб фігури, які ми малюватимемо між значеннями 0.0 та 1.0, повторювалися, утворюючи сітку.
|
|
|
|
|
|
|
|
|
|
*"Сітка забезпечує структуру, в межах якої людській інтуїції та винахідливості зручно орієнтуватись. У хаосі природи візерунки створюють контраст і обіцяють порядок. Від ранніх візерунків на кераміці до геометричної мозаїки в римських лазнях люди давно використовують сітки, щоб прикрасити своє життя за допомогою декору."* [*10 PRINT*, Mit Press, (2013)](http://10print.org/)
|
|
|
|
|
|
|
|
|
|
Спочатку згадаймо функцію [```fract()```](../glossary/?lan=ua&search=fract). Вона повертає дробову частину числа, роблячи ```fract()``` модулем одиниці ([```mod(x,1.0)```](../glossary/?lan=ua&search=mod)). Іншими словами, [```fract()```](../glossary/?lan=ua&search=fract) повертає число після коми з рухомою крапкою. Наша змінна з нормалізованою системою координат (```st```) уже змінюється в межах діапазону від 0.0 до 1.0, тому немає сенсу робити щось на наступний зразок:
|
|
|
|
|
|
|
|
|
|
```glsl
|
|
|
|
|
void main() {
|
|
|
|
|
vec2 st = gl_FragCoord.xy / u_resolution;
|
|
|
|
|
vec3 color = vec3(0.0);
|
|
|
|
|
st = fract(st);
|
|
|
|
|
color = vec3(st, 0.0);
|
|
|
|
|
gl_FragColor = vec4(color, 1.0);
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Але якщо ми збільшимо масштаб нормалізованої системи координат, скажімо, втричі до 3.0, то отримаємо три послідовності лінійної інтерполяції одиничного розміру. Перша між 0.0 та 1.0, друга між 1.0 та 2.0 й третя між 2.0 та 3.0.
|
|
|
|
|
|
|
|
|
|
<div class="codeAndCanvas" data="grid-making.frag"></div>
|
|
|
|
|
|
|
|
|
|
Настав час намалювати щось у кожному підпросторі, розкоментувавши рядок 27. Оскільки обидві вісі x та y помножуються на однакове значення, то співвідношення сторін простору не змінюється. Відповідно форми також не матимуть викривлень та будуть такими, як очікувалося.
|
|
|
|
|
|
|
|
|
|
Для глибшого розуміння, спробуйте виконати деякі з наведених нижче вправ:
|
|
|
|
|
|
|
|
|
|
* Помножте просторові координати на різні числа. Спробуйте різні значення з рухомою крапкою, а також різні значення для x та y.
|
|
|
|
|
|
|
|
|
|
* Зробіть, для цього трюку з плиткою, функцію для повторного використання.
|
|
|
|
|
|
|
|
|
|
* Розділіть простір на 3 рядки та 3 стовпці. Знайдіть спосіб дізнатися, у якому стовпці та рядку знаходиться потік, і в залежності від цього змінити фігуру, що буде малюватися. Спробуйте зробити композицію з гри у хрестики-нулики.
|
|
|
|
|
|
|
|
|
|
### Застосування матриць всередині патернів
|
|
|
|
|
|
|
|
|
|
Оскільки кожен підрозділ або комірка є зменшеною версією нормалізованої системи координат, яку ми використовували раніше, ми можемо застосувати до них такі ж самі матричні перетворення для переміщення, обертання та масштабування.
|
|
|
|
|
|
|
|
|
|
<div class="codeAndCanvas" data="checks.frag"></div>
|
|
|
|
|
|
|
|
|
|
* Подумайте про цікаві способи анімації цього візерунка. Подумайте про анімацію кольорів, форм і рухів. Зробіть три різні анімації.
|
|
|
|
|
|
|
|
|
|
* Відтворіть складніші візерунки, компонуючи різні форми.
|
|
|
|
|
|
|
|
|
|
[![](diamondtiles-long.png)](../edit.php#09/diamondtiles.frag)
|
|
|
|
|
|
|
|
|
|
* Комбінуйте різні шари патернів, щоб створити власні [орнаменти шотландського тартану](https://www.google.com/search?q=scottish+patterns+fabric&tbm=isch&tbo=u&source=univ&sa=X&ei=Y1aFVfmfD9P-yQTLuYCIDA&ved=0CB4QsAQ&biw=1399&bih=799#tbm=isch&q=Scottish+Tartans+Patterns).
|
|
|
|
|
|
|
|
|
|
[![Векторний візерунок шотландського тартану від Kavalenkava](tartan.jpg) ](http://graphicriver.net/item/vector-pattern-scottish-tartan/6590076)
|
|
|
|
|
|
|
|
|
|
### Патерни зі зміщенням
|
|
|
|
|
|
|
|
|
|
Припустимо, ми хочемо імітувати цегляну стіну. Розглядаючи стіну, ви можете побачити, що кожен другий її ряд зміщений на півцеглини по вісі x. Як можна це зробити?
|
|
|
|
|
|
|
|
|
|
![](brick.jpg)
|
|
|
|
|
|
|
|
|
|
Першим кроком потрібно визначити, чи є потік поточного рядка парним чи непарним, що дасть нам розуміння чи потрібно робити зміщення у цьому рядку. Для цього ми використаємо функцію модуля [```mod()```](../glossary/?lan=ua&search=mod) зі значенням ```2.0``` для другого параметру, а потім перевіримо, чи результат буде меншим від ``` 1.0``` чи ні. Подивіться на наступну формулу та розкоментуйте два останні рядки.
|
|
|
|
|
|
|
|
|
|
<div class="simpleFunction" data="y = mod(x, 2.0);
|
|
|
|
|
// y = mod(x, 2.0) < 1.0 ? 0. : 1. ;
|
|
|
|
|
// y = step(1.0, mod(x, 2.0));"></div>
|
|
|
|
|
|
|
|
|
|
Як бачите, ми можемо використати [тернарний оператор](https://en.wikipedia.org/wiki/%3F:), щоб перевірити, чи остача від ділення по модулю [```mod()```](../glossary/?lan=ua&search=mod) на ```2.0``` менше за ```1.0```, що означатиме другий рядок. Або ми можемо аналогічно використати функцію [```step()```](../glossary/?lan=ua&search=step), яка виконає ту саму операцію, але швидше. Чому? Хоча важко напевно знати, як кожна графічна карта оптимізує та компілює код, але можна з упевненістю припустити, що вбудовані функції працюють швидше. За кожної можливості надавайте перевагу використанню вбудованих функцій!
|
|
|
|
|
|
|
|
|
|
Тепер, маючи формулу визначення непарних чисел, ми можемо застосувати зміщення до непарних рядків, щоб надати нашим плиткам *ефект цегли*. У рядку 14 наступного коду ми використовуємо функцію для "виявлення" непарних рядків та зсуваємо їх на половину одиниці по вісі ```x```. Зауважте, що для парних рядків результатом нашої функції буде ```0.0```, що при множенні на значення для зміщення в ```0.5``` залишається тим самим ```0.0```. Але в непарних рядках ми отримуємо результат нашої функції як ```1.0```, що при множенні на зсув ```0.5```, переміщує вісь ```x``` системи координат на ```0.5```.
|
|
|
|
|
|
|
|
|
|
Тепер спробуйте розкоментувати рядок 32 — це розтягне співвідношення сторін системи координат, щоб імітувати її до співвідношення "сучасної цегли". Розкоментувавши рядок 40, ви зможете побачити, як виглядає система координат, відображена у червоний та зелений кольори.
|
|
|
|
|
|
|
|
|
|
<div class="codeAndCanvas" data="bricks.frag"></div>
|
|
|
|
|
|
|
|
|
|
* Спробуйте анімувати цей приклад, змінюючи зміщення відповідно до часу.
|
|
|
|
|
|
|
|
|
|
* Зробіть ще одну анімацію, у якій парні ряди рухаються ліворуч, а непарні — праворуч.
|
|
|
|
|
|
|
|
|
|
* Чи можете ви повторити цей ефект, але зі стовпцями?
|
|
|
|
|
|
|
|
|
|
* Спробуйте скомбінувати зсуви на вісі ```x``` та ```y```, щоб отримати щось на зразок наступного:
|
|
|
|
|
|
|
|
|
|
<a href="../edit.php#09/marching_dots.frag"><canvas id="custom" class="canvas" data-fragment-url="marching_dots.frag" width="520px" height="200px"></canvas></a>
|
|
|
|
|
|
|
|
|
|
## Плитка Труше
|
|
|
|
|
|
|
|
|
|
Тепер, коли ми навчилися визначати, чи знаходиться наша комірка в парному чи непарному рядку чи стовпці, можна повторно використовувати один елемент дизайну залежно від його положення. Розглянемо випадок [плитки Труше](http://en.wikipedia.org/wiki/Truchet_tiles), де один елемент дизайну може бути представлено чотирма різними способами:
|
|
|
|
|
|
|
|
|
|
![](truchet-00.png)
|
|
|
|
|
|
|
|
|
|
Змінюючи малюнок у плитках, можна побудувати нескінченний набір складних зображень.
|
|
|
|
|
|
|
|
|
|
![](truchet-01.png)
|
|
|
|
|
|
|
|
|
|
Зверніть увагу на функцію ```rotateTilePattern()```, яка розбиває простір на чотири комірки та призначає кожній кут повороту.
|
|
|
|
|
|
|
|
|
|
<div class="codeAndCanvas" data="truchet.frag"></div>
|
|
|
|
|
|
|
|
|
|
* Закоментуйте, розкоментуйте та продублюйте рядки з 69 по 72, щоб скомпонувати нові зображення.
|
|
|
|
|
|
|
|
|
|
* Змініть чорно-білий трикутник на інший елемент, наприклад: півколо, повернуті квадрати або лінії.
|
|
|
|
|
|
|
|
|
|
* Запрограмуйте інші патерни, де елементи обернені відповідно до їхнього положення.
|
|
|
|
|
|
|
|
|
|
* Створіть патерн, який змінює інші свої властивості відповідно до положення елементів.
|
|
|
|
|
|
|
|
|
|
* Подумайте про щось інше, не обов'язково про патерни, де ви можете застосувати принципи з цього розділу. Наприклад, [гексаграми "I Ching"](https://en.wikipedia.org/wiki/Hexagram_(I_Ching)):
|
|
|
|
|
|
|
|
|
|
<a href="../edit.php#09/iching-01.frag"><canvas id="custom" class="canvas" data-fragment-url="iching-01.frag" width="520px" height="200px"></canvas></a>
|
|
|
|
|
|
|
|
|
|
## Створення власних правил
|
|
|
|
|
|
|
|
|
|
Створення процедурних патернів — це розумова вправа з пошуку мінімальної кількості елементів для багаторазово використання в просторі. Ця давня практика. Ми, як біологічний вид, використовуємо сітки та візерунки для декорування текстилю, підлоги та границь об'єктів протягом тривалого часу: від візерунків декоративних звивистих ліній (меандрів) стародавньої Греції до китайських решітчастих патернів. Насолода від повторення та варіацій захоплює нашу уяву. Знайдіть час, щоб переглянути [декоративні](https://archive.org/stream/traditionalmetho00chririch#page/130/mode/2up) [візерунки](https://www.pinterest.com/patriciogonzv/paterns/) та подивитися як художники з дизайнерами балансуються між передбачуваністю порядку й несподіваністю варіацій та хаосу. Від арабських геометричних візерунків до розкішних африканських зображень на тканинах пролягає цілий всесвіт візерунків для натхнення та пізнання.
|
|
|
|
|
|
|
|
|
|
[![Franz Sales Meyer - A handbook of ornament (1920)](geometricpatters.png)](https://archive.org/details/handbookoforname00meyeuoft/page/10/mode/2up)
|
|
|
|
|
|
|
|
|
|
Цією главою ми закінчуємо розділ про алгоритмічне малювання. У наступних розділах ми дізнаємося, як привносити у наші шейдери трохи ентропії та створювати генеративні дизайни.
|