3D Engineering

...Лучшее из общего.

  • Увеличить размер шрифта
  • Размер шрифта по умолчанию
  • Уменьшить размер шрифта

Здравствуйте уважаемые читатели и гости 3dgo

Здравствуйте, уважаемые читатели и гости 3dgo.ru. Сегодня у нас в гостях очень талантливый и интересный художник, удостоенный награды Award в Художественной галерее 3dgo.ru – Влад Константинов (Swordlord). В данном интервью, Влад расскажет о себе, о своем пути в мире компьютерной графики, поделится опытом в создании и реконструкций древнего животного мира, а так же своими планами на будущее.

3dgo.ru: Здравствуйте, Влад. Благодарим Вас за интервью для нашего on-line журнала. Вначале расскажите о себе. Где Вы живете, какой ВУЗ Вы закончили? Вы учились в двух художественных школах, помогают ли Вам полученные знания в реализации Ваших идей?

Swordlord: Здравствуйте! Сейчас мне 23 (почти 24) года. Я живу в Рязани. Здесь родился, окончил школу и получил высшее образование. Обучался в Рязанском Государственном Радиотехническом Университете по специальности "Системы автоматизированного проектирования вычислительных средств" (САПР ВС). Что касается художественных школ, то я в них занимался, в основном, по настоянию родителей, т.к. сам особого рвения не испытывал и успехов не проявлял. Но, тем не менее, я очень рад, что меня заставили закончить обучение. Не то, чтобы эти знания и навыки мне когда-нибудь пригодились, но кто знает, как бы сложилась моя жизнь, если бы в прошлом я бросил заниматься творчеством. Да и очередная корочка никогда не бывает лишней.

3dgo.ru: Сейчас Вы учитесь в аспирантуре, расскажите о Вашей специальности и текущей работе в институте. Занимаетесь ли научной деятельностью в области высоких технологий и компьютерной графики?

Swordlord: В данный момент я на втором году обучения в аспирантуре того же ВУЗа. Моя специальность напрямую связана с компьютерной графикой и анимацией, а диссертация посвящена динозаврам (кто бы сомневался!). Текущая деятельность состоит в основном из написания научной работы, создания различных публикаций (в основном по Maya) и занятий со студентами.

3dgo.ru: Что дало толчок к Вашему знакомству с компьютерной графикой и визуализацией? Когда это произошло? Было ли сложно с нуля осваивать такую область, как CG и анимация?

Swordlord: В начальной школе я основательно заболел палеонтологией, постоянно рисовал в тетрадках всяких Годзилл, и неудивительно, что моими любимыми фильмами тогда были "Парк Юрского Периода 1-2". Позже к ним добавился еще и анимационный фильм "Динозавр" студии Дисней. Когда я узнал, что животные в этих картинах были созданы с помощью 3Д-графики, это поразило меня, и мне показалась просто замечательной идея иметь на своем компьютере какую-нибудь модель динозавра, которую можно попробовать "оживить", заставить двигаться, дышать, бегать и прыгать... Эта мысль поглотила меня целиком и где-то в классе в 10-м, благодаря своему другу (ныне фотографу), я познакомился с компьютерной графикой. Для меня открылся целый новый мир, который, пожалуй, можно было описать всего одним словом - "свобода". Ведь в 3Д можно создать практически все что угодно! С того момента мы с другом основательно занялись изучением 3ds max (тогда еще 4-й версии). Осваивать ПО было сложно, т.к. интернет в то время был еще не у всех (да и в нем информации было мало), а редкие книги, которые нам удавалось отвоевать в магазинах, по большей части, не имели внутри себя ничего, кроме описания интерфейса. Но вся сложность целиком и полностью компенсировалась интересом и новыми возможностями, которые предоставляла CG.

3dgo.ru: Опыт в компьютерной графике Вы получали самостоятельно, или устроились на работу и Вам удалось получить опыт в коллективе, работая над различными проектами?

Swordlord: Пожалуй, с самого первого запуска программы я понял, что хочу заниматься компьютерной графикой не только для самовыражения. Я четко осознал, что хочу стать профессиональным CG-художником и зарабатывать этим себе на жизнь, и поэтому я постоянно искал возможность применить свои навыки в деле. Таким образом, первый раз я устроился на работу дизайнером в возрасте 16-лет. Сейчас смешно вспоминать, но устраивались мы вместе с другом на одно место на зарплату в 2 т.р. на двоих! Само собой, ничего хорошего из этого не получилось. Следующую серьезную попытку я предпринял, будучи студентом первого курса, в 18 лет. Мне повезло попасть на место 3д-дизайнера в одном из наших городских рекламных агентств, за что огромное спасибо директору Корнеевой Надежде, которая поверила в меня, тогда еще неопытного студента и без нормального портфолио. Она многому меня научила и отнеслась ко мне с поразительной терпимостью, позволяя мне параллельно получать образование. В том агентстве я проработал чуть меньше 5 лет (почти все 5 курсов университета), занимался в основном визуализацией интерьеров и экстерьеров, принял участие в создании многих магазинов и торговых центров по всей России. Именно в этом время я получил основные знания в области CG. Было очень сложно совмещать работу и учебу в одном из самых престижных ВУЗов города, но все, же я справился.

