Вакансия Frontend JavaScript Developer (WebGL/Three.js) компании Visual Science на vc.ru, Удалённо
Удалённо Зарплата по договорённости
1590 просмотров
Требования
- В группу компаний лидера рынка компьютерной графики в сфере Biotech/Pharma и Real Estate (офис в Нью-Йорке) на фултайм-позицию с возможностью дальнейшей релокации в США приглашаем Frontend JavaScript Developer.
- Коммерческий опыт разработки JavaScript, TypeScript 3+ лет.
- Уверенные знания принципов ООП, асинхронной модели программирования.
- Опыт разработки веб-приложений с использованием 3D-графики WebGL/Three.js.
- Умение решать задачи на оптимизацию, анализ/поиск ошибок во всём стеке сцены и её компонентах.
- Опыт работы с анимациями, изингами камеры.
- Умение взаимодействовать с вёрсткой внутри WebGL, совмещать события на бэкенде внутри WebGL.
- Опыт адаптивной вёрстки под ПК и мобильные устройства.
- Опыт работы с технологиями: ReactJS, Vue, REST API, Webpack.
- Опыт интеграции сторонних библиотек в проекты.
- Опыт написания чистого и поддерживаемого кода.
Желательно
- Опыт с 3D-графикой на любых фреймворках и трёхмерных пакетах.
- Опыт работы с Мatterport SDK Bundle.
- Опыт работы с игровыми движками.
- Желание изучать новые технологии, искать нетривиальные подходы для решения сложных задач по оптимизации, улучшению пользовательского опыта продукта.
- Английский от Intermediate и выше.
- Сильные знания в математике, геометрии.
Задачи
- Лидировать разработку клиентской части продукта компании группы при участии ИТ-директора и директора по продукту.
- Лидировать разработку внутренних и внешних проектов группы компаний в сфере веб-приложений.
Условия
- Работа в продуктовом spin-off проекте мирового лидера графики с американскими и европейскими клиентами из Fortune-500, такими как Google, Johnson & Johnson, Pfizer, Roche, NASA, нобелевскими лауреатами.
- Развитие продукта в быстрорастущей продуктовой компании в США.
- Удалённая работа с комфортным графиком.
- Команда гениальных коллег, джедаев в области компьютерной графики и ИТ.
- Достойная оплата в долларах.
- Ноль бюрократии и душной клиентской разработки.
- В перспективе помощь с релокацией в США.
Дополнительно
Присылайте на [email protected]:
— Рассказ о себе;
— Ссылку на Git;
— 3 проекта, которыми гордитесь;
— Ваши ожидания по окладу и ник в Telegram.
{ «author_name»: «Ivan Konstantinov», «author_type»: «self», «tags»: [], «comments»: 0, «likes»: 0, «favorites»: 1, «is_advertisement»: false, «subsite_label»: «vacancies», «id»: «324296», «is_wide»: true }
Новая игра со старой атмосферой на Three.js
Существует множество поклонников старых игр. И они не прочь пустить скупую ностальгическую слезу и нет-нет, да сыграть в «Арканоид», «Пакмана» или «Принца Персии», как двадцать, тридцать, сорок или — подставьте нужное число — лет назад. DOS-box и эмуляторы — им в помощь. Да, что там, я недавно смотрел стрим самого первого 2D «Принца Персии» на Ютьюбе, где довольно молодой «стример» после прохождения очередного смертельного препятствия, смахнув со лба пот рукой, изрек: «Мне еще никогда не было так страшно в компьютерной игре». То есть, даже молодежь способна оценить хардкорность и крутизну старых игр.
Я подумал, а почему бы не создать новую игру в подобном стиле? Да, существуют различные ремейки и клоны. Также, радуют современные игры в стиле пиксель-арт. Однако, все они, как правило, повторяют квесты, механики и иногда вообще полностью левел-дизайн старых игр, по мотивам которых они сделаны. Ну либо, наоборот, предлагают совершенно новый сюжет и локации, являя собой просто визуальную стилизацию «под старину». А что, если представить, какой была бы новая часть старой игры, выйди она следом за последней из серии? Я решил такую создать.
Я взял 2D платформер и добавил туда 3D графику, сохранив, при этом, классический вид сбоку. Построил новые лабиринты, придумал новые квесты, ввел задания и реализовал слоты инвентаря. Слегка разнообразил ощущение пространства, добавив повороты на 90 градусов. Возможно, в те древние времена, перед тотальным переходом игр в 3D с тремя степенями свободы, нечто подобное вполне могло бы выйти.
Поскольку я увлекаюсь написанием игр под браузеры, то я решил сделать игру под браузер. В силу ее специфики, в ней нет какого-то бешеного количества полигонов, по крайней мере, отображающихся на экране одновременно, нет открытого мира. Поэтому все это не будет сильно нагружать браузер. Для вывода 3D графики я выбрал свою любимую библиотеку Three.js (WebGL) с собственной оберткой. Больше никаких других библиотек не используется, а код написан на чистом javascript.
Three.js и проблемы, с которыми я столкнулся
Разработчики графических 3D движков периодически, примерно раз в пару лет, выпускают новые версии своих творений. В случае со скриптовой библиотекой Three. js, разработчики радуют нас обновлениями с бешеной частотой — примерно раз в месяц. На момент написания статьи последняя версия имела номер 106. Казалось бы, это прекрасно. (Нет.)
Почему никто даже не задумывается об обратной совместимости? Когда разработчики Three.js переименовали свойство материала ambient, я понял — «Хьюстон, у нас проблемы». Ладно, допустим, мне не трудно было во всем своем коде поиском-заменой поменять слово «ambient» на «color». Но когда они исключили возможность источника света создавать тень без освещения как такового, я понял, что теперь уже посадке «Орла» угрожает реальная опасность, а база «Спокойствие» начинает медленно превращаться в базу «Бешенство». Однако, как выяснилось позже, это было еще полбеды…
Дело в том, что в моей игре, помимо запеченного света, используется также и динамическое освещение. Количество динамических источников на 3D сцене сильно влияет на производительность.
Я вынес в настройки игры выбор количества источников — от 1 до 7. И в зависимости от мощности видеокарты, можно попробовать разные значения.
Также имеется массив, в котором содержатся координаты и характеристики каждого источника — интенсивность, цвет и так далее. Это работает так. При движении по игровому миру в определенном квадрате вокруг игрока зажигается заданное в настройках количество источников света с заданными характеристиками. То есть, источники света как бы следуют за игроком (вокруг него) облаком.
Итак, Хьюстон, какие у нас проблемы? Докладываю.
Проблема номер 1: тени
Источники света создают тени. Я заметил, что тени от точечных источников (point light) потребляют намного больше ресурсов, чем от направленных (spot light). И это понятно: в случае точечного источника, тени отбрасываются во все стороны, а направленного — только в заданном конусе. Однако, я предположил, что, когда тени во все стороны не нужны, то можно применить сразу два источника: точечный будет создавать только освещение, а направленный — только тени в некоем заданном направлении. Это идеально подходит для моей игры и, как выяснилось, действительно, существенно экономит вычислительные мощности.
Пирамида ограничивает область, в которой могут появляться тени.
Но вот, в чем беда, начиная с версии three.js r73, направленный источник света больше не может только отбрасывать тень, он теперь всегда дает и освещение тоже. И свет от него распространяется внутри области, так же, как и тень. Убрать точечный источник и оставить только направленный нельзя: освещение мне необходимо во все стороны. А использовать оба источника, подогнав их под нужную яркость, тоже не получится: тогда объекты внутри конуса будут освещены заметно ярче. Использование же «честного» освещения с тенями во все стороны на производительности игры сказывается просто фатально.
А убрали нужное мне свойство направленного источника света .shadowOnly просто потому, что так захотелось автору движка.
Проблема номер 2: имена свойств
Я решил, что лучше останусь на версии r71, где нужное мне свойство освещения еще присутствует. Почему не r72 тогда? Ведь свойство исчезло только в версии r73. Потому что я уже написал довольно много кода для загрузки 3D моделей, анимации и физики под версию r71. А в версии r72 изменилось большое количество имен свойств: типа — shadowMap стало shadow.map и т.д. В общем, переименовывать все это мне тоже не хотелось. Да и разница между одной версией невелика. Итак, остаемся на версии r71.
Проблема номер 3: запекание теней
Запеченный свет в разных версиях движка выглядит тоже по-разному. Я не знаю, что они там с ним вытворяют, но при наложении на текстуру карты теней (shadow map) резко изменяется яркость и даже цвет. В общем, эту проблему я кое-как решил, подшаманив в GLSL коде движка и поставив автоматическую коррекцию цвета в загрузчике 3D моделей в тех местах, где используются карты теней. Это работает, естественно, только для версии r71. Для других версий придется использовать какие-то другие параметры. Это еще один повод остановиться на версии r71.
Собственно, переходить на последние версии нет никакого смысла, так как результат работы, по сравнению со старой, в плане производительности принципиально не отличается.
Хорошо. Направленный источник света создает только тень. Запечь и загрузить тени в сборку на версии r71 я могу. А теперь — самая главная засада. Персонажи.
Проблема номер 4: скелетная анимация
Вот над этим я бился очень долго. В общей сложности я потратил пару недель на то, чтобы найти какой-то рабочий алгоритм переноса персонажа с набором анимаций в игру.
В последних версиях Three.js этой проблемы нет. Там я успешно создал анимированную модель персонажа в известном онлайн сервисе, сконвертировал ее в популярный формат gltf и загрузил на тестовую сцену. Однако, если в новых версиях Three.js используется формат gltf 2.0, то в моей поддерживается только 1.0. Казалось бы, в чем проблема, ну, сконвертируй в 1. 0 и загружай. Оказалось не все так просто. Видимо, существует несколько вариаций формата gltf 1.0. Мне нужен был тот, где, помимо основного файла модели, должны присутствовать еще два файла с расширением *.glsl. Но и в этом случае, формат основного файла может варьироваться… В общем, мне не удалось найти конвертер, который бы удовлетворял всем параметрам, тем более, чтобы он еще и конвертировал из нового формата в старый. Допилить старую версию three.js до поддержки gltf 2.0 мне тоже не удалось: слишком глубоко в коде завязана эта поддержка, уходя корнями в математику, реализованную по-разному в разных версиях движка… В общем, с gltf как-то не сложилось.
Я попробовал использовать для 3D моделей формат .dae. В итоге, сама модель загружалась, но мне не удалось заставить корректно работать анимации персонажа. С текстурами также возникали проблемы.
Хорошо получилось с форматом .md2. Персонаж сразу отобразился и все анимации заработали правильно. Но, насколько я понял, md2 — это формат моделей для Quake 2 и его поддержку в Three. js кто-то реализовал просто по фану. А где достать модели в этом формате, а тем более, сконструировать и сохранить в нем своего собственного персонажа, я не нашел.
Я перепробовал еще несколько форматов. Но под них то не было загрузчика для three.js, то не было программ для создания сохранения в них своего персонажа, то они вообще не поддерживали скелетную анимацию.
Базу «Бешенство» было впору переименовывать в базу «Отчаяние».
Уже почти отчаявшись и подумывая о переходе на новую версию движка в ущерб производительности (история о направленном источнике света), я решил в последний раз помучить формат json, с которого я, на самом деле, начал. Но в первый раз мне не удалось повторить в 3D редакторе Блендер процесс конвертации персонажа из файла примера, который поставлялся в комплекте Three.js, из исходного формата .blend в .json. Анимации портились и вели себя как-то хаотично, а с десяток вариаций экспортера из Blender в json все до единого срабатывали неправильно. Причем, я их испробовал еще и на нескольких версиях Блендера. Сам JSONLoader, то есть, загрузчик моделей в формате json, сейчас уже удален из three.js. Я решил поискать, на какой версии прекратилась его поддержка, чтобы взять его и образец 3D модели не из своей версии, а из той, где он еще был. Ей оказалась r88. И, о чудо! Мне удалось воспроизвести экспорт тестовой модели в r71 и все, включая анимации персонажа, заработало в игре нормально!
«Орел» благополучно прилунился.
Тогда я решил отредактировать одну из анимаций тестового персонажа в Блендере, чтобы понять, смогу ли я делать свои. Здесь меня ждал облом. Анимация, которую я редактировал, не хотела в игре работать вообще. Персонаж застывал в исходной позе. Хотя другие анимации работали без проблем. Но это уже кое-что. То есть, теперь проблема заключается в моем незнании каких-то нюансов редактирования анимации.
Тогда я подумал — а что, если спросить у автора этого примера, как он это делал. Но докопаться до автора было нелегко. На Гитхабе у него нет никаких личных контактов. Поиск по нику и еще паре параметров вывел на его Твиттер, однако личные сообщения там были закрыты. Зато оттуда я узнал, что он — профессор какого-то американского университета, и зашел на сайт этого учебного заведения. Оказалось, что профессор занимался 3D графикой со своими учениками, используя свой пример в качестве методического материала. Тогда я вернулся на Гитхаб и просмотрел все его репозитории. Здесь меня ждал успех. Как я и предполагал, в отдельном репозитории хранился его пример. И не просто копия того, что я уже видел в примерах three.js, а пример, заботливо снабженный инструкцией (видимо, для студентов). Я скачал архив и, следуя инструкции, все повторил. Ура!
Это маленький шаг для человечества, но огромный скачок для одного человека и его игры!
Никаких проблем, Хьюстон!
Теперь я понимаю, что если я буду придерживаться этого формата, этих инструкций и этих версий Three. js, JSONLoader-а и Блендера и делать все единообразно, то смогу создавать и загружать в браузерную игру любых своих персонажей. Радовало еще то, что, несмотря на использование старой версии движка, можно использовать самую новую версию 3D редактора Blender и создавать любых персонажей с анимацией. Просто нужно потом экспортировать их по строго определенной схеме при помощи этого определенного инструментария.
Да, я заметил еще одну проблему новой версии Three.js: во время игры при скроллинге экрана почему-то наблюдаются постоянные фризы. И это не связано с усиленным потреблением ресурсов — процессор и видеокарта не загружаются на 100%. А в старом r71 такого безобразия нет.
Теперь остается только делать для игры в 3D редакторе персонажей с анимацией. Ну и, конечно же, геометрию уровней. Не знаю, сколько у меня уйдет на это времени. Но пока я только собрал на Webkit бесплатную демо-версию и выложил ее в популярные магазины приложений.
Немного об игре
Название. Я назвал игру «Перси Ланкастер». Здесь все очевидно: «я художник, и я так вижу».
Как создавалась графика. Я создал в 3D редакторе две плоскости, расположил их на расстоянии одна от другой так, чтобы дальняя скрывалась за ближней, натянул на них текстуру камней, прорезал дырки в ближней, а затем убрал ненужные, то есть, невидимые, части. Затем смоделировал плоскости для полов и потолков. Так получился коридор для хождения игрока. Разнообразил локации различными текстурами.
В самой игре такого вида нет, там — только вид сбоку, и никаких черных пространств не заметно. Это просто общий вид коридора.
Я решил создать пересекающиеся коридоры. Во время поворота достраивается одна стена другого коридора, вся конструкция поворачивается, а затем убирается стена первого коридора. На основе этой механики я также планирую создать башни, внутри которых можно подниматься по винтовой лестнице.
Со статической графикой, собственно, никаких проблем нет, она легко экспортируется в json из любого 3D редактора. Сложности, как я уже упомянул, возникли только с запеканием теней и анимацией персонажа.
Производительность. В разрешении экрана HD, то есть 1280×720, моя не самая мощная видеокарта GT-730 нагружается примерно на 35-40%, а процессор Xeon E5440 — примерно на 30%. Думаю, это более чем приемлемый результат.
ОС. Пока демоверсия доступна только под Windows в виде сборки на Webkit. В дальнейшем планирую запустить и браузерную версию. Я столкнулся с тем, что не во всех браузерах скроллинг экрана идет плавно. Мне нужно еще поработать над управлением и вызовом функции вывода графики. А пока я остановился на Webkit версии 26.0. Она мало весит и на ней все работает нормально.
Звук. Звуки частично взяты из бесплатных библиотек, частично сгенерированы. В общем, они пока сделаны, «чтобы было». Пока я над ними не сильно заморачивался.
Видео. Полное прохождение демосцены.
Планы
Я планирую выйти на краудфандинг, и на собранные деньги нанять 3D моделера, который создаст нормального персонажа и анимации для него. Все же, графика — это не мое. Но зато теперь я знаю, как внедрить персонажа в мою игру.
Также, планирую запустить браузерную версию под свежие версии Chrome и Firefox. Скажу по секрету, мне даже удалось запустить игру на MS Edge, но там почему-то пропадали объекты, на которые накладываются текстуры запеченных теней, я еще с этим не разобрался. Далее займусь отладкой под браузеры под Linux и Android и, если добуду у кого-нибудь для теста яблочные девайсы, то — также и под браузеры на iOS и MacOS.
В отдаленной перспективе — написание собственной библиотеки для работы с WebGL, наподобие Three.js: мне не нравится, что они резко переименовывают свойства и убирают нужный мне функционал. И наоборот, большинство из огромного количества возможностей, которые предлагает Three.js, мне не нужно.
Думаю, позже, когда разберусь с корректной работой игры под все браузеры на различных ОС, напишу об этом статью уже с какими-то техническими подробностями.
3JS-3-R
check_circle
Номинальный ток, Ампер | 3 |
Напряжение переменного тока | 350 |
Характеристика | Медленный удар |
Соответствует RoHS | ДА |
Упаковка | Масса (косичка) |
Бизнес / Организация *
Имя *
Первый
Последний
Электронная почта *
Адрес
Адресная строка 1 *
Адреса 2
Город *
Государство / Провинция / Регион *
POSTAL POSTAL код * *
AfghanistanAland IslandsAlbaniaAlgeriaAmerican SamoaAndorraAngolaAnguillaAntarcticaAntigua and BarbudaArgentinaArmeniaArubaAscension IslandAustraliaAustriaAzerbaijan)BahamasBahrainBangladeshBarbadosBelarusBelgiumBelizeBeninBermudaBhutanBoliviaBosnia and HerzegovinaBotswanaBouvet IslandBrazilBritish Indian Ocean TerritoryBritish Virgin IslandsBruneiBulgariaBurkina FasoBurundiCambodiaCameroonCanadaCanary IslandsCape VerdeCaribbean NetherlandsCayman IslandsCentral African RepublicCeuta and MelillaChad ChileChinaChristmas IslandClipperton IslandCocos (Keeling) IslandsColombiaComorosCongo (DRC)Congo (Republic)Cook IslandsCosta RicaCôte d’IvoireCroatiaCubaCuraçaoCyprusCzech RepublicDenmark (Danmark ) Диего Га rciaDjiboutiDominicaDominican RepublicEcuadorEgyptEl SalvadorEquatorial Guinea EritreaEstoniaEthiopiaFalkland IslandsFaroe IslandsFijiFinlandFranceFrench GuianaFrench PolynesiaFrench Southern TerritoriesGabonGambiaGeorgiaGermanyGhanaGibraltarGreeceGreenlandGrenadaGuadeloupeGuamGuatemalaGuernseyGuineaGuinea-BissauGuyanaHaitiHeard & McDonald IslandsHondurasHong Kong)HungaryIcelandIndiaIndonesiaIranIraqIrelandIsle of ManIsraelItalyJamaicaJapanJerseyJordanKazakhstan)KenyaKiribatiKosovoKuwaitKyrgyzstanLaosLatviaLebanonLesothoLiberiaLibyaLiechtensteinLithuaniaLuxembourgMacauMacedonia (FYROM)MadagascarMalawiMalaysiaMaldivesMaliMaltaMarshall IslandsMartiniqueMauritaniaMauritius)MayotteMexicoMicronesiaMoldovaMonacoMongoliaMontenegroMontserratMoroccoMozambiqueMyanmarNamibiaNauruNepalNetherlandsNew CaledoniaNew ZealandNicaraguaNigerNigeriaNiueNorfolk IslandNorthern Mariana IslandsNorth KoreaNorwayOmanPakistanPalauPalestinePanamaPapua New GuineaParaguayPeruPhilippinesPitcairn IslandsPolandPortugal Пуэрто-РикоКатарРеюньонРумынияРоссияРуандаСент-БартельмиСент-ХеленаСент-Китс и НевисСент-ЛюсияСен-Мартин Сен-Пьер и МикелонСамоаСан-МариноСан-Томе и ПринсипиСаудовская АравияСенегалСербияСейшельские островаСьерра-ЛеонеСингапурСинт-МартенСловакияСловенияСоломоновы островаСомалиЮжная АфрикаЮжная Грузия и Южная ЛанкаСпасыЮжная КореяСпасыЮжная Корея Винсент и ГренадиныСуданСуринамШпицберген и Ян-МайенСвазилендШвецияШвейцарияСирияТайваньТаджикистанТанзанияТаиландТимор-ЛештиТогоТокелауТонгаТринидад и ТобагоТристан-да-КуньяТунисТурцияТуркменистанОстрова Теркс и КайкосТувалуСША.