687
Ricardo Cabello aka mrdoob

Ricardo Cabello · анимированной трехмерной компьютерной графики в веб-браузере. Скрипты three.js можно использовать

  • Upload
    others

  • View
    32

  • Download
    0

Embed Size (px)

Citation preview

  • RicardoCabelloakamrdoob

    https://github.com/mrdoob

  • three.jsсправочноеруководство

    three.js-этонебольшаяпоразмерукроссбраузернаяJavaScriptбиблиотека/APIиспользуемаядлясозданияиотображенияанимированнойтрехмернойкомпьютернойграфикиввеб-браузере.Скриптыthree.jsможноиспользоватьвсвязкесэлементомcanvasHTML5,SVGилиWebGL.

    Вthree.jsвозможносоздаватьтрехмерныеанимации,ускоряемыеграфическимпроцессором,используяязыкJavaScriptкакчастьвебсайта,неполагаясьнасобственныеплагиныбраузеров.ЭтосталовозможнымблагодаряпоявлениюWebGL.

    Библиотекапредоставляетрендереры,,CSS3DиWebGL.

    Вthree.jsвключеныследующиефункции:Визуализаторы(рендереры):Canvas,SVGиWebGL.Эффекты:анаглиф,собственныхглазменятьфокусноерасстояние.Еслиестьжеланиепопробовать,выполнитеследующуюпоследовательностьдействий:'+'

    Смотритенаизображение.Неотрываявзглядаотизображения,начинайтесдвигатьфокусноерасстояниеближекносу(скоситеглаза).

    '+'Двечастиизображенияначнутнакладыватьсяоднанадругую,образуятретью,котораяпоявитсявцентре.

    '+'Сосредоточьтесьнапоявившейсякартинкеисфокусируйтенанейвзгляд.

    https://ru.wikipedia.org/wiki/%D0%90%D0%BD%D0%B0%D0%B3%D0%BB%D0%B8%D1%84

  • Еслиувасвсеполучилось,тоизображениевцентревыувидитетрехмерным.')">перекрестныйвзгляд(cross-eyed)ипараллаксныйбарьер(parallaxbarrier).Сцены:добавлениеиудалениеобъектоввовремявыполнения;туманКамеры:перспективнаяиортографическаяКонтроллеры:трекбол,FPS,pathидругиеControllers:trackball,FPS,pathandmoreАнимация:armatures,forwardkinematics,inversekinematics,morphandkeyframeОсвещение:фоновое,направленное,точечноеипрожекторноеambient,direction,pointandspotlightsТени:отбрасываниеиполучениеcastandreceiveМатериалы:PBR,Phong,Lambert,smoothshading,texturesandmoreФормы:доступкполноценномуязыкупрограммированияшейдеров(OpenGLShadingLanguage-GLSL)Capabilities:бликиотлинз,передачаглубиныиобширнаябиблиотекапост-обработкиlensflare,depthpassandextensivepost-processinglibraryОбъекты:сетки(meshes),частицы(particles),спрайты(sprites),линии,ленты(ribbons),кости(bones)имногоедругое-всесallwithLevelofdetailГеометрия:плоскость,куб,сфера,тор,3DтекстидругиеModifiers:lathe,extrudeandtubeЗагрузчикиданных:бинарный,графический,JSONисценарныйDataloaders:binary,image,JSONandsceneУтилиты:полныйнаборвременны́хитрехмерныхматематическихфункций,включаяусеченныйконус(усеченнаяпараллельнымиплоскостямичастьфигуры),матрицу,Quaternian,UVидругиеUtilities:fullsetoftimeand3Dmathfunctionsincludingfrustum,matrix,Quaternian,UVsandmoreЭкспортиимпорт:утилитыдлясозданияJSON-файлов,совместимыхсthree.jsиз:Blender,openCTM,FBX,Max,иOBJСопровождение:разрабатываетсядокументацияпоAPI,общественныйфорумивикивполномобъемеdocumentationisunderconstruction,publicforumandwikiinfulloperation

    https://ru.wikipedia.org/wiki/%D0%9F%D0%B0%D1%80%D0%B0%D0%BB%D0%BB%D0%B0%D0%BA%D1%81%D0%BD%D1%8B%D0%B9_%D0%B1%D0%B0%D1%80%D1%8C%D0%B5%D1%80https://en.wikipedia.org/wiki/Parallax_barrierhttps://ru.wikipedia.org/wiki/%D0%A2%D1%80%D0%B5%D0%BA%D0%B1%D0%BE%D0%BBhttps://ru.wikipedia.org/wiki/OpenGL_Shading_Language

  • Примеры:Свыше150файловскодамипримеровплюсшрифты,модели,текстуры,звукиидругиеподдерживаемыефайлыОтладка:Stats.js,WebGLInspector,Three.jsInspector

    three.jsработаетвовсехбраузерах,поддерживающихWebGL.Выпускаетсяthree.jsподлицензиейMIT.

    https://github.com/mrdoob/stats.js/https://benvanik.github.io/WebGL-Inspector/http://zz85.github.io/zz85-bookmarklets/threelabs.htmlhttps://ru.wikipedia.org/wiki/%D0%9B%D0%B8%D1%86%D0%B5%D0%BD%D0%B7%D0%B8%D1%8F_MIT

  • ВВЕДЕНИЕ

    Созданиесцены

    Цельэтогораздела-датькраткоевступлениевthree.js.Начнемегосозданиемсюжетасвращающимсякубом.Наслучайесливызапутаетесьипонадобитсяпомощь,рабочийпримеркодаприводитсяниже.

    Преждечемначать

    Передиспользованиемthree.js,нужноопределиться,гдемыбудемегопоказывать.СохранитеследующийHTML-кодкакфайлнасвоемкомпьютеревместескопиейфайлаthree.jsвпапкеjs/иоткройтееговсвоембраузере.

    MyfirstThree.jsappbody{margin:0;}canvas{width:100%;height:100%}//ЗдесьбудетвашJavascriptкод.

    Этовсе.Веськоднижеидетвпустойтег.

    Созданиесцены

    Длятого,чтобыбылавозможностьчто-либоотображатьсthree.js,

    http://threejs.org/build/three.jshttp://davidscottlyons.com/threejs/presentations/frontporch14/index.html#slide-16

  • нужнытривещи:сцена(scene),камера(camera)ивизуализатор(renderer)-такженазываемыйрендерер(позвучаниюанглийскогослова),чтобыбылавозможностьпоказыватьсцену,снятуюкамерой.varscene=newTHREE.Scene();varcamera=newTHREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000);

    varrenderer=newTHREE.WebGLRenderer();renderer.setSize(window.innerWidth,window.innerHeight);document.body.appendChild(renderer.domElement);

    Давайтевоспользуемсямоментомипоясним,чтоздесьпроисходит.Наданномэтапеунасимеетсянаборизсцены(переменнаяscene),камеры(переменнаяcamera)ивизуализатора(переменнаяrenderer).Вthree.jsимеетсянесколькоразныхкамер.СейчасмыбудемиспользоватьPerspectiveCamera(т.е.камерусотображениемперспективы).Первымпараметромунееявляетсякоторымограниченазонавидимостикамеры,объектынепопадающие'+'внеенебудутвидны.Различаютполезренияпогоризонталииповертикали.Вthree.jsуголfov-этополезренияповертикалииизмеряетсявградусах.');"onmouseout="hide()">fov(полезренияилипросмотра).

    Второйпараметр-этоaspectratio-отношениесторон');"onmouseout="hide()">aspect(соотношениесторон,пропорцииилиформаткадра).Почтивсегданужноиспользоватьотношениешириныэлементакеговысотеилиполучитетакойжерезультаткакприпросмотрестарыхфильмовнаширокоэкранныхтелевизорах-изображениебудетвыглядетьсплющенным.

    Следующимидвумяпараметрамиявляютсяnear(ближняя)иfar(дальняя)плоскостиотсечения.Этозначит,чтообъектыдальше,чемзначениеfarилиближе,чемnearнебудутпоказаны.Покаонихможнонебеспокоиться,нодляувеличениябыстродействиявсвоемприложенииможноиспользоватьдругиезначения.Примечаниепереводчика:какговорится"вместотысячислов",вотнарисункепоказанывсепараметрыкамеры....читатьдалее

  • Далееидетвизуализатор(рендерер).Воттуттоипроисходитволшебство.ВдополнениекиспользуемомуздесьWebGLRenderer,вThree.jsимеетсянесколькодругих,зачастуюиспользуемыхвкачестверезервноговариантадляпользователейсостарымибраузерамиилитех,укогонетподдержкиWebGLподругимпричинам.

    Помимосозданияэкземпляравизуализатора(рендерера),такженужноустановитьразмерывкоторыхбудетотображатьсянашеприложение.Хорошейидеейбудетиспользованиешириныивысотыобласти,которуюнамхочетсязанятьнашимприложением-вданномслучае,этоширинаивысотаэлемента,т.е.полныйразмер(помните,уиширина(width)ивысота(height)равны100%)окнабраузера.ПривыполненииресурсоёмкихприложенийтакжеможнозадатьпараметруsetSizeменьшиезначения,вродеwindow.innerWidth/2иwindow.innerHeight/2,которыесделаютвизуализациюприложениявполовинномразмере.

    Еслинужносохранитьразмерыприложения,ноотобразитьегосболеенизкимразрешением,можносделатьэто,вызвавпараметрsetSizeсозначениемfalseвкачествепараметраupdateStyle.Например,кодsetSize(window.innerWidth/2,window.innerHeight/2,false)сделаетвизуализациюприложениявполовинномразрешении,сучетомтого,чтонашимеет100%ширинуивысотуотразмеровокнабраузера.

    Инаконец,чтонеменееважно,кнашемуHTML-документудобавляемэлементrenderer'а.Этоэлемент,накоторомрендерериотображаетсцену.

    Тактовсехорошо,ногдеэтотобещанныйкуб?Сейчасмыегодобавим.

    vargeometry=newTHREE.BoxGeometry(1,1,1);varmaterial=newTHREE.MeshBasicMaterial({color:0x00ff00});varcube=newTHREE.Mesh(geometry,material);scene.add(cube);

  • camera.position.z=5;

    ДлясозданиякубанампотребуетсяBoxGeometry,т.е.геометриякуба.Этообъект,содержащийвсеточки(вершины-verticesед.числоvertex)истороны(грани-faces)куба.Вдальнейшеммырассмотримэтоболееподробно.Примечаниепереводчика:Здесьидалееслово«геометрия»означаетсовокупностьвсехгеометрическихсвойствобъекта,т.е.всеэлементы,которыесоставляюткаркасобъекта-вершины,грани,атакжеихцветирасположение....читатьдалее

    Вдополнениекгеометриикубапонадобитсяиматериалдляегоокрашивания.ВThree.jsимеетсянесколькоматериалов,новданномслучаебудемиспользоватьMeshBasicMaterial.Всематериалыпринимаютсвойстваобъекта,чтобыликнемуприменены.Чтобысохранитьпростотувещей,предоставимтолькоатрибутцвета0x00ff00,т.е.зеленыйцвет.ЭтоработаетточнотакжекаквCSSилиPhotoshop(шестнадцатиричныезначенияцвета).

    Третьявещь,чтонампотребуется,этоMesh,т.е.сетка.Meshпредставляетсобойобъект,которыйпринимаетгеометриюиприменяеткнейматериал,которыйпотомможновставитьвнашусценуисвободноперемещатьсявокруг.

    Поумолчанию,привызовеscene.add(),добавляемаянамивещьбудетрасполагатьсявкоординатах(0,0,0).Чтобыэтогоизбежать,мывпоследнейстрокепростонемножкосмещаемкамеру.

    Визуализация(рендеринг)сцены

    Еслископироватькод,приведенныйвыше,ивставитьвзаранеесозданныйHTML-файл,товыничегонеувидите.Потомучтонасамомделепокаещенечегоотображать.Длятого,чтобычто-нибудьпоявилосьнужното,чтоназываетсяrenderloop-цикломвизуализации.functionrender(){ requestAnimationFrame(render); renderer.render(scene,camera);}render();

  • Этоткодсоздастцикл,которыйбудет60развсекундувызыватьвизуализатордляпрорисовкисцены.Есливыновичоквнаписаниибраузерныхигр,томожетесказать:"ПочемубынампростоневызватьJavaScript-функциют.е.временимеждувызовамифункцииперерисовкисцены');"onmouseout="hide()">setInterval?"Конечноже,можноэтосделать,ноуфункции-позволяетсинхронизироватьвсеанимациисовстроеннымимеханизмамиобновлениястраницы.

    Тоесть,сгруппированыбудутнетолькоJavaScript-анимации,ноиCSS-анимацииидругиебраузерныеперерисовки.Приэтомграфическийускорительиспользуетсямаксимальноэффективноиисключаетсяповторнаяобработкаоднихитехжеучастковстраницы.Азначит–меньшебудетзагрузкаCPU,даисамаанимациястанетболееплавной.');"onmouseout="hide()">requestAnimationFrameимеетсянесколькопреимуществ.Пожалуй,самымважнымизнихявляетсято,чтоанимацияприостанавливаетсяприпереходепользователянадругуювкладкубраузера,аследовательнонетратитсядрагоценнаявычислительнаямощностьизарядаккумулятора.

    Примечаниепереводчика:Вотещёоднакартинкадлялучшегопониманияпроцессавизуализациивthree.js....читатьдалее

    Анимациякуба

    Есливеськод,приведенныйвыше,вставленвзаранеесозданныйфайл,выдолжныувидетьзеленыйкуб.Давайтесделаемегочутьпоинтереснее-покрутимего.

    Добавьтеследующийкодсразупередвызовомrenderer.renderфункцииrender:cube.rotation.x+=0.1;cube.rotation.y+=0.1;

    Этоткодбудетвыполнятьсявкаждомкадре(60развсекунду)и

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

    Итог

    Поздравляем!Вытолькочтополучилисвоепервоеthree.jsприложение.Каквидите,простонужнобылогде-тоначать.

    Полныйкодпоказанниже.Чтобыполучитьболееполноепредставлениеоегоработе,поиграйтесьсним(т.е.попробуйтепоменятьтеилииныепараметрыипонаблюдайтезаполучающимисяизменениями).Код:...показать

  • Импортспомощьюмодулей

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

    Нужновручнуювыбиратьиподключатькопиюбиблиотекикакчастьисходногокодапроекта.Обновлениеверсиибиблиотекитакже"ручной"процесс.Припроверкеновойверсииданнойбиблиотекиуправлениеразличиявуправленииверсиямизаваленымножествомстроксборочногофайла.

    Использованиедиспетчеразависимостейтипаnpmобходитэтиусловияпозволяяпростоскачиватьиимпортироватьжелаемуюверсиюбиблиотекинавашумашину.

    Установкаприпомощиnpm

    Примечаниепереводчика:npm-сокращ.отNode.jsPackageManager—менеджерпакетов,входящийвсоставNode.js

    three.jsвыпускаетсякакмодульnpm.Этозначит,чтодлявключенияthree.jsвпроект,нужнопростозапустить"npminstallthree".

    Импортмодуля

    Предположим,чтовыобъединяетефайлыспомощьютакогоинструментакакWebpackилиBrowserify,которыепозволяютAssumingthatyou'rebundlingyourfileswithatoolsuchasWebpackorBrowserify,whichallowyouto"require('modules')inthebrowserbybundlingupallofyourdependencies."Теперьможновнестимодульвсвоиисходныефайлыипродолжитьиспользоватьеговобычномрежиме.varTHREE=require('three');

    varscene=newTHREE.Scene();...

    https://ru.wikipedia.org/wiki/Node.jshttps://www.npmjs.com/package/threehttps://webpack.github.io/https://github.com/substack/node-browserify

  • ТакжеестьвозможностьиспользованияимпортасинтаксисаES6:import*asTHREEfrom'three';

    constscene=newTHREE.Scene();...

    или,еслихотитеимпортироватьтолькоотдельныечастибиблиотекиthree.js,напримерScene:import{Scene}from'three';

    constscene=newScene();...

    Предостережения

    Внастоящеевремятакимспособомневозможноимпортироватьфайлывкаталог"examples/js".Этопроисходитиз-затого,чтонекоторыеизфайловзависимыотзагрязненияглобальногопространстваименTHREE.БолееподробныесведениясмотритенаTransform`examples/js`tosupportmodules#9562.

    https://github.com/mrdoob/three.js/issues/9562

  • Поддержкабраузерами

    Обзор

    Three.jsможетиспользоватьWebGLдлявизуализации(рендеринга)сценвовсехсовременныхбраузерах.Длястарыхбраузеров,особенноInternetExplorer10иниже,можетпотребоватьсяоткаткодномуизоставшихсявизуализаторов(рендереров)(CSS2DRenderer,CSS3DRenderer,SVGRenderer,CanvasRenderer).Крометого,можетпотребоватьсявключениенекоторыхполифиллов,особенноприиспользованиифайловизкаталога/examples.«Полифилл»(англ.«polyfill»-poly-много,fill-наполнять,заполнять)...читатьдалее

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

    Браузеры,поддерживающиеWebGL

    WebGLподдерживаетсяследующимибраузерами:GoogleChrome9+,Firefox4+,Opera15+,Safari5.1+,InternetExplorer11иMicrosoftEdge.Узнать,какиебраузерыподдерживаютWebGLможнона«могулияпользоватьсяWebGL»');"onmouseout="hide()">CanIuseWebGL.

    Используемыевthree.jsфункциинаязыкеJavaScriptилиWebAPI

    Вотнесколькофункций,используемыхвthree.js.Длянекоторыхизнихможетпотребоватьсядополнениеполифиллами.ФУНКЦИИFEATURE

    ОБЛАСТЬПРИМЕНЕНИЯUSESCOPE

    МОДУЛИMODULES

    TypedArrays Исходник BufferAttribute,BufferGeometryит.д.WebAudioAPI Исходник

    Audio,AudioContext,AudioListenerит.д.

    WebVRAPI Исходник WebVRManagerит.д.

    https://github.com/mrdoob/three.js/tree/master/examples/js/renderershttps://github.com/mrdoob/three.js/tree/master/exampleshttps://caniuse.com/#feat=webgl

  • Blob Исходник FileLoader,etc.

    Promise Примеры GLTFLoader,GLTF2Loader,WebVR,VREffectит.д.Fetch Примеры ImageBitmapLoaderит.д.FileAPI Примеры GLTFExporterит.д.URLAPI Примеры GLTFLoaderит.д.PointerLockAPI Примеры PointerLockControls

    Полифиллы

    Простоимпортируйтеполифиллы,исходяизсвоихтребований.ЕсливкачествепримеравзятьIE9,топотребуютсяполифиллыкакминимумкэтимфункциям:

    TypedArraysBlob

    Рекомендуемыеполифиллыcore-jstypedarray.jsES6-PromiseBlob.jsfetch

    https://github.com/zloirock/core-jshttps://github.com/inexorabletash/polyfill/blob/master/typedarray.jshttps://github.com/stefanpenner/es6-promise/https://github.com/eligrey/Blob.jshttps://github.com/github/fetch

  • ОбнаружениесовместимостибраузерасWebGL

    Несмотрянато,чтопроблемавстречаетсявсережеиреже,некоторыеустройстваилибраузерывсеещёнемогутработатьсWebGL.Описанныйнижеметодпроверяет,поддерживаетсялиWebGLи,еслиэтонетак,выводитсообщениепользователю.

    Добавьтессвоемуjavascript-кодуDetector.jsизапускайтеследующийкодпреждечемпытатьсячто-либоотобразить.if(Detector.webgl){//Initiatefunctionorotherinitializationshere//Здесьрасполагаетсяинициализацияфункцииилидругиеинициализацииanimate();}else{varwarning=Detector.getWebGLErrorMessage();document.getElementById('container').appendChild(warning);}

    https://github.com/mrdoob/three.js/blob/master/examples/js/Detector.js

  • Каквсеэтозапуститьлокально

    Еслииспользуютсятолькоконструкции,предусмотренныевThree.js,иникакихтекстурдополнительнонезагружается,веб-страницыдолжныработатьпрямоизфайловойсистемы,простосделайтедвойноккликвфайловомменеджерепоHTMLфайлуиондолженпоявитьсяиначатьработатьвбраузере(вадреснойстрокебудетвидноfile:///yourFile.html).

    Содержимое,загружаемоеизвнешнихфайлов

    Еслимоделиилитекстурызагружаютсяизвнешнихфайлов,из-заограниченийбезопасностипосангл.«Принциподинаковогоисточника»)—этоважнаяконцепциябезопасностидлянекоторыхязыковпрограммированиянасторонеклиента,такихкакJavaScript.'+'Политикаразрешаетсценариям,находящимсянастраницаходногосайта,доступкметодамисвойствамдругдругабезограничений,нопредотвращаетдоступкбольшинствуметодовисвойствдлястраницнаразныхсайтах.'+'Одинаковыеисточники—этоисточники,укоторыхсовпадаюттрипризнака:домен,порт,протокол.');"onmouseout="hide()">правилуограничениядоменабраузера,загрузкаизфайловойсистемызавершитсяошибкойивыдачейсообщениясописаниемисключениябезопасности.Примечаниепереводчика:ВотссылкинастатьивВикипедиипроПравилоограничениядоменаиSameOriginPolicy.

    Существуетдваспособарешенияэтойпроблемы:1. Изменитьдлялокальныхфайловправилабезопасностив

    браузере.Этопозволитполучитьдоступксвоейстраницекак:file:///yourFile.html

    2. Запускатьфайлыизлокальноговеб-сервера.Этопозволитполучитьдоступксвоейстраницекак:http://localhost/yourFile.html

    Прииспользованиипервоговариантаимейтеввиду,чтоесли

    https://ru.wikipedia.org/wiki/%D0%9F%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D0%BE_%D0%BE%D0%B3%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B4%D0%BE%D0%BC%D0%B5%D0%BD%D0%B0http://en.wikipedia.org/wiki/Same_origin_policy

  • используететотжесамыйбраузеридляобычноговеб-серфинга,можнооткрытьнекоторыеуязвимости.Длябезопасности,можносоздатьотдельныйпрофиль/ярлыкбраузератолькодлялокальногоприменения.Давайтерассмотримкаждыйвариантпоочереди.

    Изменениеполитикибезопасностилокальныхфайловвбраузере

    SafariСпомощьюпанелинастройкивключитеменюразработки,черезAdvanced(дополнительно)=>"Showdevelopmenuinmenubar"(показыватьменюразработкивпанелименю).

    Затемвменю"Develop"(разработка)браузеравыберите"Disablelocalfilerestrictions"(отключитьограничениялокальныхфайлов),стоиттакжеотметить,чтоSafariимеетнесколькостранноеповедениеприработескэшем,такчтовтомжеменюжелательноиспользоватьопцию"Disablecaches"(отключитькэш);еслиредактированиеиотладкаведутьсяспомощьюSafari.

    ChromeВначалезакройтевсеработающиеэкземплярыбраузераChrome.Главноесловоздесь"все".

    ВоперационнойсистемеWindowsможнопроверитьчислоиспользуемыхэкземпляровChromeчерезПанельзадач.Крометого,есливсистемномтреевидноиконкуChrome,можнооткрытьегоконтекстноеменюикликнуть'Exit'-выйти.ЭтодолжнозакрытьвсеэкземплярыбраузераChrome.

    ЗатемзапуститеисполняемыйфайлChromeсфлагомкоманднойстроки:chrome--allow-file-access-from-files

    ВОСWindows,возможно,самымпростымспособомявляетсясозданиеспециальногоярлыка,вкоторомдобавленфлаг,указанныйвыше(правыйкликпоиконкеярлыкавызоветконтекстноеменю,вкоторомнужносделатьлевыйкликнастроке

  • Свойства(Properties).Воткрывшемсяокнесвойствярлыка,встрокеОбъект(Target)инужнодобавитьупомянутыйфлаг).

    ВоперационнойсистемеMacOSXэтоделаетсяспомощьюopen/Applications/Google\Chrome.app--args--allow-file-access-from-files

    Firefox1. Наберитевадреснойстрокеabout:config2. Найдитепараметр

    security.fileuri.strict_origin_policy3. Установитеегокакfalse

    Запусклокальногосервера

    НамногихязыкахпрограммированияимеютсявстроенныепростыеHTTP-серверы.Ониненастолькополнофункциональны,какреальноработающиесервера,подобныеApacheилиNGINX,темнеменееонидолжныбытьдостаточныдлятестированияприложенияthree.js.ЗапусксервераPythonЕслиустановленPython,тоегодолжнобытьдостаточнодлязапускасервераизкоманднойстроки(израбочегокаталога)://Python2.xpython-mSimpleHTTPServer

    //Python3.xpython-mhttp.server

    Онбудетобслуживатьфайлыизтекущегокаталогавlocalhostпо8000порту,тоесть,вадреснойстрокенаберите:http://localhost:8000/

    ЗапусксервераRubyЕслиустановленRuby,можнополучитьтотжерезультат,запустиввзаменследующее:ruby-rwebrick-e"s=WEBrick::HTTPServer.new(:Port=>8000,:DocumentRoot=>Dir.pwd);trap('INT'){s.shutdown};s.start"

    https://www.apache.org/https://nginx.orghttp://python.org/

  • ЗапусксервераPHPВPHPтакжеимеетсявстроенныйсервер,начинаясверсииphp5.4.0:php-Slocalhost:8000

    ЗапусксервераNode.jsВNode.jsимеетсяпростойпакетHTTPсервера.Дляустановки:npminstallhttp-server-g

    Длязапуска(излокальногокаталога):http-server.-p8000

    ЗапусксервераlighttpdнаMacLighttpd-этооченьлегковесныйвеб-серверобщегоназначения.СейчасрасскажемоегоустановкенаOSXспомощьюHomeBrew.Вотличиеотдругихсерверов,обсуждаемыхздесь,lighttpd-этополноценныйсервер,готовыйкреальнойработе.

    1. Устанавливаемсерверчерезhomebrewbrewinstalllighttpd

    2. Вкаталоге,гденужнозапуститьвеб-сервер,создаемфайлнастройкисназваниемlighttpd.conf.Вотздесьимеетсяпример.

    3. Вфайленастройкизаменяемзначениепараметраserver.document-rootнакаталог,вкоторомнужнообслуживатьфайлы.

    4. Запускаемегоlighttpd-flighttpd.conf

    5. Переходимнаhttp://localhost:3000/ионбудетобслуживатьстатическиефайлыизвыбранногокаталога.

    ДругиепростейшиевариантыобсуждаютсянапримернаStackOverflow.

    http://redmine.lighttpd.net/projects/lighttpd/wiki/TutorialConfigurationhttp://stackoverflow.com/q/12905426/24874

  • Рисованиелиний

    Предположим,нужнонарисоватьлиниюиликруг,безкаркаснойсетки.Вначаленужноустановитьрендерер(визуализатор),сценуикамеру(смотритестраницуСозданиесцены).

    Воткод,которыйдляэтогобудетиспользоваться:varrenderer=newTHREE.WebGLRenderer();renderer.setSize(window.innerWidth,window.innerHeight);document.body.appendChild(renderer.domElement);

    varcamera=newTHREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,1,500);camera.position.set(0,0,100);camera.lookAt(newTHREE.Vector3(0,0,0));

    varscene=newTHREE.Scene();

    Следующее,чтонужносделать,этоопределитьматериал.ДлялинийможноиспользоватьLineBasicMaterialилиLineDashedMaterial.//createablueLineBasicMaterial(создадимсинийLineBasicMaterial)varmaterial=newTHREE.LineBasicMaterial({color:0x0000ff});

    ПослеопределенияматериаланужноопределитьсясGeometryилиBufferGeometryснекоторымколичествомвершин(рекомендуетсяиспользоватьBufferGeometryкакболеепроизводительную,однакодляупрощенияздесьбудетиспользованаGeometry):vargeometry=newTHREE.Geometry();geometry.vertices.push(newTHREE.Vector3(-10,0,0));geometry.vertices.push(newTHREE.Vector3(0,10,0));geometry.vertices.push(newTHREE.Vector3(10,0,0));

    Обратитевнимание,чтолиниипроведенымеждукаждойпоследующейпаройвершин,нонемеждупервойипоследней(тоесть,эталиниянезамкнута).

    Теперь,когдаестьточкидлядвухлинийиматериал,можносложитьвсевместедляформированиялинии.varline=newTHREE.Line(geometry,material);

    Всечтоосталось,вывести(добавить)еёнасценуивызватьрендерер.scene.add(line);

  • renderer.render(scene,camera);

    Теперьвыдолжныувидетьстрелкуиздвухсинихлиний,направленнуювверх.

  • Созданиетекста

    Частобываеттак,чтовприложенииthree.jsнужноиспользоватьтекст-вотнесколькоспособов,какможноэтосделать.

    1.DOM+CSS

    ИспользованиеHTML-этонаиболеепростойибыстрыйспособдобавлениятекста.Thisisthemethodusedfordescriptiveoverlaysinmostthree.jsexamples.

    МожнодобавитьсодержимоевDescription

    ииспользоватьCSS-разметкудляразмещениявабсолютнонезависимойпозициииповерхвсегоостальногопоz-индексу,особенноеслиприложениеthree.jsработаетвполноэкранномрежиме.#info{ position:absolute; top:10px; width:100%; text-align:center; z-index:100; display:block;}

    2.Нарисоватьтекстнаcanvasииспользоватьегокактекстуру

    Используйтеэтотспособ,еслихочетсяпростонарисоватьтекстнаплоскости,насвоейthree.js-сцене.

    3.Создатьмодельтекставвыбраннойвамипрограмме3D-графикииэкспортироватьеёвthree.js

    Используйтеэтотспособ,еслипредпочитаетеработатьсосвоейпрограммой3D-графикиивставьтеэтумодельвthree.js.

  • 4.ProceduralTextGeometry

    Еслипредпочитаетеработатьисключительновthree.jsилисоздаватьIfyouprefertoworkpurelyinTHREE.jsortocreateproceduralanddynamic3Dtextgeometries,youcancreateameshwhosegeometryisaninstanceofTHREE.TextGeometry:newTHREE.TextGeometry(text,parameters);

    Длятого,чтобыэтосработало,дляTextGeometryбудетнуженэкземплярTHREE.Font,установленныйвкачествезначенияегопараметра"font"-шрифт.ПосмотритестраницуTextGeometryдляполучениядополнительныхсведенийотом,какэтоможносделатьсописаниемкаждогопринимаемогопараметраиспискомJSON-шрифтов,поставляемыхвсоставесамогоTHREE.js.ПримерыWebGL/geometry/textcanvas/geometry/textWebGL/shadowmap

    Еслишрифтнеработаетилинужноиспользоватьшрифт,которогоздесьнет,существуетруководствососкриптомнаязыкеPythonдляBlender'а,которыйпозволяетэкспортироватьтекствпонятномдляThree.jsформатеJSON.

    https://ru.wikipedia.org/wiki/JSONhttps://threejs.org/examples/#webgl_geometry_texthttps://threejs.org/examples/#canvas_geometry_texthttps://threejs.org/examples/#webgl_shadowmaphttp://www.jaanga.com/2012/03/blender-to-threejs-create-3d-text-with.htmlhttps://www.blender.org/

  • Руководствопомиграцииистилюкода

    Руководствопомиграциитоесть,попереводупрограммthree.js,сделанныхводнойверсии,дляработывдругойверсииthree.jsхранитсянаwiki.Оносодержитсписокизмененийкаждойверсииthree.js,начинаясрелизаr45.Егоможнонайтиздесь.Примечаниепереводчика:Вики(англ.wiki)—веб-сайт,...читатьдалее

    Веськодипримерынаthree.jsнаписанывстилекодаотMr.doob.Конечно,можноиспользоватьлюбой,предпочитаемыйвамидляработы,стиль,нопридобавлениикодавбиблиотекуиливпримеры,требуетсяследоватьэтомуруководству.Подробностиможнонайтиздесь.

    https://github.com/mrdoob/three.js/wikihttps://github.com/mrdoob/three.js/wiki/Migration-Guidehttps://ru.wikipedia.org/wiki/%D0%92%D0%B8%D0%BA%D0%B8-%D1%80%D0%B0%D0%B7%D0%BC%D0%B5%D1%82%D0%BA%D0%B0https://ru.wikipedia.org/wiki/%D0%92%D0%B8%D0%BA%D0%B8https://github.com/mrdoob/three.js/wiki/Mr.doob%27s-Code-Style%E2%84%A2

  • ЧАстозадаваемыеВОпросы

    Какойформатимпорта/экспорталучшевсегоподдерживается?

    TODO

    Почемувпримерахприсутствуюттегиmetaдляокнапросмотра(viewport)?

    Этитэгиуправляютразмерамиокнапросмотра(viewport)имасштабомдлябраузеровмобильныхтелефонов(гдесодержимоестраницыможетотображатьсявдругомразмере,чемвидимоеокнопросмотра).http://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariWebContent/UsingtheViewport/UsingtheViewport.html

    https://developer.mozilla.org/en/Mobile/Viewport_meta_tag(англ.)https://developer.mozilla.org/ru/docs/Mozilla/Mobile/Viewport_meta_tagнарусском

    Какможносохранитьмасштабсценыприизмененииразмера?

    Хочетсячтобывсеобъекты,независимоотихрасстояниядокамеры,выгляделиодинаково,дажеприизмененииразмераокна.Ключевоеуравнениедлярешенияэтойзадачи-этоформуладлявидимойвысоты(visible_height)назаданномрасстоянииоткамеры(distance_from_camera):visible_height=2*Math.tan((Math.PI/180)*camera.fov/2)*distance_from_camera;

    Еслиувеличиваетсявысотаокнанаопределенныйпроцент,тоивидимаявысотанавсехрасстоянияхтакжеувеличиваласьнатотжесамыйпроцент.Этогонельзясделатьизменениемположениякамеры.Вместоэтогоследуетизменятьполепросмотракамеры(параметрfov-field-of-view).Пример.

    Почемучастьмоегообъектаневидима?

    http://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariWebContent/UsingtheViewport/UsingtheViewport.htmlhttps://developer.mozilla.org/en/Mobile/Viewport_meta_taghttps://developer.mozilla.org/ru/docs/Mozilla/Mobile/Viewport_meta_taghttp://jsfiddle.net/Q4Jpu/

  • Этоможетпроисходитьиз-завыбораграни.Угранейимеетсяориентир,которыйопределяеткакаясторонаявляетсяпереднейивидимой,акакая-заднейиневидимой.Ивобычныхусловияхпривыбореудаляетсязадняя,невидимаясторона.Еслипроблемавэтом,изменитесторонуматериаланаTHREE.DoubleSide.material.side=THREE.DoubleSide

  • Ссылкинаполезныересурсы

    Нижеприведенаколлекцияссылок,которыевозможнобудутполезнымиприизученииthree.js.Есливынашличто-либо,чтохочетсясюдадобавить,илисчитаете,чтооднаизприведенныхссылокбольшенеуместнаилинеработает,нестесняйтеськликнутькнопку'edit'(редактировать)справавверхуивнестинекоторыеизменения!

    Отметьтетакже,чтоthree.jsдовольнобыстроразвивается,многиеизэтихссылокбудутсодержатьустаревшиесведения-есличто-тоработаетнетак,какожидалосьиликакуказываетсявэтойссылке,проверьтеконсольбраузерананаличиепредупрежденийиошибок,соответствующиеразделыэтойсправкииособенностраницуDeprecatedList(списокустаревшихэлементовAPI).

    Вдополнениекэтойстранице,mrdoobподдерживаетколлекциюссылок,связанныхсthree.jsвGoogle+.Посмотриихздесь.

    Справочныефорумы

    Three.jsофициальноиспользуетStackOverflowдлязапросовсправочнойинформации.Есливчем-либотребуетсяпомощь,обращайтесьтуда.НЕНУЖНОсоздаватьпроблемыпросьбамипомочьнаGithub'е.

    Учебникиикурсы

    Началоработысthree.jsBeginningwith3DWebGLотRachelSmith.AnimatingsceneswithWebGLandthree.jsанимациясценсWebGLиthree.js

    БолеерасширенныеидополняющиестатьиикурсыCollectionoftutorialsнаборучебниковотCJGammon.Glossyspheresinthree.jsблестящиесферывthree.js.

    https://plus.google.com/+ThreejsOrghttp://stackoverflow.com/tags/three.js/infohttps://codepen.io/rachsmith/post/beginning-with-3d-webgl-pt-1-the-scenehttps://codepen.io/rachsmith/https://www.august.com.au/blog/animating-scenes-with-webgl-three-js/http://blog.cjgammon.com/http://www.cjgammon.com/https://medium.com/@soffritti.pierfrancesco/glossy-spheres-in-three-js-bfd2785d4857

  • Interactive3DGraphics-бесплатныйкурспоUdacity,обучающийосновам3Dграфикиииспользующийвкачествеинструментакодированияthree.js.AerotwistучебникиотPaulLewis.LearningThree.js–ablogwitharticlesdedicatedtoteachingthree.jsAnimatedselectiveglowinThree.jsотBKcore

    УчебникинадругихязыкахBuildingAPhysicsSimulationEnvironmentпостроениесредымоделированияфизическихпроцессов-учебникthree.jsнаяпонском

    Дополнительнаядокументация

    Three.jswalkingmap-agraphicalbreakdownofthestructureofathree.jsscene.

    Новостииобновления

    Three.jsнаredditWebGLнаredditLearningWebGLBlog–АвторитетныйисточникновостейоWebGL.Three.jspostsнаGoogle+–частыесообщенияоThree.js

    Примеры

    ProfessorStemkoskisExamples(ПримерыпрофессораСтемкоскис)-Сборникдружественныхпримеровдляначинающих,построенныхсиспользованиемthree.jsверсииr60a.Официальныепримерыthree.js-этипримерысохраняютсякакчастьрепозиторияthree.jsивсегдаиспользуютпоследнююверсиюthree.js.Officialthree.jsdevbranchexamples-Sameastheabove,excepttheseusethedevbranchofthree.js,andareusedtocheckthateverythingisworkingasthree.jsbeingisdeveloped.

    https://www.udacity.com/course/cs291https://aerotwist.com/tutorials/https://github.com/paullewis/http://learningthreejs.com/http://bkcore.com/blog/3d/webgl-three-js-animated-selective-glow.htmlhttps://github.com/BKcorehttp://www.natural-science.or.jp/article/20120220155529.phphttp://ushiroad.com/3j/http://www.reddit.com/r/threejs/http://www.reddit.com/r/webgl/http://learningwebgl.com/blog/https://plus.google.com/104300307601542851567/postshttp://stemkoski.github.io/Three.js/index.htmlhttps://threejs.org/examples/https://rawgit.com/mrdoob/three.js/dev/examples/

  • Инструменты

    physgl.org-javascriptfront-endwithwrapperstothree.js,чтобыдонестиграфикуWebGLдостудентов,изучающихфизикуиматематику.tobringWebGLgraphicstostudentslearningphysicsandmath.[link:http://whitestormjs.xyz/Whitestorm.js]–AwrapperaroundThree.jsandcustom[link:https://github.com/chandlerprall/Physijsphysi.js].Three.jsInspectorThreeNodes.js.

    Старыессылки

    Этиссылкихранятсявисторическихцелях-внихтожеможнонайтичто-тополезное,ноимейтеввиду,содержащаясявнихинформацияотноситсякоченьстарымверсиямthree.js.

    AlterQualiaatWebGLCamp3YomotsusExamples(примеры)-коллекцияпримеров,сиспользованиемthree.jsверсииr45.IntroductiontoThree.js-введениевThree.jsотIlmariHeikkinen(слайдшоу).WebGLandThree.jsотAkihiroOyamada(слайдшоу).FastHTML5gamedevelopmentusingthree.jsотBKcore(видео).TriggerRallyотjareiko(видео).ThreeFab-редакторсцен,поддерживалсяприблизительнодоthree.jsверсииr50.MaxtoThree.jsworkflowtipsandtricksотBKcoreAwhirlwindlookatThree.js(БеглыйвзгляднаThree.js)отPaulKing

    http://www.physgl.org/http://zz85.github.io/zz85-bookmarklets/threelabs.htmlhttp://idflood.github.io/ThreeNodes.js/https://www.youtube.com/watch?v=Dir4KO9RdhMhttp://yomotsu.github.io/threejs-examples/http://fhtr.org/BasicsOfThreeJS/#1http://github.com/kig/http://www.slideshare.net/yomotsu/webgl-and-threejshttp://github.com/yomotsuhttp://bkcore.com/blog/general/adobe-user-group-nl-talk-video-hexgl.htmlhttps://github.com/BKcorehttp://www.youtube.com/watch?v=VdQnOaolrPAhttps://github.com/jareikohttp://blackjk3.github.io/threefab/http://bkcore.com/blog/3d/webgl-three-js-workflow-tips.htmlhttps://github.com/BKcorehttp://12devsofxmas.co.uk/2012/01/webgl-and-three-js/http://github.com/nrocy

  • СЛЕДУЮЩИЕДЕЙСТВИЯ

    Какэтовсеобновлять

    Всеобъектыпоумолчаниюавтоматическиобновляютсвоиматрицы,еслибылидобавленынасценуприпомощиvarobject=newTHREE.Object3D;scene.add(object);

    илиеслиониявляютсядочернимипоотношениюкдругомуобъекту,ужедобавленномунасцену:varobject1=newTHREE.Object3D;varobject2=newTHREE.Object3D;

    object1.add(object2);scene.add(object1);//object1andobject2willautomaticallyupdatetheirmatrices//object1иobject2будутавтоматическиобновлятьсвоиматрицы

    Впрочем,еслиизвестночтообъектбудетстатичным,можнозапретитьавтоматическоеобновлениеиобновлятьматрицутрансформациивручную,когдапотребуется.object.matrixAutoUpdate=false;object.updateMatrix();

  • GeometriesПримечаниепереводчика:Здесьрассматриваетсяобновлениегеометрическихпараметровобъекта,т.е.вершины,грани,ихрасположение,нормали,цветаит.д.

    BufferGeometry

    BufferGeometriesсохраняютинформацию(такуюкакположениевершин,индексыграней,нормали,цвета,текстурныекоординаты(икоординатаминатекстуре(U,V-этибуквыобозначаютосидвумернойтекстуры,потомучто«X»,«Y»и«Z»ужеиспользуютсядляобозначенияосей3D-объектавпространствемодели).ЗначенияUиVобычноизменяютсяот0до1.');"onmouseout="hide()">UV)ивсеатрибуты,установленныепользователем)вбуферах,которыеявляютсятипизованнымимассивами(здесьописаниеэтихмассивовнарусскомязыке).ЭтоделаетработуBufferGeometriesвобщем-тобыстрее,посравнениюсобычнымиGeometriesзасчеттого,чтоснимисложнееработать.

    ЧтокасаетсяобновленияBufferGeometries,тосамоеглавноедляпонимания,нестоитизменятьразмербуферов(этооченьзатратно,посуществуравнозначносозданиюновойгеометрии).Однакоможнообновлятьсодержимоебуферов.

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

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

    https://ru.wikipedia.org/wiki/UV-%D0%BF%D1%80%D0%B5%D0%BE%D0%B1%D1%80%D0%B0%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrayshttps://developer.mozilla.org/ru/docs/Web/JavaScript/Typed_arrayshttps://en.wikipedia.org/wiki/Shader

  • для500вершин,носначала,припомощиметодаBufferGeometry.drawRange,нарисуемтолькодве.varMAX_POINTS=500;

    //geometry(геометрия)vargeometry=newTHREE.BufferGeometry();

    //attributes(атрибуты)varpositions=newFloat32Array(MAX_POINTS*3);//3verticesperpoint(3вершинынаточку)geometry.addAttribute('position',newTHREE.BufferAttribute(positions,3));

    //drawrange(рисуемрядточек)vardrawCount=2;//drawthefirst2points,only(рисуемтолькопервыедветочки)geometry.setDrawRange(0,drawCount);

    //material(материал)varmaterial=newTHREE.LineBasicMaterial({color:0xff0000,linewidth:2});

    //line(линия)varline=newTHREE.Line(geometry,material);scene.add(line);

    Далеебудемслучайнымобразомдобавлятьточкиклинииприпомощишаблонаввиде:varpositions=line.geometry.attributes.position.array;

    varx,y,z,index;x=y=z=index=0;

    for(vari=0,l=MAX_POINTS;i<l;i++){

    positions[index++]=x;positions[index++]=y;positions[index++]=z;

    x+=(Math.random()-0.5)*30;y+=(Math.random()-0.5)*30;z+=(Math.random()-0.5)*30;

    }

    Еслинужноизменитьколичествоточек,отображаемыхпослепервойвизуализации,сделайтеследующее:line.geometry.setDrawRange(0,newValue);

    Если,послепервойвизуализации,нужноизменитьзначенияданных

  • положения,следуетустановитьфлагneedsUpdate,воттак:line.geometry.attributes.position.needsUpdate=true;//requiredafterthefirstrender(запрашиваетсяпослепервойвизуализации)

    ВотпУтанка,представленнаяанимированнойлинией,которуюможноприспособитьподсвоинужды.

    Примеры:WebGL/custom/attributesWebGL/buffergeometry/custom/attributes/particles

    Geometry

    Следующиефлагиуправляютобновлениемразличныхатрибутовгеометрии.Устанавливайтефлагитолькодляатрибутов,требующихобновления,таккакобновления-затратнаявещь.Послеизменениябуферовэтифлагиавтоматическисбрасываютсяобратнокзначениюfalse.Еслитребуетсяпродолжатьобновлениебуферов,нужносохранитьихкакtrue.Обратитевнимание,чтоэтоотноситсятолькокGeometry,анекBufferGeometry.vargeometry=newTHREE.Geometry();geometry.verticesNeedUpdate=true;geometry.elementsNeedUpdate=true;geometry.morphTargetsNeedUpdate=true;geometry.uvsNeedUpdate=true;geometry.normalsNeedUpdate=true;geometry.colorsNeedUpdate=true;geometry.tangentsNeedUpdate=true;

    Кромеэтого,вверсиях,предшествующихr66,сеткам(mesh)необходимовключатьфлагdynamic(длясохранениявнутреннихтипизованныхмассивов)://removedafterr66(удаляетсяпослеверсииr66)geometry.dynamic=true;

    Пример:WebGL/geometry/dynamic

    http://jsfiddle.net/w67tzfhx/https://threejs.org/examples/#webgl_custom_attributeshttps://threejs.org/examples/#webgl_buffergeometry_custom_attributes_particleshttps://github.com/mrdoob/three.js/releases/tag/r66https://threejs.org/examples/#webgl_geometry_dynamic

  • Материалы

    ВсеоднотипныезначениямогутбытьсвободноизмененыAlluniformsvaluescanbechangedfreely(например,цвета,текстуры,непрозрачностьитакдалее),значенияотправляютсявшейдерскаждымкадром.valuesaresenttotheshadereveryframe.Примечаниепереводчика:Вобластикомпьютернойграфики,шейдер-этокомпьютернаяпрограмма...читатьдалее

    ПараметрысвязанныесGLstateтакжемогутбытьизмененывлюбоймомент(depthTest,blending,polygonOffset,ит.д.).

    Плоское(flat)/плавное(smooth)shadingisbakedintonormals.Требуетсясбросбуферанормалей(смотритевыше).

    Следующиесвойстванельзяпростотакизменитьвовремявыполнения(послетого,какматериалбылвизуализированхотябыраз):

    типыичислоuniformsтипыичислоисточниковосвещенияналичиеилиотсутствие

    текстуры(texture)тумана(fog)цветавершин(vertexcolors)

    созданиякожи,встречаетсятакженаписаниескиннинг)-этоодинизэтаповпостановки3d-персонажа,когдамодельперсонажапривязывается(скинится)кскелету.'+'Делаетсяэтодлятого,чтобыпридвижениискелетадвигаласьисамамодельперсонажа.'+'Этодостаточнотрудоемкийпроцесс,посколькунужноправильноназначитьвес(англ.weight)длякаждойвершинымодели.Чембольшевес,тембольшевлияетконкретнаякостьнаконкретнуювершину3d-модели.');"

  • onmouseout="hide()">скининга(skinning)

    анимации,визуальныйэффект,создающийвпечатлениеплавнойтрансформацииодногообъектавдругой.Встречаетсявтрёхмернойидвухмерной(какрастровой,такивекторной)графике.'+'Длясозданияэффектаиспользуютсякакминимумдваизображения,накоторыххудожникзадаётвзависимостиотиспользующегосяпрограммногообеспеченияопорныефигурыилиключевыеточки(т.н.маркеры,илиметки),которыепомогаюткомпьютерувыполнитьправильныйморфинг,тоестьсоздатьизображенияпромежуточныхсостояний(интерполируяимеющиесяданные).'+'Морфингтакжечастоиспользуетсядлясозданияанимации,когданестоитзадачадобитьсяэффектапревращенияодногообъектавдругой,атребуетсялишьвыстроитьпромежуточныесостояниямеждудвумя(иболее)ключевымиположениямианимируемогообъекта.');"onmouseout="hide()">морфинга(morphing)теневойкарты(shadowmap)

    векторцветавформатеRGBA.Альфа-компонентопределяетнепрозрачностьматериалавдиапазонеот1.0означающегополнуюнепрозрачностьдо0.0,означающегополнуюпрозрачность.'+'Длятогочтобысоздаватьпрозрачныеиполупрозрачныеобъекты,необходиморазрешитьтестироватьбуферальфа-каналаивключить

  • механизмподназваниемальфа-смешивание.'+'Привключённомальфа-тестесравниваетсявходящеезначениеальфа-каналасэталоннымзначением.Фрагментпринимаетсяилиотклоняетсявзависимостиотрезультатовсравнения.');"onmouseout="hide()">альфа-теста(alphatest)

    Изменениявнихтребуютсозданияновойшейдернойпрограммы.Нужнобудетустановитьmaterial.needsUpdate=true

    Имейтеввиду,чтоэтоможетбытьдовольномедленноивызыватьподергиваниекадров(особенновWindows,посколькушейдернаякомпиляциявDirectXмедленнее,чемвOpenGL).

    Дляповышенияплавностиработыможновнекоторойстепениимитироватьизмененияэтихфункций,спомощью«фиктивных»значений,такихкакосвещениеснулевойинтенсивностью,белыхтекстурилитуманаснулевойплотностью.

    Можносвободноизменятьматериал,используемыйдлячастейгеометрии,однаконельзяизменятьспособразделенияобъектаначасти(всоответствиисматериаламиграни).Youcanfreelychangethematerialusedforgeometrychunks,howeveryoucannotchangehowanobjectisdividedintochunks(accordingtofacematerials).Есливовремявыполнениянужныразныеконфигурацииматериалов:Есличисломатериалов/частейневелико,можнозаблаговременнопредварительноразделитьобъект(например,длячеловека-волосы(hair)/лицо(face)/тело(body)/верхняяодежда(upperclothes)/брюки(trousers),дляавтомобиля-перед(front)/боковыестороны(sides)/верх(top)/стекла(glass)/шины(tire)/салон(interior)).

    Есличисловелико(кпримерукаждоелицо/граньможетбытьпотенциальноразличным),рассмотритедругоерешение,такоекакиспользованиеатрибутов/текстурдляприведениякдругомувнешнемувиду.Примеры:

  • WebGL/materials/carsWebGL/webgl_postprocessing/dof

    Текстуры

    Еслитекстурыизображения,элементаcanvas,видеоиданныхбылиизменены,тоунихдолженбытьустановленследующийфлаг:Image,canvas,videoanddatatexturesneedtohavethefollowingflagsetiftheyarechanged:texture.needsUpdate=true;

    Обновлениецелейвизуализациипроизойдетавтоматически.Rendertargetsupdateautomatically.Примеры:WebGL/materials/videoWebGL/rtt

    Камеры

    Положениевпространствеинаправлениесъемкикамерыобновляютсяавтоматически.Еслинужноизменитьпараметры

    fov(полепросмотра)aspect(соотношениесторон)near(ближняяплоскостьотсечения)far(дальняяплоскостьотсечения)

    тотребуетсяпересчитатьматрицупроекции:camera.aspect=window.innerWidth/window.innerHeight;camera.updateProjectionMatrix();

    https://threejs.org/examples/#webgl_materials_carshttps://threejs.org/examples/#webgl_postprocessing_dofhttps://threejs.org/examples/webgl_materials_videohttps://threejs.org/examples/webgl_rtt

  • Матричныепреобразования

    Вthree.jsдлякодирования3-мерныхпреобразований-перемещения(измененияположения),вращенияимасштабированияиспользуютсяматрицы.КаждыйэкземплярObject3Dимеетсвойствоmatrix,вкоторомхранитсяположение,уголповоротаимасштабэтогообъекта.Наэтойстраницеописываетсякакобновлятьпреобразование(трансформацию)объекта.ПреимуществасвойствиmatrixAutoUpdateСуществуетдваспособаобновленияпреобразованияобъекта:

    1. Изменитьсвойстваобъектаposition,quaternionиscale,ипозволитьThree.jsпересчитатьматрицуобъектасэтимисвойствами:object.position.copy(start_position);object.quaternion.copy(quaternion);

    Поумолчанию,свойствоmatrixAutoUpdateустанавливаетсяравнымtrue,такчтоматрицабудетпересчитанаавтоматически.Еслиобъектстатиченилинужновручнуюопределятькогдабудетпроисходитьпересчетматрицы,наилучшуюпроизводительностьможнополучитьустановкойэтогосвойствакакfalse:object.matrixAutoUpdate=false;

    Ипослеизменениякаких-либосвойств,вручнуюобновитьматрицу:object.updateMatrix();

    2. Непосредственноизменитьматрицуобъекта.КлассMatrix4имеетразличныеметодыдляизмененияматрицы:object.matrix.setRotationFromQuaternion(quaternion);object.matrix.setPosition(start_position);object.matrixAutoUpdate=false;

    Обратитевнимание,чтовэтомслучаесвойствоmatrixAutoUpdateдолжнобытьустановленокакfalse,приэтомследуетубедиться,чтонебыловызоваupdateMatrix.ВызовupdateMatrixперебьетизмененияматрицы,сделанныевручную,пересчитавматрицудля

  • position,scaleитакдалее.

    МатрицыобъектаиworldAnobject's[page:Object3D.matrixmatrixstorestheobject'stransformationrelativetotheobject's[page:Object3D.parentparent;togettheobject'stransformationinworldcoordinates,youmustaccesstheobject's[page:Object3D.matrixWorld.

    ПриизмененияхвпреобразованииродительскогоилидочернегообъектаможнозапроситьобновлениесвойстваmatrixWorldдочернегообъектавызовомметодаupdateMatrixWorld.ВращениеикватернионыThree.jsпредоставляетдваспособапредставлениятрехмерныхвращений:углыЭйлераиQuaternions,атакжеметодыконвертированиямеждуними.Three.jsprovidestwowaysofrepresenting3Drotations:EuleranglesandQuaternions,aswellasmethodsforconvertingbetweenthetwo.Euleranglesaresubjecttoaproblemcalled"gimballock,"wherecertainconfigurationscanloseadegreeoffreedom(preventingtheobjectfrombeingrotatedaboutoneaxis).Поэтойпричине,вращениеобъектавсегдасохраняетсявегосвойствеquaternion.Forthisreason,objectrotationsarealwaysstoredintheobject'squaternion.

    ПредыдущиеверсиибиблиотекивключаливсебясвойствоuseQuaternion,которое,будучиустановленноекакfalse,приводилокрасчетуматрицыобъектаизугловЭйлера.Этапрактикаустарела-взаменследуетиспользоватьметодsetRotationFromEulermethod,whichwillupdatethequaternion.

  • Системаанимации

    Обзор

    Врамкаханимационнойсистемыthree.jsможноанимироватьразличныесвойствамодели:кости(bone)skinnedandriggedmodel,целиморфинга(morphtargets),различныесвойстваматериала(цвета,непрозрачность,логику),видимостьипреобразования.Свойствамианимациимогутбытьпостепенноепоявление(fadedin),постепенноеисчезновение(fadedout),плавноепоявлениенафонеплавногоисчезновения(crossfaded)идеформация(warped).«Веса́»(weight)ивременны́емасштабы(timescales)различныходновременныханимацийкакнаодномитомжеобъекте,такинаразныхобъектах,могутбытьизмененынезависимодруготдруга.Можносинхронизироватьразличныеанимациикакнаодномитомжеобъекте,такинаразныхобъектах.

    Чтобыдостичьвсегоэтоговединственнойоднороднойсистеме,системаанимацииthree.jsполностьюизмениласьв2015году(помнитеобустаревшейинформации!),итеперьегоархитектура,походитнаUnity/UnrealEngine4.Наэтойстраницедаетсякраткийобзоросновныхкомпонентовэтойсистемыиспособовихсовместнойработы.

    https://github.com/mrdoob/three.js/issues/6881

  • АнимационныеклипыAnimationClips

    Еслиимеетсяуспешноимпортированныйанимированный3Dобъект(неважноимеютсяливнемкостиилицелиморфинга,илиитоидругое)-например,экспортированныйизBlender'аспомощьюBlenderexporterизагруженныйнасценуthree.jsзагрузчикомJSONLoader,-тооднимизсвойствгеометриизагружаемойсетки(mesh)долженбытьмассив,поименованныйкак"animations",содержащийAnimationClip'ыдляданноймодели(смотритенижесписоквозможныхзагрузчиков).Ifyouhavesuccessfullyimportedananimated3Dobject(itdoesn'tmatterifithasbonesormorphtargetsorboth)-forexampleexportingitfromBlenderwiththe[link:https://github.com/mrdoob/three.js/tree/master/utils/exporters/blender/addons/io_threeBlenderexporter]andloadingitintoathree.jssceneusing[page:JSONLoader]-,oneofthegeometry'spropertiesoftheloadedmeshshouldbeanarraynamed"animations",containingthe[page:AnimationClipAnimationClips]forthismodel(seealistofpossibleloadersbelow).

    Каждый«AnimationClip»обычносодержитданныедляопределеннойактивностиобъекта.Еслисеткой,напримерявляетсяперсонаж,тодляциклаходьбыможетбытьодинAnimationClip,дляпрыжка-второй,третийдляуклонениявсторонуитакдалее.Each*AnimationClip*usuallyholdsthedataforacertainactivityoftheobject.Ifthemeshisacharacter,forexample,theremaybeoneAnimationClipforawalkcycle,asecondforajump,athirdforsidesteppingandsoon.

    ТрекиключевыхкадровKeyframeTracks

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

    https://github.com/mrdoob/three.js/tree/master/utils/exporters/blender/addons/io_three

  • Предположим,чтоумоделиимеютсяцелиморфинга(например,однацельморфингапоказываетприветливоелицо,адругая-сердитое),каждыйтрекхранитсведенияотом,каквоздействие(influence)некоторойцелиморфингаизменяетсявовремявыполненияклипа.Assumedthemodelhas[page:Geometry.morphTargetsmorphtargets](forexampleonemorphtargetshowingafriendlyfaceandanothershowinganangryface),eachtrackholdstheinformationastohowthe[page:Mesh.morphTargetInfluencesinfluence]ofacertainmorphtargetchangesduringtheperformanceoftheclip.

    Микшеранимации(AnimationMixer)

    Сохраненныеданныеформируюттолькоосновуанимации-фактическоевоспроизведениеконтролируетсяAnimationMixer.Можнопредставитьэтонетолькокакигрокадляанимации,ноикаксимуляциюаппаратногообеспечения,например,реальноймикшернойконсоли,котораяможетодновременноуправлятьнесколькимианимациями,смешиваяиобъединяяих.Thestoreddataformonlythebasisfortheanimations-actualplaybackiscontrolledbythe[page:AnimationMixer].Youcanimaginethisnotonlyasaplayerforanimations,butasasimulationofahardwarelikearealmixerconsole,whichcancontrolseveralanimationssimultaneously,blendingandmergingthem.

    Действияанимации(AnimationActions)

    Собственносам«AnimationMixer»имееттолькооченьмало(общих)свойствиметодов,потомучтоимможноуправлятьспомощьюAnimationActions.The*AnimationMixer*itselfhasonlyveryfew(general)propertiesandmethods,becauseitcanbecontrolledbythe[page:AnimationActionAnimationActions].Настройкой«AnimationAction»можноопределятькогдаконкретный«AnimationClip»будетвоспроизводиться,устанавливатьсявпаузуилибытьостановленнымнаодномизмикшеров,будетлионповторятьсяиеслибудет,какчасто,долженлионвыполнятьсяс

  • затуханиемилимасштабироватьсяповремени,идругимидополнительнымиособенностямивродекроссфейдингаилисинхронизации.Byconfiguringan*AnimationAction*youcandeterminewhenacertain*AnimationClip*shallbeplayed,pausedorstoppedononeofthemixers,ifandhowoftenthecliphastoberepeated,whetheritshallbeperformedwithafadeoratimescaling,andsomeadditionalthings,suchcrossfadingorsynchronizing.

    Анимациягруппобъектов

    Еслинужночтобыгруппаобъектовприобреласовместноиспользуемоесостояниеанимации,можноиспользоватьAnimationObjectGroup.

    Поддерживаемыеформатыизагрузчики

    Обратитевнимание,невсеформатымоделейвключаютанимацию(вчастностиOBJневключает),ичтотольконекоторыезагрузчикиthree.jsподдерживаютпоследовательностиAnimationClip.Notethatnotallmodelformatsincludeanimation(OBJnotablydoesnot),andthatonlysomethree.jsloaderssupport[page:AnimationClipAnimationClip]sequences.Severalthatdosupportthisanimationtype:

    THREE.JSONLoaderTHREE.ObjectLoaderTHREE.BVHLoaderTHREE.FBXLoaderTHREE.GLTF2LoaderTHREE.MMDLoaderTHREE.SEA3DLoader

    Обратитевнимание,чтовнастоящеевремя3dsmaxиMayaнемогутэкспортироватьнесколькоанимаций(тоесть,анимаций,которыененаходятсянаодномитомжевременномпромежутке)непосредственноводинфайл.Примерvarmesh;

    //CreateanAnimationMixer,andgetthelistofAnimationClipinstances

  • //СоздаемAnimationMixerиполучаемсписокэкземпляровAnimationClipvarmixer=newTHREE.AnimationMixer(mesh);varclips=mesh.animations;

    //Updatethemixeroneachframe(обновляеммикшервкаждомкадре)functionupdate(){ mixer.update(deltaSeconds);}

    //Playaspecificanimation(проигрываемконкретнуюанимацию)varclip=THREE.AnimationClip.findByName(clips,'dance');varaction=mixer.clipAction(clip);action.play();

    //Playallanimations(проигрываемвсеанимации)clips.forEach(function(clip){ mixer.clipAction(clip).play();});

  • Сборочныеинструменты

    Проверкаспомощью—менеджерпакетов,входящийвсоставNode.js');"onmouseout="hide()">

    Вданнойстатьерассказываетсякакполучитьthree.jsвсредеnode.js,такчтобыможнобыловыполнятьавтоматическиепроверки.Тестированиеможнозапускатьизкоманднойстрокиилиспомощьюавтоматизированныхинструментовнепрерывнойинтеграциинепрерывнаяинтеграция—этопрактикаразработкипрограммногообеспечения,котораязаключаетсявслияниирабочихкопийвобщуюосновнуюветвьразработкинесколькоразвденьивыполнениичастыхавтоматизированныхсборокпроектадляскорейшеговыявленияирешенияинтеграционныхпроблем.');"onmouseout="hide()">(CI),вродеTravis.БолееподробнопронепрерывнуюинтеграциюможнопосмотретьвВикипедииилинаХабрахабре.

    Сокращенныйвариант

    Есливампривычнаработасnodeиnpm,$npminstallthree--save-dev

    иксвоейпроверкедобавьтеvarTHREE=require('three');

    Созданиепроектадлятестированияснуля

    Еслиэтиинструментывамнезнакомы,воткраткоеруководство(дляLinuxпроцессустановкибудетнемногоотличатьсяотработывWindows,нокомандыnpmидентичны).

    Basicsetup1. Устанавливаемnpmиnode.js.Кратчайшийпутьобычно

    выглядитприблизительнотак$sudoapt-getinstall-ynpmnodejs-legacy#fixanyproblemswithSSLinthedefaultregistryURL$npmconfigsetregistryhttp://registry.npmjs.org/

    https://nodejs.org/en/https://travis-ci.org/https://ru.wikipedia.org/wiki/%D0%9D%D0%B5%D0%BF%D1%80%D0%B5%D1%80%D1%8B%D0%B2%D0%BD%D0%B0%D1%8F_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D1%86%D0%B8%D1%8Fhttps://habrahabr.ru/post/190412/https://www.npmjs.org/

  • 2. Делаемкаталогновогопроекта$mkdirtest-example;cdtest-example

    3. Запрашиваемnpmдлясозданияфайлановогопроектаtocreateanewprojectfileforyou:$npminit

    andacceptalldefaultsbyhittingEnteronalltheprompts.Thiswillcreatepackage.json.

    4. Tryandstartthetestfeaturewith$npmtest

    Thiswillfail,whichisexpected.Ifyoulookinthepackage.json,thedefinitionofthetestscriptis"test":"echo\"Error:notestspecified\"&&exit1"

    ДобавляеммногофункциональнаясредадлятестированияJavaScript,работающаянаNode.jsивбраузере,чтоделаетасинхронноетестированиепростымиинтересным.'+'ТестированиеMochaзапускаетсяпоочередно,позволяягибкоиточносообщать,атакжесопоставлятьнеперехваченныеисключениясправильнымитестовымипримерами.');"onmouseout="hide()">mocha

    Будемиспользоватьmocha.1. Устанавливаемmochaспомощью

    $npminstallmocha--save-dev

    Обратитевнимание,чтоnode_modules/созданивсезависимостиокажутьсятам.Такжеотметьте,чтоpackage.jsonбылобновлен:добавленоиобновленосвойствоdevDependenciesприпомощи--save-dev.Noticethatnode_modules/iscreatedandyourdependenciesappearinthere.Alsonoticethatyourpackage.jsonhasbeenupdated:thepropertydevDependenciesisaddedandupdatedbytheuseof--save-dev.

    2. Editpackage.jsontousemochafortesting.Whentestisinvoked,wejustwanttorunmochaandspecifyaverbose

    https://mochajs.org/

  • reporter.Bydefaultthiswillrunanythingintest/(nothavingdirectorytest/canrunintonpmERR!,createitbymkdirtest)"test":"mocha--reporterlist"

    3. Перезапускаемтестспомощью$npmtest.

    Теперьондолженбытьуспешным,Thisshouldnowsucceed,reporting0passing(1ms)orsimilar.

    Добавлениеthree.js

    1. Let'spullinourthree.jsdependencywith$npminstallthree--save-dev

    Еслинужнадругаяверсияthree.js,используйте$npmshowthreeversions

    чтобыпосмотреть,какаядоступна.toseewhat'savailable.Totellnpmtherightone,[email protected]

    (0.84.0inthisexample).--savemakesthisadependencyofthisproject,ratherthandevdependency.Дляболееподробныхсведенийсмотритедокументациюздесь.

    2. Mochawilllookfortestsintest/,solet's$mkdirtest.

    3. FinallyweactuallyneedaJStesttorun.Let'saddasimpletestthatwillverifythatthethree.jsobjectisavailableandworking.Createtest/verify-three.jscontaining:varTHREE=require('three');varassert=require("assert");

    describe('TheTHREEobject',function(){it('shouldhaveadefinedBasicShadowMapconstant',function(){assert.notEqual('undefined',THREE.BasicShadowMap);}),

    it('shouldbeabletoconstructaVector3withdefaultofx=0',function(){varvec3=newTHREE.Vector3();assert.equal(0,vec3.x);})})

    https://www.npmjs.org/doc/json.html

  • 4. Finallylet'stestagainwith$npmtest.Thisshouldrunthetestsaboveandsucceed,showingsomethinglike:TheTHREEobjectshouldhaveadefinedBasicShadowMapconstant:0msTheTHREEobjectshouldbeabletoconstructaVector3withdefaultofx=0:0ms2passing(8ms)

    Добавляемсвойсобственныйкод

    Нужносделатьтривещи:1. Написатьтестдляожидаемогоповедениясвоегокодаи

    разместитьеговtest/.Вотпримеризреальногопроекта.2. Экспортируйтесвойдействующийкодтакимобразом,

    чтобыnodejsмогеговидеть,дляиспользованиявсочетаниисrequire.Смотритепримерздесь.Exportyourfunctionalcodeinsuchawaythatnodejscanseeit,foruseinconjunctionwithrequire.Seeit[link:https://github.com/air/encounter/blob/master/js/Physics.jshere].

    3. Requireyourcodeintothetestfile,inthesamewaywedidarequire('three')intheexampleabove.

    Пункты2и3будутзависетьоттого,каквыуправляетесвоимкодом.ВпримереPhysics.js,приведенномниже,Items2and3willvarydependingonhowyoumanageyourcode.IntheexampleofPhysics.jsgivenabove,theexportpartisrightattheend.Weassignanobjecttomodule.exports://=============================================================================//makeavailableinnodejs//=============================================================================if(typeofexports!=='undefined'){module.exports=Physics;}

    РаботасзависимостямиЕсливыужепользовалисьчем-тоумным,вродеОноптимизировандляработывбраузере,номожетиспользоватьсяивдругихсредахJavaScript,вродеRhinoиNode.Использованиемодульногозагрузчикаскрипта,подобногоRequireJS,повышаетскорость

    https://github.com/air/encounter/blob/master/test/Physics-test.jshttps://github.com/air/encounter/blob/master/js/Physics.jshttp://requirejs.org/

  • икачествокода.');"onmouseout="hide()"target="_blank">require.jsилиbrowserify,пропуститеэтучасть.

    Обычно,проектthree.jsзапускаетсявбраузере.Следовательно,загрузкамодулябраузеромвыполняетмножествоскриптовыхтегов.Отдельныефайлыпроектанедолжныбеспокоитьсяозависимостях.Moduleloadingishencedonebythebrowserexecutingabunchofscripttags.Yourindividualfilesdon'thavetoworryaboutdependencies.Однако,вконтекстеnodejsнетфайлаindex.html,увязывающеговсевместе,такчтоInanodejscontexthowever,thereisnoindex.htmlbindingeverythingtogether,soyouhavetobeexplicit.

    Еслиэкспортируетсямодуль,зависящийотдругихфайлов,нужноуказатьnodeоихзагрузке.Вотодинизподходов:

    1. Вначалекодамодуляпроверьте,находитесьливывсредеnode.js.

    2. Еслиэтотак,явнообъявитезависимости.3. Еслинет,товероятновывбраузере,такчтоболь