Пока я работал в агентстве и учился, мне удавалось находить время для создания различных персонажей для себя и для портфолио. Примерно к 4-му курсу сбылась моя мечта, и я начал получать редкие сторонние заказы на персонажку. Сначала мне удавалось выполнять их параллельно с основной работой, но со временем клиентов становилось все больше, и где-то в районе периода сдачи дипломной работы я твердо понял, что за двумя зайцами не угонишься, и окончательно перешел на фриланс. И приблизительно в это же время мне удалось получить свой первый опыт в киноиндустрии. Это было просто незабываемо, т.к. я всю свою жизнь мечтал о кино. С того времени мне удалось выполнить еще множество очень интересных заказов из разных сфер: кино, игры, полиграфия... - и я познакомился со многими известными и чрезвычайно одаренными людьми, среди которых были даже работники ведущих студий мира, таких как ILM, Disney, Sony Pictures. Основная сфера моей деятельности - это создание работ на палеонтологическую тематику или близкую ей, но конечно я не ограничиваюсь только этим. Сейчас я, в основном, работаю больше с зарубежными клиентами.

3dgo.ru: Влад, Вы известны, в первую очередь, своими работами, посвященными реконструкции доисторического животного мира. Расскажите о своем увлечении этим загадочным и до сих пор малоизученным миром. Для создания своих работ Вы консультируетесь со специалистами-палеонтологами?

Swordlord: Да, как бы я ни хотел выглядеть разносторонне развитым человеком, первое, что я слышу во время нового знакомства - это «Эй! ты тот парень, который динозавра сделал?». Ничего не поделаешь, я вынужден признать, что динозавры и другие вымершие животные - одно из моих самых главных увлечений. Мир, исчезнувший десятки миллионов лет назад, просто не может не потрясать человеческое воображение. Мы все любим смотреть на различных монстров и необычных чудовищ в фильмах, но ведь, если подумать, то далеко ходить не надо. Подобные неведомые, загадочные и величественные существа, когда-то на самом деле обитали на нашей планете. Это великолепное ощущение - представлять мир таким, какой он был до существования человека, думать о нем, мечтать. Здесь лежит огромный простор для фантазии и для вдохновения. И я считаю, что наиболее полноценно оживить ту эпоху можно только с помощью компьютерной графики.

Задачей палеоиллюстратора является максимально правдоподобное восстановление облика тех исчезнувших созданий, и, разумеется, для этого нужны специальные знания в области анатомии, биологии, экологии и многого-многого другого. Я далеко не профессионал этих областях, поэтому я был вынужден зарегистрироваться на палеонтологическом форуме, где я узнал многих очень хороших и компетентных людей, которые до сих пор помогают мне в создании моих работ и снабжают нужной информацией. Кроме того, иногда мне удается пообщаться с зарубежными известными специалистами.

3dgo.ru: Расскажите о Вашей первой работе, связанной с воссозданием динозавра. Вы изначально подготовили всю информацию и материалы для работы? С какими сложностями Вам пришлось столкнуться при создании первой работы?

Swordlord: Своего первого законченного динозавра я создавал с огромными трудностями. Фактически, это была первая моя более-менее приличная модель персонажа, я имел скудный багаж знаний, и у меня не было практически никакого опыта в создании органических 3Д-моделей. Разумеется, мне пришлось пройти через все этапы: моделирование, развертка, скульптинг, текстуринг, шейдинг, освещение, рендер и пост. Когда брался за ту модель, я "со скрипом" знал лишь Max, но, после окончания работы над динозавром, я уже мог похвастаться умением работать с ZBrush, Photoshop, Brazil, V-ray, Unfold 3d. Тогда еще не на профессиональном уровне, кончено, но уже более-менее уверенно. Эта работа дала мне очень многое - знания, уверенность в себе, терпение... Поскольку мне приходилось осваивать все инструменты на ходу, создание финального изображения заняло у меня очень много времени - почти полтора года, с учетом фона (хотя конечно были небольшие перерывы). Лишь врожденное упорство помогло мне не бросить картинку на полпути и не халтурить, стараясь получить именно такой результат, какой я хотел. В итоге я был вознагражден за свое терпение сразу несколькими Авардами на разных сайтах, в том числе и на Рендер.ру. Ну и, разумеется, я многим обязан людям, которые помогали мне в моем ВИПе на 3DCenter, на палеонтологическом форуме и просто через ICQ.

Изначально я не планировал делать реконструкцию динозавра. Я просто хотел получить красивого и запоминающегося стилизованного Ти-Рекса. Но во время работы я сильно втянулся и понял, что, на самом деле, создать правдоподобную модель вымершего животного - задача намного сложнее и интереснее. Теперь это не только мое хобби, но и работа. Если бы кто-то сказал мне года 3 назад, что я буду зарабатывать на динозаврах, я бы сильно рассмеялся.

