The Book of Shaders by Patricio Gonzalez Vivo & Jen Lowe

日本語 - 中文版 - 한국어 - Español - Français - Italiano - Deutsch - Русский - English


Генеративный дизайн

Не удивительно, что после стольких повторений и порядка, автор вынужден привнести немного хаоса.

Беспорядок

Рёдзи Икеда - тестовый шаблон (2008)

Случайность есть сильнейшее проявление энтропии. Но как получить беспорядок в казалось бы предсказуемом и строгом программном окружении?

Давайте начнём со следующей функции:

Выше мы извлекаем дробную часть синусоиды. Таким образом, значения синуса, плавно изменяющиеся от -1.0 до 1.0, урезается до положительного диапазона от 0.0 до 1.0. Этот эффект можно использовать для получения псевдослучайных значений, разбивая синусоиду на меньшие кусочки. Как? Умножением значения синуса на большие числа. Попробуйте добавить нулей в функцию выше.

Когда коэффициент достигнет 100000.0 (то есть когда функция примет вид y = fract(sin(x)*100000.0)), волны синусоиды станут неразличимыми. Дискретность дробной части повредила плавное течение синусоидальной волны, превратив её в псевдослучайный хаос.

Управление хаосом

Использование беспорядка может стать непростой задачей. Он одновременно бывает слишком хаотичным и не слишком случайным. Посмотрите на следующий график. В нём мы используем функцию rand(), реализованную в точности как показано выше.

Присмотревшись, можно увидеть гребень синусоидальной волны в точках -1.5707 и 1.5707. Легко понять почему: именно в этих точках синус достигает максимума и минимума.

Так же при детальном рассмотрении видно, что значения больше концентрируются в середине, чем на краях полосы.

Некоторое время назад Pixelero опубликовал интересную статью о вероятностных распределениях. Я добавил несколько функций из неё в график выше, чтобы вы могли поиграться с ними и посмотреть как меняется распределение значений. Раскомментируйте функции и посмотрите что произойдёт.

Читая статью Pixelero, важно помнить, что функция rand() является детерминированной, или псевдослучайной. Это означает, что, к примеру, rand(1.) всегда возвращает одно и то же значение. Pixelero упоминает недетерминированную функцию Math.random() из ActionScript, которая каждый раз возвращает разные значения.

Двумерный беспорядок

Теперь у нас есть лучшее понимание беспорядка, и мы можем применить его в двумерном пространстве, к осям x и y одновременно. Для этого нам нужен способ преобразования двумерного вектора в одномерное значение с плавающей точкой. Можно придумать много способов сделать это, например использовать скалярное произведение (dot()). В коде ниже функция от скалярного произведения возвращает единственное число в диапазоне от 0.0 до 1.0 в зависимости от взаимного расположения векторов.

Обратите внимания на строки с 13 по 15, где vec2 st сравнивается с другим двумерным вектором vec2(12.9898,78.233).

Использование хаоса

Случайные значения в двумерном изображении выглядят как шум ненастроенного телевизора, не правда ли? Это слишком жёсткий и сырой материал для создания изображений. Давайте сделаем его более полезным.

В качестве первого шага применим к случайному шуму сетку. Используя функцию floor(), можно сгенерировать таблицу с целочисленным количеством клеток. Посмотрите на следующий код, особенно на строки 22 и 23.

После увеличения пространства в 10 раз (строка 21), мы отделяем целые части координат от дробных. Эта операция нам уже знакома по разбиению пространства на клетки, в каждой из которых координаты изменяются от 0.0 до 1.0. Извлекая целую часть координаты, мы получаем общее число для всех пикселей одной клетки. Далее мы можем использовать это целое число чтобы сгенерировать случайное число для всей клетки. Так как случайная функция детерминирована, это случайное число получится одинаковым для всех пикселей клетки.

Раскомментируйте строку 29, где мы используем сохранённую дробную часть координат пикселя в качестве нормированных координат внутри клетки.

Комбинация целой и дробной части координат позволяет смешивать порядок и изменчивость.

Посмотрите на GLSL-версию известного генератора лабиринтов 10 PRINT CHR$(205.5+RND(1)); : GOTO 10.

В нём используется случайное значение клетки для рисования линии в том или ином направлении с помощью функции truchetPattern() из предыдущей главы (строки с 41 по 47).

Раскомментируя строки с 50 по 53, можно получить ещё один интересный узор, а убрав комментарии со строк 35 и 36, вы увидите анимацию.

Мастер Беспорядка

Японский электронный музыкант и художник Рёдзи Икеда преуспел в использовании беспорядка. Сложно противостоять очарованию и гипнотизму его работ. Беспорядок особым образом вплетён в его работы: там он не создаёт раздражающий хаос, а отражает сложность нашей технологической культуры.

Посмотрите на работу Икеды и попробуйте выполнить следующее:

Сделать беспорядок эстетически привлекательным непросто, особенно если вы хотите делать симуляции, которые выглядят естественно. Беспорядок слишком хаотичен, и очень немногие из реальных вещей выглядят действительно случайно. Такие хаотичные вещи, как капли дождя или график биржевых котировок, не выглядят похожими на случайный рисунок, который мы делали вначале главы. В чём причина? Ну, случайные значения никак не коррелируют друг с другом, в то время как реальные вещи обычно «помнят» о своих предыдущих состояниях.

В следующей главе мы изучим шум. Это способ создания хаоса с помощью компьютера, который выглядит плавно и естественно.