Свои узлы CETN
Любой может сделать узел для CETN, пользоваться им сам и делиться ссылкой на патч. Лучшие узлы КОННЕКТ принимает в библиотеку сообщества, и тогда их видят все.
Как это устроено
- Свои узлы. В CETN откройте панель «Узлы», затем «Свои узлы», и загрузите файл узла или вставьте его текст. Узел появится в категории «Свои узлы».
- Ссылка на патч. Если в патче есть ваш узел, его описание едет внутри ссылки. У того, кто откроет ссылку, узел помечен как непроверенный, и шейдер запустится только после его нажатия.
- Библиотека сообщества. В «Своих узлах» нажмите «Подать в библиотеку». Решение о приёме принимает КОННЕКТ. Принятый узел попадает в категорию «Сообщество» для всех, с именем автора.
Почему без JavaScript
Узел описывается файлом JSON. Код внутри бывает двух видов, и оба не могут навредить человеку, который открыл ваш патч.
- Изображение (kind: "top"): код на GLSL. Он выполняется только на видеокарте и не видит страницу, данные, ключи и сеть.
- Сигналы (kind: "chop"): формулы вроде
sin(time * speed) * 0.5 + 0.5. Их разбирает сама CETN, без eval.
Страница CETN закрыта политикой безопасности (CSP): чужие скрипты не выполнятся, а данные не уйдут на посторонние адреса. Если видеокарта сбросится после запуска непроверенного шейдера, CETN снимет с него разрешение и предупредит.
Узел изображения
{
"format": "cetn-node/1",
"id": "ivan.kaleido",
"name": "Калейдоскоп Ивана",
"about": "Складывает кадр в калейдоскоп.",
"author": "Иван",
"version": "1.0.0",
"license": "MIT",
"kind": "top",
"inputs": [ { "id": "img", "name": "кадр", "type": "texture" } ],
"params": [
{ "id": "seg", "name": "грани", "min": 2, "max": 16, "step": 1, "value": 6 },
{ "id": "spin", "name": "вращение", "min": 0, "max": 1, "value": 0.1 }
],
"glsl": "void main(){ vec2 p = (uv - .5) * vec2(asp, 1.); float r = length(p), a = atan(p.y, p.x) + time * spin, s = 6.2832 / seg; a = abs(mod(a, s) - s * .5); o = vec4(texture(img, vec2(cos(a), sin(a)) * r / vec2(asp, 1.) + .5).rgb, 1.); }"
}
В коде доступны: uv (координата 0..1), o (результат, vec4), time, res (размер кадра), asp (ширина к высоте), шум ns(vec2) и fbm(vec2). Каждый вход texture это sampler2D с его id, каждый вход value и каждый параметр это float с его id. Объявлять их не нужно.
Узел сигналов
{
"format": "cetn-node/1",
"id": "ivan.pulse",
"name": "Пульс Ивана",
"kind": "chop",
"inputs": [ { "id": "gate", "name": "удар", "type": "value" } ],
"params": [ { "id": "decay", "name": "спад", "min": 0.5, "max": 0.99, "value": 0.9 } ],
"outputs": [ { "id": "v", "name": "выход" } ],
"expr": { "v": "gate > 0.5 ? 1 : v * decay" }
}
В формуле доступны входы, параметры, прежние значения выходов (для сглаживания и счётчиков), time, dt, frame, pi. Знаки: + - * / % ^, сравнения, && || !, условие ? да : нет. Функции: sin, cos, tan, asin, acos, atan, atan2, abs, sign, floor, ceil, round, fract, sqrt, exp, log, pow, min, max, clamp, mix, step, smoothstep, mod, noise, rand.
Правила
| Размер | файл до 32 КБ, код GLSL до 16 000 символов, формула до 400 символов |
| id узла | 3-40 символов: латиница в нижнем регистре, цифры, точка, дефис. Удобно «ник.название». |
| id входов и параметров | латиница, до 16 символов, не слова GLSL и не служебные имена (uv, o, time, res, asp) |
| Количество | до 4 входов texture, до 8 входов value, до 16 параметров, до 8 выходов |
| GLSL | только ASCII, без директив #, без циклов while и do, без layout. Результат пишите в o. |
| Тексты | название до 32 символов, описание до 140, без управляющих символов |
Каждый параметр узла можно вести сигналом из других узлов, как в TouchDesigner: вход появится сам.
Подача в библиотеку
- Загрузите узел в «Свои узлы» и проверьте его в патче.
- Нажмите «Подать в библиотеку», оставьте Telegram или почту, если хотите получить ответ.
- КОННЕКТ посмотрит узел и решит, принять ли его. Принятый узел появится у всех в категории «Сообщество».
Не больше 5 подач в час с одного адреса.