3dgo.ru: Сейчас создание моделей доисторических ящеров является практически основной Вашей деятельностью. Расскажите, пожалуйста, что именно Вам приходится делать по работе? Какие обычно заказы Вам приходится выполнять?

Swordlord: На самом деле, палеонтологическая тематика (в частности динозавры) достаточно популярна, и может найти применение практически везде: в кино, в полиграфии и книжных изданиях, в рекламе, в играх... В данный момент, например, я работаю над созданием иллюстраций для японского палеонтологического журнала.

3dgo.ru: Какие из Ваших проектов были для Вас наиболее значимыми?

Swordlord: Безусловно, на данный момент я больше всего горжусь тем, что с лета прошлого года я принимаю участие в создании научно-популярного фильма для канала Discovery. Это был бесценный опыт для меня! В процессе работы я познакомился со многими известными людьми, некоторые из которых, до этого числились в списке моих кумиров (и, разумеется, числятся там до сих пор). К сожалению, согласно условиям контракта, я не имею права подробно рассказывать про этот проект, а свои работы смогу продемонстрировать только после премьеры.

Так же, наверное, я могу выделить серию тетрадей питерской компании "Polynom" с моими динозаврами на обложках. На обратной стороне заказчик даже согласился разместить мое имя и контактные данные, за что я ему очень благодарен. Сейчас эти тетради как раз поступили в магазины моего города, и я, время от времени, хожу на них посмотреть и купить парочку.

3dgo.ru: Вы также работаете над частным небольшим проектом совместно с администратором Художественной галереи 3dgo.ru, Skif'ом. Расскажите, пожалуйста, об этом проекте. Когда стоит ожидать первой детальной информации о нем и уже первых готовых материалов?

