Post on 03-Jun-2020
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,use$npminstallthree@0.84.0--save
(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. Еслинет,товероятновывбраузере,такчтоболь