Мигание лампочек: автоматизация процесса
Урок этот для тех, кто работает во внешней рекламе, особенно для тех, кто занимается входными группами для игрового бизнеса и других развлекательных индустрий.
Лично мне, к примеру, надоело ручками на линейке проставлять ключики при мигании неона и лампочек.
Рассмотрим первый, самый простой, но довольно распространенный вариант. Две поочередно зажигающиеся и гаснущие лампочки.
Для начала разберем такую задачу:
Нам необходимо, чтобы в течении одной секунды сначала зажигалась первая лампочка (назовем ее Lamp1), потом она гасла и сразу зажигалась вторая лампочка (Lamp2), после чего к исходу текущей секунды эта лампочка гасла. Обратите внимание, что время, когда лампочка горит равно времени, когда лампочка не горит. Ну и конечно сделать этот процесс цикличным на любой отрезок времени.
Для этого нам нужно параметр Self-Illumination материала нашей лампочки прописать функцией, которая циклично менялась от 0% к 100%, причем не постепенно, а прыжками.
МИГАНИЕ ДВУХ ЛАМПОЧЕК.
В конце этой части мы увидим, как решать более универсальную задачу (произвольное изменение периода колебаний)
Разберем для начала одну лампочку, вторую пропишем по аналогии.
Итак, в Material Editor создаем материал (назовем его L1).
Вот настройки L1:
В Diffuse я забросил карту Falloff. Это не обязательно делать, но желательно. Для чего – увидите, когда будем рендерить «горящую» лампочку
В сцене нарисуем сферу и присвоим ей наш материал.
Зададим сфере имя Lamp1
В этом материале (L1) нас интересует параметр Self-Illumination.
Значение 0 соответствует не горящей лампочке, значение 100 – зажженной лампочке.
Для управления этим параметром воспользуемся такой замечательной вещью, как Curve Editor.
Сделаем это либо через пункт меню: Graph Editor/ Track View-Curve Editor
Либо гораздо проще: кликаем правой кнопкой в любом видовом окне и в контекстном меню выбираем Curve Editor.
Ну что же:) тут все как на ладони:)
В левой части окна все возможные параметры нашей сцены. Так что же нам мешает найти параметр Self-Illumination? Да ничего.
В левой части окна находим: Medit Material/ Имя нашего материала (в данном случае L1)/ Shader Basic Parameters/ Self-Illumination
Теперь, для того, чтобы мы могли задать какую-либо функцию параметру Self-Illumination, нам нужно проассоциировать этот параметр с контроллером Float Expression. Именно в этом контроллере мы сможем прописывать наши функции.
Для этого кликаем правой кнопкой мыши на параметре Self-Illumination в левой части Curve Editor, в контекстном меню выбираем команду Assign Controller, в появившемся окошке выбираем Float Expression, жмем ОК.
Перед Вами должно появится окно контроллера:
Для тех, кто впервые видит это окошко – не бойтесь, все будет просто:)
Настройте правую часть Curve Editor-а с помощью инструментов зума, так что бы по вертикали были видны значения 100 и -100.
Возвращаемся к окну Expression Controller.
Наши функции мы будем прописывать в области Expression.
По умолчанию там стоит значение 0. Давайте поменяем его на 1 и нажмем кнопку Evaluate (аналог кнопки «Применить» в стандартных виндовых окнах). Значение самосвечения подпрыгивает до 100%.
Для наглядности можете вызвать окно Material Editor и любоваться изменениями в нашем материале.
Вообще любое значение в области Expression меньшее либо равное нулю соответствует отсутствию самосвечения, а любое значение равное либо большее 1, будет соответствовать 100% самосвечения.
Давайте представим себе, как должны выглядеть графики этих двух лампочек в Curve Editor.
Т.е. в периоде между каждой N-ой и N+1-ой секундой в Curve Editor должны происходить вот такие колебания.
Осталось только написать функции, которые описывали бы эти графики.
«полуматематическим» языком график первой лампочки можно описать так:
Если текущее время в отрезке между N-ой и N+1-ой секундой меньше, чем половина этого периода (т.е. меньше чем 0,5), то значение функции = 1, иначе =0
Кое-кто уже догадался, к чему я веду:)
А веду я к употреблению условного оператора «Если».
В окне Expression Controller нажимаем на кнопочку Function List. Перед нами появляется список функций. Первая функция, которая нас интересует это if(c,t,f). По человечески это означает следующее: если выполняется условие C, тогда функция принимает значение T, иначе (если условие С не выполняется), функция принимает значение F.
Получаем следующее:
if(С,1,0),
где С - «текущее время в отрезке между N-ой и N+1-ой секундой меньше чем половина этого периода».
Теперь наше условие С нужно перевести на язык, который понимала бы машина.
По идее, нас интересует не сама N-я секунда, а значение времени между N-ой и N+1-ой секундой.
Для этого мы воспользуемся еще одной функцией из Function List: Floor(x).
Эта функция отсекает у Х значение после запятой. К примеру:
Floor(2,3)=2; Floor(5,7)=5; 12,6-Floor(12,6)=0,6
Используя Floor мы можем нашу функцию для первой лампочки привести к виду:
If (S-floor(S)<0.5,1,0)
Для второй соответственно:
If (S-floor(<0.5,0,1)
S – это «вшитое» в 3DMAXе значение, соответствующее текущей секунде.
С такими функциями наши лампочки будут совершат по одному поочередному колебанию в секунду.<
Изменение частоты колебаний
Допустим, нам необходимо сделать эти прыжки «горим-не_горим» в два раза чаще. Для этого просто достаточно S умножить на 2.
Для первой лампочки получаем:
If (S*2-floor(S*2)<0.5,1,0)
Для второй, соответственно:
If (S*2-floor(S*2)<0.5,0,1)
Для универсальности формулы в окне Expression Controller введем скалярную переменную, которая будет соответствовать частоте миганий в секунду. Назовем ее «А».
Теперь пошагово:
В окне Expression Controller в области Create Variables пишем название переменной, в нашем случае вписываем букву «А».
Проследите, чтобы справа был выбран вариант Scalar. Нажимаем кнопку Create. В области Scalars появится наша переменная.
Выделите ее, кликнув на ней левой кнопкой мыши, и задайте число колебаний в секунду, нажав на кнопку Assign to Constant и вписав необходимое число в появившемся окне (к примеру 2). Нажимаем ОК.
Нашу функцию заменяем на
If (S*А-floor(S*А)<0.5,1,0) для первой лампочки и
If (S*А-floor(S*А)<0.5,0,1) для второй.
Теперь с помощью Assign to Constant мы можем изменить переменную «А» на произвольное число.
Не забудьте «Эволюционировать», т.е. нажимать Evaluate. Ну и, конечно же, наслаждаться:)
Вот собственно и все, что касается мигания двух лампочек. Помните, что вы можете добавить к лампочкам Lens Effect/ Glow и добавить аналогичные функции в параметр Intensity. Да и вообще куда угодно.
Теперь давайте рассмотрим немного более сложный вариант.
ВОЛНА ИЗ ПЯТИ ЛАМПОЧЕК
Вот так выглядят графики для наших лампочек, функции на которые нам нужно написать.
На самом деле мы видим, что они практически не отличаются от предыдущего примера. Разница лишь в том, что переход происходит не в середине периода, а в определенной доле соответствующей определенной лампочке.
Так для первой лампочки момент включения происходит в 1/6-ой части от периода, для второй в 1/3-й и т.д.
Вывод прост:
Создаем 5 материалов. Проделываем все те же процессы, что и в предыдущем примере, только формула для первой лампочки будет:
If (S*А-floor(S*А)<1/6,0,1)
Для второй:
If (S*А-floor(S*А)<1/3,0,1)
…
Для пятой:
If (S*А-floor(S*А)<5/6,0,1)
Где (напоминаю):
S – это «вшитое» в 3DMAXе значение, соответствующее текущей секунде.
А – частота повторов периодов в секунду.
Если А=2, то за одну секунду пройдет две волны, если А=1/2, то одна волна пройдет за две секунды.
Теперь сделаем формулу более универсальной для N-ого количества лампочек.
Введем еще две скалярные переменные:
В – будет соответствовать числу, равному номеру зажигающейся лампочке (т.е. порядковому номеру лампочки, если лампочка должна зажечься третей, тогда В=3).
С - будет соответствовать общему количеству лампочек, т.е. С=N.
Получаем формулу:
If (S*А-floor(S*А)<В/(С+1),0,1)
Для М-ной лампочки из общего количества N лампочек переменные
В=М
С=N
И последний случай
ПООЧЕРЕДНОЕ ЗАЖИГАНИЕ ПЯТИ ЛАМПОЧЕК
Этот пример интересен тем, что период лампочки состоит из трех этапов: не горит, горит, не горит.
Итак, разберем, к примеру, вторую из пяти. В виде функции нам надо описать следующее:
Если текущее время в отрезке между N-ой и N+1-ой секундой больше чем 1/6, но меньше чем 1/3, то значение функции = 1, иначе =0
Исходя из всех примеров, которые были, хочется написать:
If(1/6<S*А-floor(S*А)<1/3,0,1)
Но, как я не пробовал, почему-то макс не хочет нормально воспринимать в качестве условия отрезок времени ограниченный с двух сторон.
Соответственно пришлось сделать двойной оператор «Если»:
if(1/6<A*S-floor(A*S),
if(A*S-floor(A*S)<1/3,1,0)
,0)
В переводе на русский это звучит примерно так:
Если текущее время в отрезке между N-ой и N+1-ой секундой больше чем 1/6, тогда:
Если текущее время в отрезке между N-ой и N+1-ой секундой меньше чем 1/3,тогда
значение функции = 1, иначе =0
, иначе =0
Я просто плачу, когда представляю, как вы это читаете:)
На самом деле ничего сложного, просто не спешите и внимательно читайте.
Попытайтесь понять то, что тут написано, а не проскочить побыстрее. Это не высшая математика, а элементарная логика:)
Ну, что ж… осталось только эту формулу сделать универсальной, для N-ого количества лампочек.
if((B-1)/C<A*S-floor(A*S),
if(A*S-floor(A*S)<B/C,1,0)
,0)
Где:
В –будет соответствовать числу равному номеру зажигающейся лампочке (т.е. порядковому номеру лампочки, если лампочка должна зажечься третей, тогда В=3).
С - будет соответствовать общему количеству лампочек, т.е. С=N.
Будьте внимательны, когда будете переписывать формулу – следите за знаками!
Кстати говоря, эта формула подходит и для первой, и для последней лампочки тоже.