Swordlord: Да, мы сейчас работаем над проектом под рабочим названием "Last hunt" (http://www.last-hunt.blogspot.com/). Кроме меня и Скифа, в нем заняты еще несколько человек. Основная идея ролика состоит в том, чтобы столкнуть лбами двух величайших охотников всех времен: человека и тираннозавра. Видео, в основном, будет служить испытательным полигоном для нашего небольшого коллектива и демонстрацией наших возможностей (хотя у нас есть пара идей о том, как развить его в более серьезный проект).

Тестовая анимация.

К огромному нашему сожалению, ролик некоммерческий, и, следовательно, мы не можем уделять ему достаточно времени и соблюдать какие-то четкие сроки, т.к. всем нам приходится зарабатывать себе на жизнь. Например, в последнее время лично мне приходится работать по 16-17 часов в сутки, чтобы не подводить своих заказчиков, и я при всем желании не могу уделять время нашему ролику. Временами похожие ситуации случаются и у других членов нашей команды. Но мы не собираемся оставлять нашу идею и будем продолжать.

Снаряжение Тираннозавра созданное skif'ом.

3dgo.ru: Учитывая что Вы очень хорошо знаете тему доисторических животных, стараетесь ли помогать пользователям, кто так же хочет начать создавать модели динозавров и других животных?

Swordlord: Да, если кто-то на форуме 3dgo.ru создает тему с динозаврами, то сразу несколько человек зовут меня. Я обязательно стараюсь отписываться в каждой такой теме и помогать советами или референсами. Наверное, я даже поднадоел со своими замечаниями.

3dgo.ru: Влад, Вы также являетесь модератором форума Dominance Ware V на 3dgo.ru. Расскажите о том, как Вы познакомились с организаторами конкурса, как сейчас обстоят дела с конкурсом? Была информация о том, что конкурс на данный момент приостановлен, правда ли это?

Swordlord: Скиф, Администратор галереи на 3dgo.ru и мой очень хороший друг, как-то обмолвился, что им на сайте нужен хороший тридешник со знанием английского языка для проведения DW. И, поскольку Администрация ресурса нередко очень помогала мне, я решил не оставаться в долгу и выставил свою кандидатуру. Затем меня наделили соответствующими модераторскими полномочиями, и я вышел на Фреда (организатора конкурса), чтобы зарегистрировать команду от нашего форума. К сожалению, мероприятие в этом году проходит в сопровождении целого ряда проблем и одно время даже находилось под угрозой срыва из-за неприятностей у Фреда. Но в данный момент вроде бы все стабилизируется, и конкурс обещает состояться, хотя и со значительными изменениями. Не могу утверждать что-то в данной ситуации, но я надеюсь, что все будет в порядке.

3dgo.ru: Влад, расскажите о своих планах на будущее. Какие идеи Вы хотите реализовать в ближайшее время или повысить свое мастерство, в каких-то областях CG?

Swordlord: Если говорить о CG, то, в первую очередь, мне бы хотелось как следует освоить визуализацию (рендеринг, шейдинг, освещение). Сейчас это самая слабая моя сторона. Так же очень хочется научиться делать качественный риг и основательно заняться анимацией. Ну и знания композитинга тоже были бы не лишними.  Словом, хочется уметь делать все на одинаково хорошем уровне. Помимо этого, я мечтаю развить навыки в традиционном искусстве (рисование, скульптура), 2Д и в режиссуре.

А что касается жизненных планов, то моя главная цель - переезд в США. Мечтаю работать над крупными проектами с известными людьми. Да, конечно все это звучит смешно и наивно, но я постараюсь приложить к этому все свои силы.

3dgo.ru: У многих художников компьютерной графики есть свои кумиры. Расскажите о художниках, работы которых Вам нравятся, стараетесь ли брать с них пример?

Swordlord: Да, разумеется, если мне нравится какая-то работа или какой-то художник, то я стараюсь их тщательно изучать и находить для себя что-то новое. Есть множество людей, чье творчество меня привлекает. Сложно перечислить всех, не упустив кого-либо. Kagaya, Olivier Ponsonnet, Alessandro Baldasseroni, Stefan Morrell, Massimo Righi, Marek Denko, Grant Warwick, David Krentz, Raul Martin и многие-многие другие.

3dgo.ru: Влад, напоследок, расскажите о своих увлечениях помимо дизайна и визуализации. Вы занимались ранее историческим фехтованием, расскажите подробней об этом. Продолжаете ли сейчас заниматься фехтованием?

Swordlord: Историческим фехтованием я занимался довольно долго. Это очень интересный и красивый вид спорта, который сейчас активно развивается не только в нашей стране. За время, которое мне удалось посвятить этому увлечению, я познакомился с большим количеством интересных людей, узнал много нового, поработал в мастерской над изготовлением доспехов и даже получил кое-какой опыт тренерской работы. К сожалению, в один момент я оказался перед выбором: работа или увлечение, т.к. фриланс практически не оставляет времени для регулярных занятий чем-либо. Пришлось прекратить занятия фехтованием, о чем я, конечно, периодически жалею.
Помимо этого, я люблю кино, обожаю читать книги, мне нравится путешествовать. Недавно купил неплохой фотоаппарат для текстур и фонов и понял, что хотелось бы заняться так же и фотографией. Ну вот, это если вкратце.

3dgo.ru: С каждым годом все больше людей стараются связать свою жизнь с цифровым искусством. Что Вы можете посоветовать начинающим дизайнерам и художникам? Стоит ли держаться цели и стараться добиваться её всеми силами?

Swordlord: В первую очередь, я бы посоветовал запасаться терпением. Без этого качества добиться больших успехов вряд ли у кого получится. И самое главное - нужно стараться всегда добиваться поставленной цели и не останавливаться на полпути.

3dgo.ru: Влад, благодарим Вас за интересную беседу. Редакция 3dgo.ru желает Вам неиссякаемого вдохновения, успехов в творчестве и во всех Ваших начинаниях, и с нетерпением ждем Ваши новые работы в галерее 3dgo.ru.

Swordlord: Спасибо! А я, в свою очередь, благодарю редакцию 3dgo.ru за это интервью. Очень надеюсь, что оно получилось интересным для пользователей. Всем удачи и спасибо за внимание!

 

Архив статей

 дек   Январь 2020   фев

ВПВСЧПС
   1  2  3  4
  5  6  7  8  91011
12131415161718
19202122232425
262728293031 
Julianna Walker Willis Technology

Случайная новость

Почти все видели стерео картинки, я, например, помню в школе у нас были тетрадки, на обложке которых были напечатаны непонятные каракули. Но если посмотреть на них «правильно» - эти каракули обретали объем. Не у всех получалось увидеть их сразу, кому это было просто, а кто так и не смог. Есть несколько рекомендаций как достигнуть иллюзию объема: смотреть «сквозь» картинку или приложить ее вплотную к носу и медленно отводить.

Немного теории.

Как человек воспринимает объем?  Чем ближе расположен рассматриваемый объект, тем больше наблюдатель «сводит» глаза. Т.о. если рассматриваемый объект расположен на бесконечно удаленном расстоянии, то глаза будут смотреть на него «параллельно».

Рис.1

Теперь рассмотрим как достигнуть иллюзию объема на плоской картинке. Итак, у нас имеется человек с двумя глазами (рис.1): левый глаз O1 и правый O2,а так же плоскость проекции стерео изображения D1D2. Пусть рассматриваемый объект B расположен на расстоянии h от наблюдателя. Тогда для того чтоб «увидеть» его на картинке необходимо совпадение рисунка в точках B1 и B2. Получается мы держим перед собой плоский рисунок и смотрим как бы «сквозь» него. Левый глаз видит точку B1, правый B2, изображения для них на листе совпадают и создается иллюзия того, что на самом деле мы видим объект B, расположенный за плоскостью листа. Т.о. чем больше расстояние между точками B1 и B2,в которых совпадает изображение, тем «дальше» воспринимается объект B.

Теперь выведем пару расчетных формул, которые пригодятся для просчета стерео изображения. Пусть a – расстояние между глазами, H – расстояние до максимально удаленного объекта, h – расстояние до объекта h_max – расстояние от максимально удаленного объекта до плоскости проекции стерео изображения. Из подобия треугольников BB1B2 и BO1O2 следует B1B2/BE= O1O2/BF. B1B2=d , O1O2=a, BF=h, BE=BF-EF, EF=AF-AE=H-h_max, BE=h-(H-h_max). Итого d/(h-H+h_max))=a/h.

Пожалуй теории пока достаточно, можно перейти к практике. Для этого понадобится Photoshop и 3dsMAX. В Photoshop’е создадим текстуру, из которой в последствии будет построено стерео изображение. Несколько рекомендаций: чем больше на текстуре деталей, тем лучше получиться окончательный вариант (с однотонными вообще ничего не получиться); высота текстуры должна совпадать с высотой изображения (поэтому сразу надо определить размер финального стерео изображения); а ширина зависит от того, где вы собираетесь в дальнейшем использовать полученную картинку. На рис.1 величина d_max как раз соответствует ширине текстуры, поэтому в реальности (на экране монитора или после распечатки) она не должна превышать расстояния между глазами a. В тоже время чем больше пикселей по ширине будет в исходной текстуре, тем более качественным получиться окончательный результат. У меня получилась вот такая текстура:

 
Рис.2

Ширина ее 100 пикселей, а высота 600 (в итоге рассчитываю получить стерео изображение размером 800 на 600 пикселей). Хотя лучше сделать ее так, чтоб она тайлилась по горизонтали. Далее создаем или открывает любой 3D-объект в MAX’е. Я для этого использовал модель осы:

 
Рис.3

Для результата не пригодятся ни материалы, ни сторонние рендеры, ни источники света. Поэтому если все это имеется в сцене, то назначаем на все стандартный материал, удаляем все источники света и используем Default Scanline Renderer. Теперь можно приступить к написанию скрипта. Для этого в меню Max’а выбираем MAXScript->New Script и откроется окно редактирование скриптов. Наш скрипт будет иметь свой собственный интерфейс. Это можно реализовать двумя способами: на панели Utilites или в отдельном окне. Выберем первый вариант и создадим новую скрипт-утилиту:

utility stereoImg "Stereo Image"

-- утилита создания стерео изображения

(

)

Сохраним ее с названием stereoImg.ms и отправим ее на просчет. Для этого надо в меню редактора скриптов выбрать Tools->Evaluate All или нажать комбинацию клавиш Ctrl+E. После этого наша утилита приобрела свой интерфейс (рис.4) и единственное что можно с ней сделать – это открыть и закрыть.

 
Рис.4

Разберем что же мы сделали: utility – зарезервированное слово с помощью которого создаются новые скрипт-утилиты, stereoImg – имя переменной, с помощью которой можно осуществлять контроль над утилитой, “Stereo Image” – символьная строка, именно она отображается в списке утилит (рис.4-3), далее в круглых скобках идет тело утилиты. Более подробную информацию по созданию скрипт-утилит и MAXScript’у можно найти в файле помощи MAX’а (в основном меню Help->MAXScript Reference). Для добавления комментариев используется «--», после него компилятор игнорирует все символы до конца строки . Пора наполнить нашу утилиту кнопками и другими элементами пользовательского интерфейса. Будем ориентироваться на следующий вариант:

 
Рис.5

Итак, список необходимых элементов: две группы Texture и Render. В группе Texture имеется метка, в которой будет отображаться информация о текстуре, и кнопка, запускающая диалог открытия файла с текстурой. В группе Render – спиннер (определяет ширину рендера), метка (информация о высоте рендера), спиннер (качество стерео изображения), индикатор процесса, кнопка выбора объекта и «самая главная» кнопка запускающая скрипт на просчет. Для этого в тело утилиты надо добавить следующие строки:

    fn fltr_cam obj = superClassOf obj == camera -- функция возвращает истину если obj камера (для фильтра выбора)

    group "Texture:"

   -- параметры текстуры

   (

       label l_T_img "no texture" -- информация о размере

       button b_T_img "Load texture bitmap" -- загрузка текстуры

   )

   group "Render:"

   -- параметры рендеринга

   (

       spinner s_R_w "width:" range:[0,1500,0] type:#integer width:82 across:2 -- ширина

       label l_R_h "height:0" -- высота

       spinner s_R_prec "quality of stereo image" range:[1,10,4] type:#integer width:80 align:#right -- качество стерео изображения

       progressBar prb_R_status value:0 -- прогресс рендера

       pickbutton pb_R_cam "Pick camera" filter:fltr_cam across:2 -- выбор камеры

       button b_R_stereo ""  -- запуск рендера

   )

Здесь: group – зарезервированное слово для создание группы, после него следует название группы, и в круглых скобках элементы группы; label – для создания метки, потом название переменной для управления меткой и срока (выводимый на форму текст); button – для создания кнопки, потом название переменной для управления кнопкой и строка (отображается на кнопке). Это основная структура для создания элементов пользовательского интерфейса. Но некоторые элементы имеют так же дополнительные параметры. Для spinner’а – range:точка в 3d-пространстве> (первая координата определяет нижний предел изменения значения, вторая – верхний, третья – начальное значение), type:#integer (тип значения – целое число, так же может принимать значение #float – вещественное число и #worldunits – число в размерности текущих координат MAX’а). Для progressBarvalue:первоначальное значение>. Для pickbuttonfilter:ссылка на функцию фильтра>, функция фильтра имеет один параметр – объект и возвращает true, если объект может быть выбран, и false в противном случае. Для определение такой функции используется зарезервированное слово fn потом идет название функции, параметр и после «=» логическое выражение, которое возвращает функция. Параметры width:, across: и align: могут использоваться при создании любых элементов и отвечают за компоновку элементов на форме: первый – ширина (если требуется отличная от создаваемой по умолчанию), второй – количество элементов в одной строке (по умолчанию каждый новый элемент создается в новой строке), третий – выравнивание.

В самом начале тела утилиты (перед описанием пользовательских элементов) определим локальные переменные, необходимые для создания стерео изображения:

    -- определение локальных переменных

   local T_img = undefined -- текстура

   local width, height, d_max -- ширина и высота рендера, ширина текстуры

Осталось прописать обработчики событий от элементов пользовательского интерфейса. Описание всех событий должно быть следующим образом: onимя элемента> название события> список аргументов>do(обработка события>). Для начала опишем поведение MAX’а на нажатие кнопки загрузки текстуры. Что должно происходить:  открыться окно диалога выбора файла, после выбора файла текстуры она загружается в MAX, выводиться на форму информация о размере текстуры и ее название, далее инициируются локальные переменные и настраиваются глобальные параметры рендера.

    on b_T_img pressed do

   -- загрузка текстуры

   (

       T_file_name = getOpenFileName types:"bitmap(*.bmp)|*.bmp" -- диалог открытия файла

       if T_file_name != undefined then -- если все файл бы выбран

       (

           T_img = openBitMap (T_file_name) -- загрузка картинки

           b_T_img.caption = filenameFromPath T_file_name -- на кнопку имя файла картинки

           l_T_img.caption = "width: " + (T_img.width as String) + " height:" + (T_img.height as String) -- вывести информацию о картинке

           d_max = T_img.width -- обновление всех локальных переменных

           height = T_img.height

           width = 4*height/3 as Integer -- определение ширины рендера так чтоб в итоге получились пропорции 3:4

           s_R_w.value = width -- отображение информации о разрешении рендера

           l_R_h.caption = "height:" + height as String

           renderWidth = width -- настройка глобальных параметров рендера (ширина, высота)

           renderHeight = height

       )

   )

Определим вид, который мы желаем получит на стерео изображении. Для этого нам понадобиться камера. Если в сцене уже имеются камеры с «нужным» видом – отлично, можно использовать их. Если нет, то необходимо создать камеру. Проще всего перейти к виду Perspective, где выбрать необходимый ракурс. После чего создать камеру из вида: в главном меню Create->Cameras->CreateCameraFromView или Crtl+C. Вспомним теорию, там были такие параметры как H – расстояние до максимально удаленного объекта и h_max – расстояние от плоскости проецирования до максимально удаленного объекта. Чтоб не вводить их вручную, будем брать их из свойства камеры, а именно из Clipping Planes. Выберем необходимую камеру, на панели Modify раскроем свиток Parameters, ставим галочку возле Clip Manually. Осталось только настроить Near Clip и Far Clip. Плоскость Near Clip соответствует плоскости проекции стерео изображения, а Far Clip – расстояние до максимально удаленного объекта. Рекомендации: объекты, по которым будет строиться стерео изображение, должна располагаться между Far Clip и Near Clip, Near Clip равно приблизительно половине Far Clip, объекты должны быть расположены подальше от Near Clip и вплотную к Far Clip. Хотя можно этим пренебречь и в дальнейшем экспериментировать с Clipping Planes, для получения более желаемого результата. Т.о. вид настроен, осталось «объяснить» скрипту, что мы будем работать с этой камерой, для этого напишем обработчик нажатия кнопки выбора камеры:

    on pb_R_cam picked cam do

   -- выбор камеры

   (

       pb_R_cam.caption = pb_R_cam.object.name -- на кнопку имя камеры

   )

После этого ссылка на камеру содержится в pb_R_cam.object.Так же необходимо скрипту отреагировать на изменение пользователем ширины рендера:

    on s_R_w changed val do

   -- обработка изменения ширины рендера

   (

       width = s_R_w.value

       renderWidth = width

   )

Осталось обработать последнее событие – нажатие «самой главной» кнопки. Опять придется заняться теорией на основе полученной ранее формулы: d/(h-H+h_max))=a/h. Здесь a, H и h_max – констаны. Последние две получаються из Clipping Planes камеры. Определим a, для этого подставим вместо h величину H – крайний случай, когда объект находиться на максимальном расстоянии. Отсюда a=d_max*H/h_max. И последняя формула: d=a*(h-H+h_max)/h – по ней вычисляется расстояние между точками d, изображения в которых совпадают, для того чтоб создавалась иллюзия, что рассматриваемый объект расположен на расстоянии h от наблюдателя.

    on b_R_stereo pressed do

   -- просчет стерео изображения

   (

       -- рендер глубины

       DOF_img = render camera:pb_R_cam.object outputwidth:width outputheight:height channels:#(#zDepth)

       unDisplay DOF_img

       -- создание битмапы для будущего стерео изображения

       OUT_img = bitmap (width+d_max) height color:black

       -- заполнение первой полосы текстурой

       for x = 0 to (d_max-1)do

       (

           for y = 0 to (height-1) do

           (

               c =(getPixels T_img [x,y] 1)[1] -- берем пиксель из текстуры

               setPixels OUT_img [x,y] #(c) -- и вставляем в будущее стерео изображение

           )

           prb_R_status.value =(100 * x / d_max)as integer -- обновление прогресса текущей операции

       )

       prb_R_status.value = 0

       -- отрисовка стерео изображения

       H = pb_R_cam.object.farclip -- расстояние от глаз до максимальной глубины

       h_max = pb_R_cam.object.farclip - pb_R_cam.object.nearclip -- расстояние от плоскости проецирования до макс. глубины

       a = d_max*H/h_max -- расстояние между глазами

       -- построчное построение стерео изображения

       for y = 0 to (height - 1)do

       (

           for x = 0 to (width - 1) do

           (

               -- берем из рендера глубины расстояние от камеры до ближайшей точки

               dist = - (getChannel DOF_img [x,y] #zDepth)[1]

               if dist > H then dist = H -- не должно быть больше макс. глубины

               d =(a*(dist+h_max-H)/(dist)+.5)as integer -- вычисляем расстояние на котором должны совпадать пиксели стерео изображения

               setPixels OUT_img [x+d_max,y](getPixels OUT_img [x+d_max-d,y] 1) -- и дубируем пиксели согласно этому расстоянию

           )

           prb_R_status.value =(100 * y / height) as integer

       )

       prb_R_status.value = 0

       display OUT_img -- открываем окно с финальным стерео изображением

   )

Рассмотрим подробнее принцып работы обработчика нажатия «самой главной» кнопки. В переменную DOF_img сохраняется ссылка на рендер из выбранной камеры. Параметр channels:массив каналов> метода render указывает какие каналы необходимо отрендерить дополнительно, в нашем случае обязателен только один канал: #zDepth - расстояние от камеры до места пересечения объекта с лучом, выходящим из камеры и проходящим через заданную точку рендера h (в скрипте – это переменная dist). Метод unDisplay ссылка на изображение> закрывает окно с изображением, если оно открыто, этот метод противоположен display ссылка на изображение>. Затем создается новое изображение шириной большей, чем ширина рендера на ширину текстуры и слева заполняется полосой текстуры (рис.6).

 
Рис.6

Потом идет построчное сканирование канала глубины (с проверкой на то, чтоб расстояние не превысило Far Clip камеры). На основе этой величины h (в скрипте dist) и полученных ранее формул вычисляется расстояние между повторяющимися пикселами. Таким образом идет построение стерео изображения, попутно обновляется прогресс вычислений. И в конце концов на экран выводиться окончательный результат (рис.7).

 
Рис.7

Ниже приведен полный листинг скрипт-утилиты с некоторыми улучшениями:

utility stereoImg "Stereo Image"

-- утилита создания стерео изображения

(

   -- определение локальных переменных

   local T_img = undefined -- текстура

   local width, height, d_max -- ширина и высота рендера, ширина текстуры

   fn fltr_cam obj = superClassOf obj == camera -- функция возвращает истину если obj камера (для фильтра выбора)

   group "Texture:"

   -- параметры текстуры

   (

       label l_T_img "no texture" -- информация о размере

       button b_T_img "Load texture bitmap" -- загрузка текстуры

   )

   group "Render:"

   -- параметры рендеринга

   (

       spinner s_R_w "width:" range:[0,1500,0] type:#integer width:82 across:2 -- ширина

       label l_R_h "height:0" -- высота

       spinner s_R_prec "quality of stereo image" range:[1,10,4] type:#integer width:80 align:#right -- качество стерео изображения

       progressBar prb_R_status value:0 -- прогресс рендера

       pickbutton pb_R_cam "Pick camera" filter:fltr_cam across:2 -- выбор камеры

       button b_R_stereo ""  -- запуск рендера

   )

   on b_T_img pressed do

   -- загрузка текстуры

   (

       T_file_name = getOpenFileName types:"bitmap(*.bmp)|*.bmp" -- диалог открытия файла

       if T_file_name != undefined then -- если все файл бы выбран

       (

           T_img = openBitMap (T_file_name) -- загрузка картинки

           b_T_img.caption = filenameFromPath T_file_name -- на кнопку имя файла картинки

           l_T_img.caption = "width: " + (T_img.width as String) + " height:" + (T_img.height as String) -- вывести информацию о картинке

           d_max = T_img.width -- обновление всех локальных переменных

           height = T_img.height

           width = 4*height/3 as Integer -- определение ширины рендера так чтоб в итоге получились пропорции 3:4

           s_R_w.value = width -- отображение информации о разрешении рендера

           l_R_h.caption = "height:" + height as String

           renderWidth = width -- настройка глобальных параметров рендера (ширина, высота)

           renderHeight = height

       )

   )

   on pb_R_cam picked cam do

   -- выбор камеры

   (

       pb_R_cam.caption = pb_R_cam.object.name -- на кнопку имя камеры

   )

   on s_R_w changed val do

   -- обработка изменения ширины рендера

   (

       width = s_R_w.value

       renderWidth = width

   )

   on b_R_stereo pressed do

   -- просчет стерео изображения

   (

       if (height == undefined) or (width == 0) then

       (

           messageBox "No texture or invalid size"

           return 0

       )

       if pb_R_cam.object == undefined then

       (

           messageBox "Pick camera first"

           return 0

       )

       -- рендер глубины

       DOF_img = render camera:pb_R_cam.object outputwidth:width outputheight:height channels:#(#zDepth)

       unDisplay DOF_img

       -- создание битмапы для будущего "расширенного" стерео изображения

       -- причем ширина умножается на точность

       prec = s_R_prec.value -- точность (коэф. качества)

       OUT_img = bitmap ((width+d_max)*prec) height color:black

       -- заполнение первой полосы текстурой

       for x = 0 to (d_max-1)do

       (

           for y = 0 to (height-1) do

           for i = 0 to (prec-1) do

           (

               c1 =(getPixels T_img [x,y] 1)[1] -- берем пиксель из текстуры

               c2 = (getPixels T_img [x+1,y] 1)[1]

               if c2 == undefined then c2 = (getPixels T_img [0,y] 1)[1]

               c = c1*(1.*(prec-i)/prec)+ c2*(1.*i/prec) -- линейно сглаживаем растяжение

               setPixels OUT_img [x*prec+i,y] #(c) -- и вставляем в будущее стерео изображение

           )

           prb_R_status.value =(100 * x / d_max)as integer -- обновление прогресса текущей операции

       )

       prb_R_status.value = 0

       -- отрисовка "расширенного" стерео изображения

       H = pb_R_cam.object.farclip -- расстояние от глаз до максимальной глубины

       h_max = pb_R_cam.object.farclip - pb_R_cam.object.nearclip -- расстояние от плоскости проецирования до макс. глубины

       a = d_max*H/h_max -- расстояние между глазами

       -- построчное построение стерео изображения ("расширенное")

       for y = 0 to (height - 1) do

       (

           for x = 0 to (width - 1) do

           for dx = 0 to (prec - 1) do

           (

               -- берем из рендера глубины расстояние от камеры до ближайшей точки (тут тоже идет линейное сглаживание)

               dist = (- (getChannel DOF_img [x,y] #zDepth)[1]*(prec-dx) - (getChannel DOF_img [x,y] #zDepth)[1]*dx)/prec

               if dist > H then dist = H -- не должно быть больше макс. глубины

               d =(prec*a*(dist+h_max-H)/(dist)+.5)as integer -- вычисляем расстояние на котором должны совпадать пиксели стерео изображения

               setPixels OUT_img [x*prec+dx+d_max*prec,y](getPixels OUT_img [x*prec+dx+d,y] 1) -- и дубируем пиксели согласно этому расстоянию

           )

           prb_R_status.value =(100 * y / height) as integer

       )

       prb_R_status.value = 0

       -- получение из "расширенного" "нормальное" стерео изображение

       FIN_img = bitmap (width+d_max) height color:black -- создание битмапы для финального стерео изображения

       for y = 0 to (height - 1) do

       (

           for x = 0 to (width + d_max - 1) do

           (

               c = black

               for i = 0 to (prec-1) do

                   c +=(getPixels OUT_img [x*prec+i,y] 1)[1]/prec -- получение сренего арифметического цвета

               setPixels FIN_img [x,y] #(c) -- и сохранение его в финальное стрео изображение

           )

           prb_R_status.value =(100 * y / height) as integer

       )

       prb_R_status.value = 0

       display FIN_img -- открываем окно с финальным стерео изображением

   )

)

Изменение здесь только в алгоритме просчета стерео изображения. Добавилась проверка «от дурака»: просчет не начнется, если не была выбрана текстура и камера. Так же тут был реализован алгоритм «улучшенного» расчета стерео изображения с использованием спиннера «качество». В двух словах в чем это заключается: изображение сначала линейно растягивается и просчет ведется тоже «растянуто», а потом полученный результат сжимается до первоначального размера. Разницу можно увидеть на рис.7, рис.8, рис.9.

 
рис.8

 
рис.9

На рис.7 качество выставлено в единицу, а на рис.8 и рис.9 – 4 и 8 соответственно. Конечно чем выше качество, тем больше время просчета.

Вот и все. Теперь у нас имеется скрипт-утилита, с помощью которой можно из любого 3D-объекта получить стерео изображение. Очень надеюсь что урок был понятен (для этого надо дружить с геометрией :) и полезен (по крайней мере тем, что можно действительно посмотреть свои модели «в объеме»).

далее