threepipe
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

README.md 200KB

hace 2 años
hace 2 años
hace 2 años
hace 2 años
hace 2 años
hace 2 años
hace 2 años
hace 2 años
hace 2 años
hace 2 años
hace 2 años
hace 2 años
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191
  1. # ThreePipe
  2. A new way to work with three.js, 3D models and rendering on the web.
  3. [ThreePipe](https://threepipe.org/) —
  4. [Github](https://github.com/repalash/threepipe) —
  5. [Examples](https://threepipe.org/examples/) —
  6. [API Reference](https://threepipe.org/docs/) —
  7. [WebGi](https://webgi.xyz/docs/)
  8. [![NPM Package](https://img.shields.io/npm/v/threepipe.svg)](https://www.npmjs.com/package/threepipe)
  9. [![Discord Server](https://img.shields.io/discord/956788102473584660?label=Discord&logo=discord)](https://discord.gg/apzU8rUWxY)
  10. [![License: Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-green.svg)](https://opensource.org/license/apache-2-0/)
  11. [![Twitter](https://img.shields.io/twitter/url/https/twitter.com/repalash.svg?style=social&label=Follow%20%40repalash)](https://twitter.com/repalash)
  12. ThreePipe is a 3D framework built on top of [three.js](https://threejs.org/) in TypeScript with a focus on rendering quality, modularity, and extensibility.
  13. Key features include:
  14. - Simple, intuitive API for creating 3D model viewers/configurators/editors on web pages, with many built-in presets for common workflows and use-cases.
  15. - Companion [editor](https://threepipe.org/examples/tweakpane-editor/) to create, edit and configure 3D scenes in the browser.
  16. - Modular architecture that allows you to easily extend the viewer, scene objects, materials, shaders, rendering, post-processing and serialization with custom functionality.
  17. - Plugin system along with a rich library of built-in plugins that allows you to easily add new features to the viewer.
  18. - [uiconfig](https://github.com/repalash/uiconfig.js) compatibility to automatically generate configuration UIs in the browser.
  19. - Modular rendering pipeline with built-in deferred rendering, post-processing, RGBM HDR rendering, etc.
  20. - Material extension framework to modify/inject/build custom shader code into existing materials at runtime from plugins.
  21. - Extendable asset import, export and management pipeline with built-in support for gltf, glb, obj+mtl, fbx, materials(pmat/bmat), json, zip, png, jpeg, svg, webp, ktx2, ply, 3dm and many more.
  22. - Automatic serialization of all viewer and plugin settings in GLB(with custom extensions) and JSON formats.
  23. - Automatic disposal of all three.js resources with built-in reference management.
  24. ## Examples
  25. Code samples and demos covering various usecases and test are present in the [examples](./examples/) folder.
  26. Try them: https://threepipe.org/examples/
  27. View the source code by pressing the code button on the top left of the example page.
  28. To make changes and run the example, click on the CodePen button on the top right of the source code.
  29. ## Table of Contents
  30. - [ThreePipe](#threepipe)
  31. - [Examples](https://threepipe.org/examples/)
  32. - [Table of Contents](#table-of-contents)
  33. - [Getting Started](#getting-started)
  34. - [HTML/JS Quickstart (CDN)](#htmljs-quickstart-cdn)
  35. - [React](#react)
  36. - [Vue.js](#vuejs)
  37. - [Svelte](#svelte)
  38. - [NPM/YARN Package](#npmyarn)
  39. - [Installation](#installation)
  40. - [Loading a 3D Model](#loading-a-3d-model)
  41. - [License](#license)
  42. - [Status](#status)
  43. - [Documentation (API Reference)](#documentation)
  44. - [WebGi](#webgi)
  45. - [Contributing](#contributing)
  46. - [Features](#features)
  47. - [File Formats](#file-formats)
  48. - [Loading files](#loading-files)
  49. - [3D models](#3d-models)
  50. - [Materials](#materials)
  51. - [Images/Textures](#imagestextures)
  52. - [zip files](#zip-files)
  53. - [txt, json files](#txt-json-files)
  54. - [Data URLs](#data-urls)
  55. - [Local files, File and Blob](#local-files-file-and-blob)
  56. - [Background, Environment maps](#background-environment-maps)
  57. - [SVG strings](#svg-strings)
  58. - [Exporting files](#exporting-files)
  59. - [Exporting 3D models](#exporting-3d-models)
  60. - [Exporting Materials](#exporting-materials)
  61. - [Exporting Canvas Images](#exporting-canvas-images)
  62. - [Exporting Images/Textures](#exporting-imagestextures)
  63. - [Exporting Render Targets](#exporting-render-targets)
  64. - [Render Pipeline](#render-pipeline)
  65. - [Material Extension](#material-extension)
  66. - [UI Configuration](#ui-configuration)
  67. - [Serialization](#serialization)
  68. - [Plugin System](#plugin-system)
  69. - [Viewer API](#viewer-api)
  70. - [ThreeViewer](#threeviewer)
  71. - [RenderManager](#rendermanager)
  72. - [RootScene](#rootscene)
  73. - [ICamera](#icamera)
  74. - [AssetManager](#assetmanager)
  75. - [AssetImporter](#assetimporter)
  76. - [AssetExporter](#assetexporter)
  77. - [MaterialManager](#materialmanager)
  78. - [Other classes and interfaces](#other-classes-and-interfaces)
  79. - [Plugins](#threepipe-plugins)
  80. - [TonemapPlugin](#tonemapplugin) - Add tonemap to the final screen pass
  81. - [DropzonePlugin](#dropzoneplugin) - Drag and drop local files to import and load
  82. - [ProgressivePlugin](#progressiveplugin) - Post-render pass to blend the last frame with the current frame
  83. - [SSAAPlugin](#ssaaplugin) - Add Super Sample Anti-Aliasing by applying jitter to the camera.
  84. - [DepthBufferPlugin](#depthbufferplugin) - Pre-rendering of depth buffer
  85. - [NormalBufferPlugin](#normalbufferplugin) - Pre-rendering of normal buffer
  86. - [GBufferPlugin](#gbufferplugin) - Pre-rendering of depth-normal and flags buffers in a single pass
  87. - [SSAOPlugin](#ssaoplugin) - Add SSAO(Screen Space Ambient Occlusion) for physical materials.
  88. - [CanvasSnapshotPlugin](#canvassnapshotplugin) - Add support for taking snapshots of the canvas
  89. - [PickingPlugin](#pickingplugin) - Adds support for selecting objects in the viewer with user interactions and selection widgets
  90. - [AssetExporterPlugin](#assetexporterplugin) - Provides options and methods to export the scene, object GLB or Viewer Configuration.
  91. - [LoadingScreenPlugin](#loadingscreenplugin) - Shows a configurable loading screen overlay over the canvas.
  92. - [FullScreenPlugin](#fullscreenplugin) - Adds support for moving the canvas or the container fullscreen mode in browsers
  93. - [InteractionPromptPlugin](#interactionpromptplugin) - Adds an animated hand icon over canvas to prompt the user to interact
  94. - [TransformControlsPlugin](#transformcontrolsplugin) - Adds support for moving, rotating and scaling objects in the viewer with interactive widgets
  95. - [ContactShadowGroundPlugin](#contactshadowgroundplugin) - Adds a ground plane at runtime with contact shadows
  96. - [GLTFAnimationPlugin](#gltfanimationplugin) - Add support for playing and seeking gltf animations
  97. - [PopmotionPlugin](#popmotionplugin) - Integrates with popmotion.io library for animation/tweening
  98. - [CameraViewPlugin](#cameraviewplugin) - Add support for saving, loading, animating, looping between camera views
  99. - [TransformAnimationPlugin](#transformanimationplugin) - Add support for saving, loading, animating, between object transforms
  100. - [RenderTargetPreviewPlugin](#rendertargetpreviewplugin) - Preview any render target in a UI panel over the canvas
  101. - [GeometryUVPreviewPlugin](#geometryuvpreviewplugin) - Preview UVs of any geometry in a UI panel over the canvas
  102. - [FrameFadePlugin](#framefadeplugin) - Post-render pass to smoothly fade to a new rendered frame over time
  103. - [VignettePlugin](#vignetteplugin) - Add Vignette effect by patching the final screen pass
  104. - [ChromaticAberrationPlugin](#chromaticaberrationplugin) - Add Chromatic Aberration effect by patching the final screen pass
  105. - [FilmicGrainPlugin](#filmicgrainplugin) - Add Filmic Grain effect by patching the final screen pass
  106. - [NoiseBumpMaterialPlugin](#noisebumpmaterialplugin) - Sparkle Bump/Noise Bump material extension for PhysicalMaterial
  107. - [CustomBumpMapPlugin](#custombumpmapplugin) - Custom Bump Map material extension for PhysicalMaterial
  108. - [ClearcoatTintPlugin](#clearcoattintplugin) - Clearcoat Tint material extension for PhysicalMaterial
  109. - [FragmentClippingExtensionPlugin](#fragmentclippingextensionplugin) - Fragment/SDF Clipping material extension for PhysicalMaterial
  110. - [ParallaxMappingPlugin](#parallaxmappingplugin) - Relief Parallax Bump Mapping extension for PhysicalMaterial
  111. - [HDRiGroundPlugin](#hdrigroundplugin) - Add support for ground projected hdri/skybox to the webgl background shader.
  112. - [VirtualCamerasPlugin](#virtualcamerasplugin) - Add support for rendering virtual cameras before the main one every frame.
  113. - [EditorViewWidgetPlugin](#editorviewwidgetplugin) - Adds an interactive ViewHelper/AxisHelper that syncs with the main camera.
  114. - [Object3DWidgetsPlugin](#object3dwidgetsplugin) - Automatically create light and camera helpers/gizmos when they are added to the scene.
  115. - [Object3DGeneratorPlugin](#object3dwidgetsplugin) - Provides UI and API to create scene objects like lights, cameras, meshes, etc.
  116. - [DeviceOrientationControlsPlugin](#deviceorientationcontrolsplugin) - Adds a controlsMode to the mainCamera for device orientation controls(gyroscope rotation control).
  117. - [PointerLockControlsPlugin](#pointerlockcontrolsplugin) - Adds a controlsMode to the mainCamera for pointer lock controls.
  118. - [ThreeFirstPersonControlsPlugin](#threefirstpersoncontrolsplugin) - Adds a controlsMode to the mainCamera for first person controls from threejs.
  119. - [GLTFKHRMaterialVariantsPlugin](#gltfkhrmaterialvariantsplugin) - Support using for variants from KHR_materials_variants extension in gltf models.
  120. - [Rhino3dmLoadPlugin](#rhino3dmloadplugin) - Add support for loading .3dm files
  121. - [PLYLoadPlugin](#plyloadplugin) - Add support for loading .ply files
  122. - [STLLoadPlugin](#stlloadplugin) - Add support for loading .stl files
  123. - [KTX2LoadPlugin](#ktx2loadplugin) - Add support for loading .ktx2 files
  124. - [KTXLoadPlugin](#ktxloadplugin) - Add support for loading .ktx files
  125. - [USDZLoadPlugin](#usdzloadplugin) - Add support for loading .usdz files
  126. - [GLTFMeshOptDecodePlugin](#gltfmeshoptdecodeplugin) - Decode gltf files with EXT_meshopt_compression extension.
  127. - [SimplifyModifierPlugin](#simplifymodifierplugin) - Boilerplate for plugin to simplify geometries
  128. - [MeshOptSimplifyModifierPlugin](#meshoptsimplifymodifierplugin) - Simplify geometries using meshoptimizer library
  129. - [Packages](#threepipe-packages)
  130. - [@threepipe/plugin-tweakpane](#threepipeplugin-tweakpane) Tweakpane UI Plugin
  131. - [@threepipe/plugin-blueprintjs](#threepipeplugin-blueprintjs) BlueprintJs UI Plugin
  132. - [@threepipe/plugin-tweakpane-editor](#threepipeplugin-tweakpane-editor) - Tweakpane Editor Plugin
  133. - [@threepipe/plugin-configurator](#threepipeplugin-configurator) - Provides Material Configurator and Switch Node Plugin to allow users to select variations
  134. - [@threepipe/plugin-gltf-transform](#threepipeplugin-gltf-transform) - Plugin to transform gltf models (draco compression)
  135. - [@threepipe/plugins-extra-importers](#threepipeplugins-extra-importers) - Plugin for loading more file types supported by loaders in three.js
  136. - [@threepipe/plugin-blend-importer](#threepipeplugin-blend-importer) - Blender to add support for loading .blend file
  137. - [@threepipe/plugin-geometry-generator](#threepipeplugin-geometry-generator) - Generate parametric geometry types that can be re-generated from UI/API.
  138. - [@threepipe/plugin-gaussian-splatting](#threepipeplugin-gaussian-splatting) - Gaussian Splatting plugin for loading and rendering splat files
  139. - [@threepipe/plugin-network](#threepipeplugin-network) - Network/Cloud related plugin implementations for Threepipe.
  140. - [@threepipe/plugin-svg-renderer](#threepipeplugin-svg-renderer) - Add support for exporting 3d scene as SVG.
  141. ## Getting Started
  142. ### HTML/JS Quickstart (CDN)
  143. ```html
  144. <canvas id="three-canvas" style="width: 800px; height: 600px;"></canvas>
  145. <script type="module">
  146. import {ThreeViewer, DepthBufferPlugin} from 'https://threepipe.org/dist/index.mjs'
  147. const viewer = new ThreeViewer({canvas: document.getElementById('three-canvas')})
  148. // Add some plugins
  149. viewer.addPluginSync(new DepthBufferPlugin())
  150. // Load an environment map
  151. const envPromise = viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr')
  152. const modelPromise = viewer.load('https://threejs.org/examples/models/gltf/DamagedHelmet/glTF/DamagedHelmet.gltf', {
  153. autoCenter: true,
  154. autoScale: true,
  155. })
  156. Promise.all([envPromise, modelPromise]).then(([env, model]) => {
  157. console.log('Loaded', model, env, viewer)
  158. })
  159. </script>
  160. ```
  161. Check it in action: https://threepipe.org/examples/#html-js-sample/
  162. Check out the details about the [ThreeViewer API](#viewer-api) and more [plugins](#threepipe-plugins) below.
  163. ### React
  164. A sample [react](https://react.dev) component in tsx to render a model with an environment map.
  165. ```tsx
  166. import React from 'react'
  167. function ThreeViewerComponent({src, env}: {src: string, env: string}) {
  168. const canvasRef = React.useRef(null)
  169. React.useEffect(() => {
  170. const viewer = new ThreeViewer({canvas: canvasRef.current})
  171. const envPromise = viewer.setEnvironmentMap(env)
  172. const modelPromise = viewer.load(src)
  173. Promise.all([envPromise, modelPromise]).then(([env, model]) => {
  174. console.log('Loaded', model, env, viewer)
  175. })
  176. return () => {
  177. viewer.dispose()
  178. }
  179. }, [])
  180. return (
  181. <canvas id="three-canvas" style={{width: 800, height: 600}} ref={canvasRef} />
  182. )
  183. }
  184. ```
  185. Check it in action: https://threepipe.org/examples/#react-tsx-sample/
  186. Other examples in js: https://threepipe.org/examples/#react-js-sample/ and jsx: https://threepipe.org/examples/#react-jsx-sample/
  187. ### Vue.js
  188. A sample [vue.js](https://vuejs.org/) component in js to render a model with an environment map.
  189. ```js
  190. const ThreeViewerComponent = {
  191. setup() {
  192. const canvasRef = ref(null);
  193. onMounted(() => {
  194. const viewer = new ThreeViewer({ canvas: canvasRef.value });
  195. const envPromise = viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr');
  196. const modelPromise = viewer.load('https://threejs.org/examples/models/gltf/DamagedHelmet/glTF/DamagedHelmet.gltf');
  197. Promise.all([envPromise, modelPromise]).then(([env, model]) => {
  198. console.log('Loaded', model, env, viewer)
  199. })
  200. onBeforeUnmount(() => {
  201. viewer.dispose();
  202. });
  203. });
  204. return { canvasRef };
  205. },
  206. };
  207. ```
  208. Check it in action: https://threepipe.org/examples/#vue-html-sample/
  209. Another example with Vue SFC(Single file component): https://threepipe.org/examples/#vue-sfc-sample/
  210. ### Svelte
  211. A sample [svelte](https://svelte.dev/) component in js to render a model with an environment map.
  212. ```html
  213. <script>
  214. import {onDestroy, onMount} from 'svelte';
  215. import {ThreeViewer} from 'threepipe';
  216. let canvasRef;
  217. let viewer;
  218. onMount(() => {
  219. viewer = new ThreeViewer({canvas: canvasRef});
  220. const envPromise = viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr');
  221. const modelPromise = viewer.load('https://threejs.org/examples/models/gltf/DamagedHelmet/glTF/DamagedHelmet.gltf');
  222. Promise.all([envPromise, modelPromise]).then(([env, model]) => {
  223. console.log('Loaded', model, env, viewer)
  224. })
  225. });
  226. onDestroy(() => viewer.dispose())
  227. </script>
  228. <canvas bind:this={canvasRef} id="three-canvas" style="width: 800px; height: 600px"></canvas>
  229. ```
  230. Check it in action: https://threepipe.org/examples/#svelte-sample/
  231. ### NPM/YARN
  232. ### Installation
  233. ```bash
  234. npm install threepipe
  235. ```
  236. ### Loading a 3D Model
  237. First, create a canvas element in your HTML page:
  238. ```html
  239. <canvas id="three-canvas" style="width: 800px; height: 600px;"></canvas>
  240. ```
  241. Then, import the viewer and create a new instance:
  242. ```typescript
  243. import {ThreeViewer, IObject3D} from 'threepipe'
  244. // Create a viewer
  245. const viewer = new ThreeViewer({canvas: document.getElementById('three-canvas') as HTMLCanvasElement})
  246. // Load an environment map
  247. await viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr')
  248. // Load a model
  249. const result = await viewer.load<IObject3D>('https://threejs.org/examples/models/gltf/DamagedHelmet/glTF/DamagedHelmet.gltf', {
  250. autoCenter: true,
  251. autoScale: true,
  252. })
  253. ```
  254. That's it! You should now see a 3D model on your page.
  255. The 3D model can be opened in the [editor](https://threepipe.org/examples/tweakpane-editor/) to view and edit the scene settings, objects, materials, lights, cameras, post-processing, etc. and exported as a GLB file. All settings are automatically serialized and saved in the GLB file, which can be loaded into the viewer. Any plugins used in the editor can be added to the viewer to add the same functionality. The plugin data is automatically loaded(if the plugin is added) when the model is added to the scene.
  256. The viewer initializes with a Scene, Camera, Camera controls(Orbit Controls), several importers, exporters and a default rendering pipeline. Additional functionality can be added with plugins.
  257. Check out the GLTF Load example to see it in action or to check the JS equivalent code: https://threepipe.org/examples/#gltf-load/
  258. Check out the [Plugins](#plugin-system) section below to learn how to add additional functionality to the viewer.
  259. ## License
  260. The core framework([src](https://github.com/repalash/threepipe/tree/master/src), [dist](https://github.com/repalash/threepipe/tree/master/dist), [examples](https://github.com/repalash/threepipe/tree/master/examples) folders) and any [plugins](https://github.com/repalash/threepipe/tree/master/plugins) without a separate license are under the Free [Apache 2.0 license](https://github.com/repalash/threepipe/tree/master/LICENSE).
  261. Some plugins(in the [plugins](https://github.com/repalash/threepipe/tree/master/plugins) folder) might have different licenses. Check the individual plugin documentation and the source folder/files for more details.
  262. ## Status
  263. The project is in `alpha` stage and under active development. Many features will be added but the core API will not change significantly in future releases.
  264. Check out [WebGi](https://webgi.xyz/) for an advanced tailor-made solution for e-commerce, jewelry, automobile, apparel, furniture etc.
  265. ## Documentation
  266. Check the list of all functions, classes and types in the [API Reference Docs](https://threepipe.org/docs/).
  267. ## WebGi
  268. Check out WebGi - Premium Photo-realistic 3D rendering framework and tools for web applications and online commerce along with custom modules and rendering solutions for e-commerce, jewelry, automobile, apparel, furniture and other retail applications.
  269. [Homepage](https://webgi.xyz/) &mdash; [Docs](https://webgi.xyz/docs/)
  270. [![Twitter](https://img.shields.io/twitter/url/https/twitter.com/repalash.svg?style=social&label=Follow%20%40pixotronics)](https://twitter.com/pixotronics)
  271. ## Contributing
  272. Contributions to ThreePipe are welcome and encouraged! Feel free to open issues and pull requests on the GitHub repository.
  273. # Features
  274. ## File Formats
  275. ThreePipe Asset Manager supports the import of the following file formats out of the box:
  276. * **Models**: gltf, glb, obj+mtl, fbx, drc
  277. * **Materials**: mat, pmat, bmat (json based), registered material template slugs
  278. * **Images**: webp, png, jpeg, jpg, svg, ico, avif, hdr, exr
  279. * **Misc**: json, vjson, zip, txt
  280. Plugins can add additional formats:
  281. * Models
  282. * 3dm - Using [Rhino3dmLoadPlugin](#Rhino3dmLoadPlugin)
  283. * ply - Using [PLYLoadPlugin](#PLYLoadPlugin)
  284. * usdz - Using [USDZLoadPlugin](#USDZLoadPlugin)
  285. * stl - Using [STLLoadPlugin](#STLLoadPlugin)
  286. * ktx - Using [KTXLoadPlugin](#KTXLoadPlugin)
  287. * ktx2 - Using [KTX2LoadPlugin](#KTX2LoadPlugin)
  288. Plugins to support more model formats are available in the package [@threepipe/plugins-extra-importers](#threepipeplugins-extra-importers) including .3ds,
  289. .3mf, .collada, .amf, .bvh, .vox, .gcode, .mdd, .pcd, .tilt, .wrl, .mpd, .vtk, .xyz
  290. ## Loading files
  291. ThreePipe uses the [AssetManager](https://threepipe.org/docs/classes/AssetManager.html) to load files.
  292. The AssetManager has support for loading files from URLs, local files and data URLs.
  293. The AssetManager also adds support for loading files from a zip archive. The zip files are automatically unzipped, and the files are loaded from the zip archive.
  294. [viewer.load()](https://threepipe.org/docs/classes/ThreeViewer.html#load) is a high-level wrapper for loading files from the AssetManager.
  295. It automatically adds the loaded object to the scene and returns a promise that resolves to the loaded object,
  296. the materials are also automatically registered to the material manager.
  297. AssetManager internally uses [AssetImporter](https://threepipe.org/docs/classes/AssetImporter.html),
  298. which provides a low-level API
  299. for managing three.js [LoadingManager](https://threejs.org/docs/#api/en/loaders/LoadingManager)
  300. and adding and registering loaders for different file types.
  301. If the purpose is not to add files to the scene then [viewer.assetManager.importer.import()](https://threepipe.org/docs/classes/AssetImporter.html#import) method can be used
  302. to import files from the `AssetImporter`.
  303. viewer.assetManager.loadImported()](https://threepipe.org/docs/classes/AssetManager.html#loadImported)
  304. can then be called to load the imported files after any processing.
  305. The `viewer.load()`, `viewer.assetManager.addAsset()`
  306. and `viewer.assetManager.addAssetSingle()` methods perform combination of `import` and `loadImported`.
  307. ### 3D models
  308. The 3d models are added to `viewer.scene.modelRoot` on `viewer.load` unless some option is specified.
  309. ```typescript
  310. const objectGlb = await viewer.load<IObject3D>('https://example.com/file.glb')
  311. const objectFbx = await viewer.load<IObject3D>('https://example.com/file.fbx')
  312. const objectObj = await viewer.load<IObject3D>('https://example.com/file.obj') // .mtl referenced in obj is automatically loaded
  313. // ... load any 3d model file as an object
  314. ```
  315. Here, we are casting to [IObject3D](https://threepipe.org/docs/interfaces/IObject3D.html) type
  316. to get the proper type and autocomplete for the object.
  317. `IObject3D` inherits [Object3D](https://threejs.org/docs/#api/en/core/Object3D) from three.js and adds some additional properties.
  318. For JavaScript, the type can be omitted.
  319. ```javascript
  320. const objectGlb = await viewer.load('https://example.com/file.glb')
  321. ```
  322. When loading models, several options can be passed to automatically process the model first time, like `autoScale`, `autoCenter`, `addToRoot` etc. Check [AddObjectOptions](https://threepipe.org/docs/interfaces/AddObjectOptions.html) and [ImportAddOptions](https://threepipe.org/docs/interfaces/ImportAddOptions.html) for more details.
  323. ### Materials
  324. The materials downloaded as PMAT/BMAT/JSON etc from threepipe,
  325. webgi or the editor can be loaded
  326. and registered with the [MaterialManager](https://threepipe.org/docs/classes/MaterialManager)
  327. using the `viewer.load` method.
  328. Custom material types can also be registered by plugins(like dmat for diamonds), which can also be loaded automatically using the `viewer.load` method.
  329. ```typescript
  330. const pMaterial = await viewer.load<PhysicalMaterial>('https://example.com/file.pmat')
  331. const bMaterial = await viewer.load<UnlitMaterial>('https://example.com/file.bmat')
  332. // ... load any material file as a material
  333. ```
  334. Casting to [PhysicalMaterial](https://threepipe.org/docs/classes/PhysicalMaterial) or [UnlitMaterial](https://threepipe.org/docs/classes/UnlitMaterial) is optional but recommended to get the proper type and autocomplete for the material.
  335. To assign the material on any object, set it to `object.material`
  336. ```typescript
  337. // find a loaded mesh in the scene
  338. const object = viewer.scene.getObjectByName('objectName');
  339. // assign the material
  340. object.material = pMaterial;
  341. ```
  342. To copy the properties without changing the material reference, use `material.copy()` or `material.setValues()` methods.
  343. ```typescript
  344. object.material.copy(pMaterial);
  345. // or use material manager to apply to multiple materials.
  346. viewer.assetManager.materialManager.applyMaterial(pMaterial, 'METAL') // apply props to all materials/objects with the name METAL
  347. ```
  348. TODO: add examples for material load and copy
  349. ### Images/Textures
  350. Images can be loaded using the `viewer.load` method.
  351. There is built-in support for loading all image formats supported by the browser (webp, png, jpeg, jpg, svg, ico, avif) and hdr, exr, hdr.png formats for all browsers.
  352. More formats like ktx2, ktx, etc. can be added using plugins.
  353. ```typescript
  354. const texture = await viewer.load<ITexture>('https://example.com/file.png')
  355. // ... load any image file as a texture
  356. ```
  357. Casting to [ITexture](https://threepipe.org/docs/interfaces/ITexture.html) is optional
  358. but recommended to get the proper type and autocomplete for the texture.
  359. It inherits from three.js [Texture](https://threejs.org/docs/#api/en/textures/Texture) and adds some additional properties.
  360. To assign the texture on any material, set it to `material.map`
  361. ```typescript
  362. // find a loaded mesh in the scene
  363. const object = viewer.scene.getObjectByName('objectName');
  364. const material = object.material as PhysicalMaterial;
  365. // assign the texture
  366. material.map = texture;
  367. material.setDirty() // to let the viewer know that the material has changed and needs to re-render the scene. This will also trigger fade effect if FrameFadePlugin is added.
  368. ```
  369. Check out the image load example to see it in action or to check the JS equivalent code: https://threepipe.org/examples/#image-load/
  370. ### Zip files
  371. .zip files are automatically unzipped and the files are sent to re-load recursively when loaded with `viewer.load`.
  372. Any level of zip hierarchy is flattened.
  373. Loading files like .gltf with references to assets inside the zip file,
  374. any relative references are also automatically resolved.
  375. This is supported for file types like gltf, glb, obj,
  376. etc which support references to external files and has `root` set to `true in [IImporter](https://threepipe.org/docs/interfaces/IImporter.html).
  377. ```typescript
  378. const objectGltf = await viewer.load<IObject3D>('https://example.com/model.gltf.zip')
  379. ```
  380. If we know that the zip file contains a single gltf with all the assets, we can cast the result to [IObject3D](https://threepipe.org/docs/interfaces/IObject3D.html) type.
  381. To load multiple assets from zip files like multiple textures or materials, use `viewer.assetManager.addAsset` method which returns a promise of array of loaded assets.
  382. ```typescript
  383. const textures = await viewer.assetManager.addAsset<ITexture[]>('https://example.com/textures.zip')
  384. const materials = await viewer.assetManager.addAsset<IMaterial[]>('https://example.com/materials.zip')
  385. ```
  386. The auto import of zip contents can be disabled to get the files and blobs in the zip
  387. ```typescript
  388. const zip = await viewer.load<any>('https://example.com/file.zip', {autoImportZipContents: false})
  389. ```
  390. TODO - add example for loading zip files.
  391. ### txt, json files
  392. Text and JSON files can be loaded using the `viewer.load` method and return strings and objects respectively.
  393. ```typescript
  394. const text = await viewer.load<string>('https://example.com/file.txt')
  395. const json = await viewer.load<any>('https://example.com/file.json')
  396. ```
  397. ### Data URLs
  398. Data URLs can be loaded using the `viewer.load` method. The correct mime-type is required to be set in the data URL for finding the correct importer.
  399. ```typescript
  400. const dataUrl = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA' // ... some data url
  401. const texture = await viewer.load<ITexture>(dataUrl)
  402. ```
  403. ### Local files, File and Blob
  404. Local files can be loaded using the `viewer.load` method by passing a [IAsset](https://threepipe.org/docs/interfaces/IAsset) object with [File](https://developer.mozilla.org/en-US/docs/Web/API/File) or [Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob) object.
  405. ```typescript
  406. const file: File|Blob = fileObject // create a new file, blob or get from input element
  407. const text = await viewer.load<IObject>({
  408. // a path/name is required to determine the proper importer by extension. `file.name` can also be used if available
  409. path: 'file.glb',
  410. file
  411. })
  412. ```
  413. The same can be done for any file type.
  414. To load a `Map` of files(like when multiple files are dragged and dropped on the webpage) with internal references to other files, use `viewer.assetManager.importer.importFiles` method. Check the source for [DropzonePlugin](#dropzoneplugin) for an example.
  415. ### Background, Environment maps
  416. The background and environment maps can be set using the `viewer.setBackgroundMap` and `viewer.setEnvironmentMap` methods respectively. These accept both loaded textures from `viewer.load` and direct URLs. Files can be of any image format including hdr, exr.
  417. ```typescript
  418. await viewer.setEnvironmentMap('https://example.com/file.hdr')
  419. await viewer.setBackgroundMap('https://example.com/file.png')
  420. ```
  421. The same texture can be set to both by setting `setBackground` or `setEnvironment` to true in the options:
  422. ```typescript
  423. await viewer.setEnvironmentMap('https://example.com/file.hdr', {setBackground: true})
  424. ```
  425. Check the HDR Load example to see it in action: https://threepipe.org/examples/#hdr-load/
  426. ### SVG strings
  427. SVG strings can be converted to data urls using the [svgUrl](https://repalash.com/ts-browser-helpers/functions/svgUrl.html) string template function
  428. ```typescript
  429. const svgDataUrl = svgUrl`<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"> ... </svg>`;
  430. const texture = await viewer.load<ITexture>(dataUrl)
  431. ```
  432. ### Custom file types
  433. Custom file importers/loaders can be registered to the `AssetImporter` using the `addImporter` method.
  434. ```typescript
  435. class CustomLoader extends FileLoader implements ILoader{
  436. constructor(manager?: LoadingManager) {
  437. super(manager);
  438. }
  439. load(url: string, onLoad: (data: any) => void, onProgress?: (event: ProgressEvent) => void, onError?: (event: ErrorEvent) => void): Mesh {
  440. this.setResponseType('json')
  441. return super.load(url, (json: any)=>{
  442. const mat = new PhysicalMaterial(json)
  443. onLoad?.(mat)
  444. }, onProgress, onError)
  445. }
  446. }
  447. viewer.assetManager.importer.addImporter(new Importer(CustomLoader, ['ext'], ['mime/type'], false))
  448. // load the file
  449. const mat = await viewer.load<PhysicalMaterial>('https://example.com/file.ext')
  450. ```
  451. ## Exporting files
  452. Threepipe has support for exporting various asset type with AssetManager,
  453. as well as support to export viewer and plugin configuration, arbitrary objects etc using the [serialization](#serialization) system.
  454. [viewer.export()](https://threepipe.org/docs/classes/ThreeViewer.html#export) is a high-level wrapper for exporting scene objects, materials, textures, render targets, viewer/scene configuration and plugin configurations.
  455. AssetManager internally uses [AssetExporter](https://threepipe.org/docs/classes/AssetExporter.html) to export files.
  456. AssetExporter includes some basic exporters for glb, exr, textures,
  457. and materials and a system to register exporters for different file types with plugins or custom exporters.
  458. ### Exporting 3D models
  459. Export the root scene as glb
  460. ```typescript
  461. const blob = await viewer.exportScene({
  462. viewerConfig: true, // default = true. export all viewer and plugin configuration. if false only the model root object is exported.
  463. })
  464. // download the file
  465. downloadBlob(blob, 'scene.glb')
  466. ```
  467. Export a single object from the scene as glb
  468. ```typescript
  469. const object = viewer.scene.getObjectByName('objectName');
  470. const glb: Blob = await viewer.export(object, {
  471. exportExt: 'glb', // default = glb for models
  472. embedUrlImages: true, // default = false. embed images in glb even when url is available.
  473. })
  474. // download the file
  475. downloadBlob(glb, 'object.glb')
  476. ```
  477. Check the example [glb-export](https://threepipe.org/examples/#glb-export/) to see a demo.
  478. ### Exporting Materials
  479. Export a material
  480. ```typescript
  481. const material = viewer.assetManager.materialManager.findMaterialsByName('materialName')[0];
  482. // or
  483. // const material = viewer.scene.getObjectByName('objectName').material;
  484. const blob = await viewer.export(material)
  485. // download the file
  486. downloadBlob(blob, 'material.' + blob.ext)
  487. ```
  488. Check the example [pmat-material-export](https://threepipe.org/examples/#pmat-material-export/) to see a demo.
  489. ### Exporting Canvas Images
  490. Canvas Screenshot/snapshot can be exported as png, jpeg or webp(if supported by the browser)
  491. ```typescript
  492. const blob = await viewer.getScreenshotBlob({mimeType: 'image/' + type, quality: 0.85})
  493. // or to get data url:
  494. // const dataUrl = await viewer.getScreenshotDataUrl({mimeType: 'image/' + type, quality: 0.85})
  495. // download the file
  496. downloadBlob(blob, 'screenshot.' + blob.ext)
  497. ```
  498. Check the example [image-snapshot-export](https://threepipe.org/examples/#image-snapshot-export/) to see a demo.
  499. ### Exporting Textures
  500. Textures can be exported to JSON using `viewer.export` or `AssetExporter`
  501. ```typescript
  502. const texture = await viewer.load('https://example.com/file.jpeg')
  503. const blob = await viewer.export(texture)
  504. downloadBlob(blob, texture.name + '.' + blob.ext)
  505. ```
  506. Render target textures can be exported with `viewer.renderManager.exportRenderTarget` or `viewer.export`,
  507. read about [Exporting Render Targets](#exporting-render-targets) below.
  508. TODO: add examples for texture export
  509. Textures and Uint8 Data Textures can be exported as a data url or copied to a new canvas
  510. ```typescript
  511. // get a base64 data url
  512. const dataUrl = textureToDataUrl(texture, 4096, false, 'image/png') // texture or data texture, max-size, flipY, mimeType
  513. // or copy to a new canvas
  514. const canvas = textureToCanvas(texture, 4096) // texture or data texture, max-size
  515. ```
  516. Data Textures of type Half float and Float can be exported with `viewer.export`
  517. ```typescript
  518. const dataTex = await viewer.load('https://example.com/file.hdr')
  519. const blob = await viewer.export(dataTexture, {exportExt: 'exr'})
  520. ```
  521. Check the example [hdr-to-exr](https://threepipe.org/examples/#hdr-to-exr/) to see a demo of HDR to EXR conversion.
  522. TODO: add support to export unsigned byte textures as png, jpeg, webp
  523. ### Exporting Images/Textures
  524. Exporting Textures as Images with image of types ImageBitmap, HTMLImageElement,
  525. HTMLOrSVGImageElement, CanvasImageSource, HTMLCanvasElement,
  526. OffscreenCanvas can be exported to png data urls with [imageBitmapToBase64](https://repalash.com/ts-browser-helpers/functions/imageBitmapToBase64.html) function.
  527. ```typescript
  528. const texture = await viewer.load('https://example.com/file.jpeg')
  529. const dataUrl = await imageBitmapToBase64(texture.image, 'image/png', 0.85);
  530. ```
  531. TODO: add support for texture export as images in AssetExporter
  532. ### Exporting Render Targets
  533. Unsigned byte render targets can be exported as png, jpeg or webp(if supported by the browser)
  534. ```typescript
  535. const depthPlugin = viewer.addPluginSync(DepthBufferPlugin, UnsignedByteType)
  536. // wait for the first render
  537. const blob = await viewer.export(depthPlugin.target!, {exportExt: 'png'})
  538. if (blob) downloadBlob(blob, target.texture.name + '.' + blob.ext)
  539. ```
  540. Half float and float render targets can be exported as exr
  541. ```typescript
  542. const depthPlugin = viewer.addPluginSync(DepthBufferPlugin, HalfFloatType)
  543. // wait for the first render
  544. const blob = await viewer.export(depthPlugin.target!, {exportExt: 'exr'})
  545. if (blob) downloadBlob(blob, target.texture.name + '.' + blob.ext)
  546. ```
  547. Note: `exportExt` is determined automatically if not specified.
  548. ## Render pipeline
  549. Threepipe includes a [RenderManager](https://threepipe.org/docs/classes/RenderManager.html) for managing the composition pipeline, and provides helpers for rendering and render target management.
  550. The RenderManager includes a [EffectComposer](https://threejs.org/docs/#api/en/postprocessing/EffectComposer) from three.js for rendering passes and a [WebGLRenderer](https://threejs.org/docs/#api/en/renderers/WebGLRenderer) for rendering,
  551. but the pass management and sorting is managed by the RenderManager itself.
  552. The RenderManager inherits from [RenderTargetManager](https://threepipe.org/docs/classes/RenderTargetManager.html)
  553. which provides utilities for creating, tracking and destroying dedicated and temporary render targets.
  554. ### Render Targets
  555. Render targets can be created
  556. using the `viewer.renderManager.createTarget` and `viewer.renderManager.createTargetCustom` methods.
  557. These can then be disposed using the `viewer.renderManager.disposeTarget` method when not needed anymore.
  558. Or to create temp targets for one time use `viewer.renderManager.getTempTarget` and `viewer.renderManager.releaseTempTarget` methods.
  559. can be used.
  560. All created render targets are tracked in the RenderManager,
  561. and are resized and disposed automatically when needed along with the viewer.
  562. ```typescript
  563. const newTarget = viewer.renderManager.createTarget({sizeMultiplier: 1})
  564. // or
  565. const newTarget2 = viewer.renderManager.createTarget({size: {
  566. width: 1024,
  567. height: 1024,
  568. },
  569. type: HalfFloatType
  570. })
  571. // or clone an existing target
  572. const newTarget3 = viewer.renderManager.composerTarget.clone()
  573. // for multi-sample render target
  574. const newTarget4 = viewer.renderManager.createTarget({sizeMultiplier: 1, samples: 4})
  575. // or create a custom target
  576. const newTarget5 = viewer.renderManager.createTargetCustom(
  577. {width: 1024, height: 1024},
  578. {type: HalfFloatType},
  579. WebGLCubeRenderTarget
  580. )
  581. // dispose targets
  582. viewer.renderManager.disposeTarget(newTarget)
  583. viewer.renderManager.disposeTarget(newTarget2)
  584. viewer.renderManager.disposeTarget(newTarget3)
  585. viewer.renderManager.disposeTarget(newTarget4)
  586. viewer.renderManager.disposeTarget(newTarget5)
  587. // get a temporary target
  588. const tempTarget = viewer.renderManager.getTempTarget({sizeMultiplier: 1})
  589. // release the temporary target
  590. viewer.renderManager.releaseTempTarget(tempTarget)
  591. ```
  592. Note: Render targets created with a sizeMultiplier are automatically resized when the canvas is resized.
  593. ### Passes
  594. By default, the render pipeline includes 2 passes -
  595. [RenderPass](https://threejs.org/docs/#api/en/postprocessing/RenderPass) for rendering the scene hierarchy and [ScreenPass](https://threejs.org/docs/#api/en/postprocessing/ShaderPass)
  596. for rendering the final output on the canvas.
  597. More passes can be added and removed from the pipeline
  598. using the [registerPass](https://threepipe.org/docs/classes/RenderManager.html#registerPass) and [unregisterPass](https://threepipe.org/docs/classes/RenderManager.html#unregisterPass) methods.
  599. The pipeline passes need
  600. to follow the interface of [IPipelinePass](https://threepipe.org/docs/interfaces/IPipelinePass.html) and [IPipelinePassPlugin](https://threepipe.org/docs/interfaces/IPipelinePassPlugin.html).
  601. Which adds some important parameters over the three.js Pass,
  602. like pass id and support for defining where the pass should be added in the pipeline and it's dependants.
  603. ```typescript
  604. const pass = new GBufferRenderPass('customPass', viewer.renderManager.createTarget({sizeMultiplier: 1}))
  605. pass.before = ['render'] // Add the pass before the render pass
  606. pass.after = [] // Add the pass after these passes (none in this case)
  607. pass.required = ['render'] // render pass is required to be in the pipeline for this
  608. viewer.renderManager.registerPass(pass)
  609. ```
  610. Note:
  611. See [PipelinePassPlugin](https://threepipe.org/docs/classes/PipelinePassPlugin.html) for an abstract plugin
  612. that provides the boilerplate to create a plugin that registers a custom pass in the pipeline.
  613. Check [NormalBufferPlugin](https://threepipe.org/docs/classes/NormalBufferPlugin.html) for an example of that.
  614. Note: All effects in post-processing or material extension need not be a separate pass in the pipeline.
  615. Most effects can be achieved with either extending the scene object material shaders or the Screen Pass material shader
  616. using [Material extension](#material-extension) system
  617. ## Material Extension
  618. Threepipe includes a Material extension system along with a material manager.
  619. The material manager is used to register materials and material extensions.
  620. The material extensions are used to extend any material in the scene,
  621. or any plugin/pass with additional uniforms, defines, shader snippets and provides hooks.
  622. The material extensions are automatically applied to all materials in the scene that are compatible,
  623. when the extension is registered or when the material is added to the scene.
  624. Threepipe includes several built-in materials like
  625. [PhysicalMaterial](https://threepipe.org/docs/classes/PhysicalMaterial.html),
  626. [UnlitMaterial](https://threepipe.org/docs/classes/UnlitMaterial.html),
  627. [ExtendedShaderMaterial](https://threepipe.org/docs/classes/ExtendedShaderMaterial.html), [LegacyPhongMaterial](https://threepipe.org/docs/classes/LegacyPhongMaterial.html),
  628. that include support for extending the material.
  629. Any three.js material can be made extendable,
  630. check the `ShaderPass2` class for a simple example that adds support for material extension to three.js ShaderPass.
  631. The material extensions must follow the [MaterialExtension](https://threepipe.org/docs/interfaces/MaterialExtension.html) interface.
  632. Many plugins create their own material extensions either for the scene materials or shader passes(like the screen pass).
  633. Some plugins like `DepthBufferPlugin` also provides helper material extensions for other custom plugins
  634. to fetch value in the depth buffer.
  635. A sample material extension
  636. ```typescript
  637. const extension: MaterialExtension = {
  638. shaderExtender: (shader)=> {
  639. // change the shader properties like shader.fragmentShader, etc
  640. },
  641. parsFragmentSnippet: ` // add some code before the main function in the fragment shader
  642. uniform sampler2D tTexture;
  643. uniform float opacity;
  644. `,
  645. extraUniforms: {
  646. tTexture: ()=>({value: getTexture()}),
  647. opacity: {value: 1}
  648. // add additional uniforms, these can be IUniform or functions that return IUniform
  649. },
  650. extraDefines: {
  651. ['DEPTH_PACKING']: BasicDepthPacking,
  652. ['SOME_DEFINE']: ()=>"1",
  653. // add additional defines, these can be values or functions that return values
  654. },
  655. priority: 100, // priority when using multiple extensions on the same material
  656. isCompatible: (material) => material.isMeshBasicMaterial, // check if the material is compatible with this extension,
  657. computeCacheKey: (material) => material.uuid, // a custom cache key for the material extension. Shader is recompiled when this is changed
  658. onObjectRender: (object: Object3D, material: IMaterial) => {
  659. // called when some object is rendererd which has a material with this extension.
  660. },
  661. // uiConfig
  662. // check more properties and hooks in the MaterialExtension interface
  663. }
  664. // The extension can be registered to all the materials using the MaterialManager
  665. viewer.assetManager.materialManager.registerMaterialExtension(extension)
  666. // or register it on a single material (like the Screen Pass)
  667. viewer.renderManager.screenPass.material.registerMaterialExtensions([extension])
  668. ```
  669. ## UI Configuration
  670. Most of the classes and plugins in Threepipe include [uiconfig.js](https://repalash.com/uiconfig.js/) support
  671. and can be used to create configuration UIs, 3d configurators and even full-editors.
  672. The UIs are automatically generated based on the configuration object under `.uiConfig` property on all objects.
  673. These are of type [UiObjectConfig](https://repalash.com/uiconfig.js/interfaces/UiObjectConfig.html).
  674. In some classes, the ui configs are also generated using typescript decorators.
  675. The `uiConfig` is also added to all three.js objects and materials when they are added to the scene.
  676. The UIs can be generated at runtime using any of the UI plugins like [TweakpaneUIPlugin](#threepipeplugin-tweakpane), [BlueprintJsUiPlugin](#threepipeplugin-blueprintjs)
  677. An example showing how to create a UI for a material
  678. ```typescript
  679. const ui = viewer.addPluginSync(TweakpaneUiPlugin)
  680. const object = viewer.scene.getObjectByName('objectName');
  681. const material = object.material as PhysicalMaterial;
  682. ui.appendChild(material.uiConfig)
  683. ```
  684. See it in action: https://threepipe.org/examples/#material-uiconfig/
  685. Check more examples showing [Viewer UI](https://threepipe.org/examples/#viewer-uiconfig/),
  686. [Scene UI](https://threepipe.org/examples/#scene-uiconfig/),
  687. [Object UI](https://threepipe.org/examples/#object-uiconfig/), [Camera UI](https://threepipe.org/examples/#camera-uiconfig/)
  688. [TweakpaneEditorPlugin](#threepipeplugin-tweakpane-editor) further uses the Tweakpane configuration panel along with various plugins to create an 3d editor.
  689. Custom UI configuration can be created to generate custom UI for the editor or tweaking.
  690. This can be done by using typescript decorators or defining the UI in javascript as a [UiObjectConfig](https://repalash.com/uiconfig.js/interfaces/UiObjectConfig.html) object.
  691. Here is a sample of extending the orbit controls class with decorators to automatically generate UI.
  692. ```typescript
  693. @uiPanelContainer('Orbit Controls')
  694. export class OrbitControlsWithUi extends OrbitControls implements IUiConfigContainer {
  695. // for autocomplete
  696. uiConfig?: UiObjectConfig<void, 'panel'>
  697. @uiToggle() enabled = true
  698. @uiToggle() dollyZoom = false
  699. @uiToggle() enableDamping = true
  700. @uiInput() dampingFactor = 0.08
  701. @uiToggle() autoRotate = false
  702. @uiInput() autoRotateSpeed = 2.0
  703. @uiToggle() enableZoom = true
  704. @uiInput() zoomSpeed = 0.15
  705. @uiInput() maxZoomSpeed = 0.20
  706. @uiToggle() enableRotate = true
  707. @uiInput() rotateSpeed = 2.0
  708. @uiToggle() enablePan = true
  709. @uiInput() panSpeed = 1.0
  710. @uiInput() autoPushTarget = false
  711. @uiInput() autoPullTarget = false
  712. @uiInput() minDistance = 0.35
  713. @uiInput() maxDistance = 1000
  714. @uiInput() minZoom = 0.01
  715. @uiInput() maxZoom = 1000
  716. @uiInput() minPolarAngle = 0
  717. @uiInput() maxPolarAngle = Math.PI
  718. @uiInput() minAzimuthAngle = -10000 // should be -Infinity but this breaks the UI
  719. @uiInput() maxAzimuthAngle = 10000
  720. }
  721. ```
  722. Check out the full source code:
  723. [./src/three/controls/OrbitControls3.ts](./src/three/controls/OrbitControls3.ts) for proper implementation
  724. See it in action: https://threepipe.org/examples/#camera-uiconfig/ Open the Camera UI and click on the Orbit Controls panel.
  725. There are many available decorators like `uiToggle`, `uiSlider`, `uiInput`, `uiNumber`, `uiColor`, `uiImage`.
  726. Check the complete list in the [uiconfig.js documentation](https://repalash.com/uiconfig.js/).
  727. The UI configuration can also be created using json objects in both typescript and javascript
  728. ```javascript
  729. const viewer = new ThreeViewer({...})
  730. const ui = viewer.addPluginSync(TweakpaneUiPlugin)
  731. const state = {
  732. position: new Vector3(),
  733. scale: 1,
  734. }
  735. ui.appendChild({
  736. type: 'folder',
  737. label: 'Custom UI',
  738. children: [
  739. {
  740. type: 'vec3',
  741. label: 'Position',
  742. property: [state, 'position']
  743. },
  744. {
  745. type: 'slider',
  746. label: ()=>'Scale', // everything can be a function as well.
  747. property: [state, 'scale'],
  748. bounds: [1, 2],
  749. stepSize: 0.1,
  750. }
  751. ]
  752. })
  753. ```
  754. TODO: create example/codepen for this
  755. ## Serialization
  756. Easy serialization of all threepipe and most three.js objects are supported out of the box using the Asset Manager.
  757. Fine control over serialization is also supported
  758. using the [ThreeSerialization](https://threepipe.org/docs/classes/ThreeSerialization.html) class
  759. Call `ThreeSerialization.serialize` on any object to serialize it.
  760. and `ThreeSerialization.deserialize` to deserialize the serialized object.
  761. This is done by performing a nested serialization of all the properties of the object.
  762. It's possible to implement custom serializers for custom types and classes and is done for three.js primitives,
  763. objects and plugins in threepipe
  764. To make a custom data class that is serializable,
  765. mark it using `@serializable` decorator and any properties using `@serialize` decorator.
  766. ```typescript
  767. @serializable('DataClass')
  768. class DataClass{
  769. @serialize() prop1 = 1
  770. @serialize() prop2 = 'string'
  771. @serialize() prop3 = new Vector3()
  772. @serialize() prop4 = new PhysicalMaterial()
  773. @serialize() prop4 = {
  774. prop1: 1,
  775. prop2: 'string',
  776. prop3: new Vector3(),
  777. prop4: new PhysicalMaterial(),
  778. }
  779. }
  780. const data = new DataClass()
  781. const serialized = ThreeSerialization.serialize(data)
  782. const deserialized = ThreeSerialization.deserialize(serialized)
  783. ```
  784. The classes without a `@serializable` decorator are serialized as plain objects.
  785. These can still include `@serialize` decorator to mark the properties are serializable
  786. but these classes cannot be deserialized into a new instance of the class.
  787. The ThreeViewer and plugins are an example of these.
  788. When deserialized they need an object to deserialize into.
  789. This ensures there is always just one instance.
  790. With this, the serialization system works like `toJSON` and `fromJSON` methods in three.js.
  791. Check the [plugin system](#plugin-system) below for more details on how to mark properties as serializable for plugins.
  792. ```typescript
  793. class CustomClass{
  794. @serialize() prop1 = 1
  795. @serialize() prop2 = 'string'
  796. @serialize() prop3 = new Vector3()
  797. @serialize() prop4 = new PhysicalMaterial()
  798. }
  799. const obj = new DataClass()
  800. const serialized = ThreeSerialization.serialize(data)
  801. // now to deserialize we need to pass in the object to deserialize into
  802. ThreeSerialization.deserialize(serialized, obj)
  803. ```
  804. ## Plugin System
  805. Threepipe includes a plugin system for adding additional features to the viewer in a modular way.
  806. The plugins can be added synchronously or asynchronously using `viewer.addPluginSync` and `viewer.addPlugin` methods respectively.
  807. It is recommended to create custom plugins for reusable features,
  808. as they provide built-in features for ui configuration,
  809. serialization, integration with editors etc and are easy to manage and tree-shake in the code.
  810. Check out the list of plugins in the [Plugin List](#threepipe-plugins) section below.
  811. To create new plugins,
  812. simply implement the `IViewerPlugin` interface or extend the [AViewerPluginSync](https://threepipe.org/docs/classes/AViewerPluginSync.html) or [AViewerPluginAsync](https://threepipe.org/docs/classes/AViewerPluginAsync.html) classes.
  813. The only difference is that in async the `onAdded` and `onRemove` functions are async
  814. Here is a sample plugin
  815. ```typescript
  816. @uiFolder("Sample Plugin") // This creates a folder in the Ui. (Supported by TweakpaneUiPlugin)
  817. export class SamplePlugin extends AViewerPluginSync<"sample-1" | "sample-2"> {
  818. // These are the list of events that this plugin can dispatch.
  819. static readonly PluginType = "SamplePlugin"; // This is required for serialization and handling plugins. Also used in viewer.getPluginByType()
  820. @uiToggle() // This creates a checkbox in the Ui. (Supported by TweakpaneUiPlugin)
  821. @serialize() // Adds this property to the list of serializable. This is also used when serializing to glb in AssetExporter.
  822. enabled = true;
  823. // A plugin can have custom properties.
  824. @uiSlider("Some Number", [0, 100], 1) // Adds a slider to the Ui, with custom bounds and step size (Supported by TweakpaneUiPlugin)
  825. @serialize("someNumber")
  826. @onChange(SamplePlugin.prototype._updateParams) // this function will be called whenevr this value changes.
  827. val1 = 0;
  828. // A plugin can have custom properties.
  829. @uiInput("Some Text") // Adds a slider to the Ui, with custom bounds and step size (Supported by TweakpaneUiPlugin)
  830. @onChange(SamplePlugin.prototype._updateParams) // this function will be called whenevr this value changes.
  831. @serialize()
  832. val2 = "Hello";
  833. @uiButton("Print Counters") // Adds a button to the Ui. (Supported by TweakpaneUiPlugin)
  834. public printValues = () => {
  835. console.log(this.val1, this.val2);
  836. this.dispatchEvent({ type: "sample-1", detail: { sample: this.val1 } }); // This will dispatch an event.
  837. }
  838. constructor() {
  839. super();
  840. this._updateParams = this._updateParams.bind(this);
  841. }
  842. private _updateParams() {
  843. console.log("Parameters updated.");
  844. this.dispatchEvent({ type: "sample-2" }); // This will dispatch an event.
  845. }
  846. onAdded(v: ThreeViewer): void {
  847. super.onAdded(v);
  848. // Do some initialization here.
  849. this.val1 = 0;
  850. this.val2 = "Hello";
  851. v.addEventListener("preRender", this._preRender);
  852. v.addEventListener("postRender", this._postRender);
  853. v.addEventListener("preFrame", this._preFrame);
  854. v.addEventListener("postFrame", this._postFrame);
  855. this._viewer!.scene.addEventListener("addSceneObject", this._objectAdded); // this._viewer can also be used while this plugin is attached.
  856. }
  857. onRemove(v: ThreeViewer): void {
  858. // remove dispose objects
  859. v.removeEventListener("preRender", this._preRender);
  860. v.removeEventListener("postRender", this._postRender);
  861. v.removeEventListener("preFrame", this._preFrame);
  862. v.removeEventListener("postFrame", this._postFrame);
  863. this._viewer!.scene.removeEventListener("addSceneObject", this._objectAdded); // this._viewer can also be used while this plugin is attached.
  864. super.onRemove(v);
  865. }
  866. private _objectAdded = (ev: IEvent<any>) => {
  867. console.log("A new object, texture or material is added to the scene.", ev.object);
  868. };
  869. private _preFrame = (ev: IEvent<any>) => {
  870. // This function will be called before each frame. This is called even if the viewer is not dirty, so it's a good place to do viewer.setDirty()
  871. };
  872. private _preRender = (ev: IEvent<any>) => {
  873. // This is called before each frame is rendered, only when the viewer is dirty.
  874. };
  875. // postFrame and postRender work the same way as preFrame and preRender.
  876. }
  877. ```
  878. Notes:
  879. * All plugins that are present in the dependencies array when the plugin is added to the viewer, are created and attached to the viewer in `super.onAdded`
  880. * Custom events can be dispatched with `this.dispatchEvent`, and subscribed to with `plugin.addEventListener`. The event type must be described in the class signature for typescript autocomplete to work.
  881. * Event listeners and other hooks can be added and removed in `onAdded` and `onRemove` functions for the viewer and other plugins.
  882. * To the viewer render the next frame, `viewer.setDirty()` can be called, or set `this.dirty = true` in preFrame and reset in postFrame to stop the rendering. (Note that rendering may continue if some other plugin sets the viewer dirty like `ProgressivePlugin` or any of the animation plugins). Check `isConverged` in `ProgressivePlugin` to check if its the final frame.
  883. * All Plugins which inherit from AViewerPlugin support serialisation. Create property `serializeWithViewer = false` to disable serialisation with the viewer in config and glb or `toJSON: any = undefined` to disable serialisation entirely
  884. * `plugin.toJSON()` and `plugin.fromJSON()` or `ThreeSerialization` can be used to serialize and deserialize plugins. `viewer.exportPluginConfig` and `viewer.importPluginConfig` also exist for this.
  885. * @serialize('label') decorator can be used to mark any public/private variable as serializable. label (optional) corresponds to the key in JSON.
  886. * @serialize supports instances of ITexture, IMaterial, all primitive types, simple JS objects, three.js math classes(Vector2, Vector3, Matrix3...), and some more.
  887. * uiDecorators can be used to mark properties and functions that will be shown in the Ui. The Ui shows up automatically when TweakpaneUiPlugin/BlueprintJsUiPlugin is added to the viewer. Plugins have special features in the UI for download preset and saving state.
  888. Check various plugins in the source code for more examples.
  889. # Viewer API
  890. [ThreeViewer](https://threepipe.org/docs/classes/ThreeViewer.html) - is the main entry point to 3d rendering on the canvas.
  891. - `.renderManager`: [ViewerRenderManager](https://threepipe.org/docs/classes/ViewerRenderManager.html) & [RenderManager](https://threepipe.org/docs/classes/RenderManager.html) & [RenderTargetManager](https://threepipe.org/docs/classes/RenderTargetManager.html) - Render manager for managing the rendering and composition pipeline, and provides helpers for rendering and render target management
  892. - `.renderer`: [IWebGLRenderer](https://threepipe.org/docs/interfaces/IWebGLRenderer.html) - for rendering. Instance of three.js [WebGLRenderer](https://threejs.org/docs/#api/en/renderers/WebGLRenderer)
  893. - `.composer`: [EffectComposer2](https://threepipe.org/docs/classes/EffectComposer2.html) - for rendering passes. Instance of three.js [EffectComposer](https://threejs.org/docs/#api/en/postprocessing/EffectComposer)
  894. - `.context`: [WebGLRenderingContext](https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext) - WebGL rendering context
  895. - `.renderPass`: [ExtendedRenderPass](https://threepipe.org/docs/classes/ExtendedRenderPass.html) - Render pass for rendering the scene. Instance of three.js [RenderPass](https://threejs.org/docs/#api/en/postprocessing/RenderPass) with extra features
  896. - `.screenPass`: [ScreenPass](https://threepipe.org/docs/classes/ScreenPass.html) - Screen pass for rendering the final output. Instance of three.js [ShaderPass](https://threejs.org/docs/#api/en/postprocessing/ShaderPass) with extra features.
  897. - `.scene`: [RootScene](https://threepipe.org/docs/classes/RootScene.html) - Main scene used for rendering. Instance of three.js [Scene](https://threejs.org/docs/#api/en/scenes/Scene)
  898. - `.mainCamera`: [PerspectiveCamera2](https://threepipe.org/docs/classes/PerspectiveCamera2.html) - Main camera currently being used for rendering. Instance of three.js [PerspectiveCamera](https://threejs.org/docs/#api/en/cameras/PerspectiveCamera)
  899. - `.assetManager`: [AssetManager](https://threepipe.org/docs/classes/AssetManager.html) - Asset manager for loading, managing and exporting assets
  900. - `.importer`: [AssetImporter](https://threepipe.org/docs/classes/AssetImporter.html) - for importing assets
  901. - `.exporter`: [AssetExporter](https://threepipe.org/docs/classes/AssetExporter.html) - for exporting assets
  902. - `.materialManager`: [MaterialManager](https://threepipe.org/docs/classes/MaterialManager.html) - for managing materials and material extensions
  903. - `.plugins`: `Record`<`string`, [IViewerPlugin](https://threepipe.org/docs/interfaces/IViewerPlugin.html)> - Plugins added to the viewer
  904. - `.uiConfig`: [UiObjectConfig](https://repalash.com/uiconfig.js/interfaces/UiObjectConfig.html) - UI confguration for the viewer. Used to automatically generate UIs for the viewer and plugins.
  905. ## ThreeViewer
  906. Source Code: [src/viewer/ThreeViewer.ts](./src/viewer/ThreeViewer.ts)
  907. API Reference: [ThreeViewer](https://threepipe.org/docs/classes/ThreeViewer.html)
  908. `ThreeViewer` is the main entry point to the viewer. It provides all the API for managing the scene, camera, rendering, plugins, etc.
  909. It is initialized with either a canvas element or a `HTMLElement` for the container.
  910. The canvas element is used for rendering, and the options are used to configure the viewer.
  911. If the canvas element is not provided, a new canvas element is created and appended to the container.
  912. More options can be passed in the constructor to configure various built-in plugins and rendering features in the viewer.
  913. ### Constructor
  914. ```typescript
  915. import {ThreeViewer, CameraViewPlugin} from 'threepipe'
  916. // Create a viewer. All options except canvas/container are optional
  917. const viewer = new ThreeViewer({
  918. canvas: document.getElementById('mcanvas') as HTMLCanvasElement,
  919. // or a container like:
  920. // container: document.getElementById('mcontainer'),
  921. // container: document.body,
  922. // Set the render scale to render at device resolution and clamp to max 2.
  923. renderScale: 'auto',
  924. // or Set the render scale to render at device resolution
  925. // renderScale: window.devicePixelRatio,
  926. // modify the screen shader: See ScreenPass and ScreenPass.glsl for more details
  927. screenShader: `diffuseColor = diffuseColor * 2.0;`,
  928. // Add TonemapPlugin
  929. tonemap: true,
  930. // Use MSAA(anti-aliasing)
  931. msaa: false,
  932. // Use Uint8 RGBM HDR Render Pipeline. Provides better performance with post-processing. RenderManager Uses Half-float if set to false.
  933. rgbm: true,
  934. // Use rendered gbuffer as depth-prepass / z-prepass.
  935. zPrepass: false,
  936. // Options for AssetManager
  937. assetManager: {
  938. // Use a custom CacheStorage
  939. storage: caches.open('threepipe-assetmanager'),
  940. },
  941. // Use DropzonePlugin to add support for file drag and drop
  942. // Enable and set properties
  943. dropzone: {
  944. // Set allowed extensions
  945. allowedExtensions: ['png', 'glb', 'gltf'],
  946. // Automatically add downloaded assets
  947. autoAdd: true
  948. // autoImport: true,
  949. // domElement: document.body,
  950. // addOptions: { ... }
  951. // importOptions: { ... }
  952. },
  953. // By default its false
  954. // dropzone: false,
  955. // To Enable without options
  956. // dropzone: true
  957. // Add some plugins after viewer creation.
  958. plugins: [CameraViewPlugin, new CustomPlugin()],
  959. // Shorthand to load files immediately after viewer initialization
  960. load: {
  961. src: 'https://example.com/file.glb',
  962. environment: 'https://example.com/file.hdr',
  963. background: 'https://example.com/file.png',
  964. },
  965. onLoad: (viewer) => {
  966. // Called when all the files are loaded
  967. },
  968. })
  969. ```
  970. Check the interface [ThreeViewerOptions](https://threepipe.org/docs/interfaces/ThreeViewerOptions.html) for all the options.
  971. To dispose off the viewer and all its resources call [`viewer.dispose()`](https://threepipe.org/docs/classes/ThreeViewer.html#dispose) method.
  972. To dispose only the scene objects and not the complete viewer, use `viewer.scene.disposeSceneModels()`
  973. ### Plugin Functions
  974. ```typescript
  975. import {ThreeViewer, TonemapPlugin, DepthBufferPlugin, NormalBufferPlugin} from 'threepipe'
  976. const viewer = new ThreeViewer({...})
  977. // Add a plugin
  978. const plugin = viewer.addPluginSync(new TonemapPlugin())
  979. // plugins can be added with just the class also
  980. const plugin2 = viewer.addPluginSync(TonemapPlugin)
  981. // Add multiple plugins at once
  982. viewer.addPluginsSync([
  983. TonemapPlugin,
  984. new NormalBufferPlugin(),
  985. DepthBufferPlugin,
  986. // ...
  987. ])
  988. // Get a plugin
  989. const plugin3 = viewer.getPlugin(TonemapPlugin)
  990. // Get or add a plugin, when not sure if the plugin is already added
  991. const plugin4 = viewer.getOrAddPluginSync(TonemapPlugin)
  992. // Remove a plugin
  993. viewer.removePluginSync(TonemapPlugin)
  994. ```
  995. Note: all sync functions above have async counterparts like `addPlugin`, `getOrAddPlugin`,
  996. `removePlugin` that are used for async plugins.
  997. There are no async plugins built-in to threepipe yet.
  998. ### Import/Export Functions
  999. ```typescript
  1000. import {ThreeViewer} from 'threepipe'
  1001. const viewer = new ThreeViewer({...})
  1002. // Load a 3d model
  1003. const object = await viewer.load<IObject3D>('https://example.com/file.glb')
  1004. // Load a material
  1005. const material = await viewer.load<PhysicalMaterial>('https://example.com/file.pmat')
  1006. // Load an image
  1007. const texture = await viewer.load<ITexture>('https://example.com/file.png')
  1008. // Import a model without adding to the scene
  1009. const imported = await viewer.import('https://example.com/file.glb')
  1010. // Export the complete scene with viewer configuraion
  1011. const exportedScene = await viewer.exportScene({})
  1012. // Export an object
  1013. const exported = await viewer.export(object)
  1014. // Export a material
  1015. const exportedMaterial = await viewer.export(material)
  1016. // Export a texture
  1017. const exportedTexture = await viewer.export(texture)
  1018. // Export viewer and plugins configurations
  1019. const exportedConfig = await viewer.export(viewer)
  1020. // Export plugin configuration
  1021. const exportedPlugin = await viewer.exportPlugin(viewer.getPlugin(PluginClass))
  1022. // Set Background Image
  1023. await viewer.setBackgroundMap('https://example.com/file.png')
  1024. // Set Environment Map
  1025. await viewer.setEnvironmentMap('https://example.com/file.hdr')
  1026. // Add an imported object or a created three.js object to the scene
  1027. viewer.addSceneObject(imported)
  1028. ```
  1029. [`viewer.load`](https://threepipe.org/docs/classes/ThreeViewer.html#load) - Loads a single asset by path or [IAsset](https://threepipe.org/docs/interfaces/IAsset.html) object, and adds to the scene if its 3d object or loads it if it's a configuration It is the same as [AssetManager.addAssetSingle](https://threepipe.org/docs/classes/AssetManager.html#addAssetSingle). Use [AssetManager.addAsset](https://threepipe.org/docs/classes/AssetManager.html#addAsset) to load multiple assets from the same path like in case of zip bundles.
  1030. [`viewer.import`](https://threepipe.org/docs/classes/ThreeViewer.html#import) - Load a single asset but does not add to the scene or load the configuration. It is the same as [AssetManager.importer.importSingle](https://threepipe.org/docs/classes/AssetImporter.html#importSingle). Use [AssetManager.importer.import](https://threepipe.org/docs/classes/AssetImporter.html#import) to import multiple assets from the same path like in case of zip bundles.
  1031. [`viewer.export`](https://threepipe.org/docs/classes/ThreeViewer.html#export) - Exports an object, material, texture, render target or plugin configuration and returns a Blob. It is similar to [AssetManager.exporter.exportObject](https://threepipe.org/docs/classes/AssetExporter.html#exportObject) but adds support for exporting plugin and self(viewer) configs.
  1032. [`viewer.exportScene`](https://threepipe.org/docs/classes/ThreeViewer.html#exportScene) - Exports the scene model root and all configurations into a bundled `glb` file and returns a blob.
  1033. [`viewer.exportPlugin`](https://threepipe.org/docs/classes/ThreeViewer.html#exportPlugin) - Exports a plugin configuration and returns a blob.
  1034. [`viewer.setBackgroundMap`](https://threepipe.org/docs/classes/ThreeViewer.html#setBackgroundMap) - Sets the background map to the given texture or url. Also sets it as environment map if `setEnvironment` is `true` in the options.
  1035. [`viewer.setEnvironmentMap`](https://threepipe.org/docs/classes/ThreeViewer.html#setEnvironmentMap) - Sets the environment map to the given texture or url. Also sets it as background if `setBackground` is `true` in the options.
  1036. [`viewer.addSceneObject`](https://threepipe.org/docs/classes/ThreeViewer.html#addSceneObject) - Adds an imported object or a created three.js object to the scene model root. If an imported scene model root is passed, it will be loaded with viewer configuration, unless `importConfig` is `false` in the options.
  1037. ### Frame/Rendering Events
  1038. ```typescript
  1039. import {ThreeViewer} from 'threepipe'
  1040. const viewer = new ThreeViewer({...})
  1041. // Add a callback to be called before every frame, irrespective of whether enything is being rendered that frame
  1042. viewer.addEventListener('preFrame', (ev)=>{
  1043. console.log(ev);
  1044. // change something
  1045. viewer.setDirty() // let the viewer know to re-render the scene from this frame
  1046. })
  1047. // Add a callback to be called after every frame, irrespective of whether enything was rendered that frame
  1048. viewer.addEventListener('postFrame', (ev)=>{
  1049. console.log(ev);
  1050. // change something
  1051. viewer.setDirty() // let the viewer know to re-render the scene from next frame
  1052. })
  1053. // Add a callback to be called before every render, only if something is being rendered that frame
  1054. viewer.addEventListener('preRender', (ev)=>{
  1055. // canvas is about to be rendered, or re-rendered for progressive rendering
  1056. console.log(ev, viewer.renderManager.frameCount);
  1057. })
  1058. // Add a callback to be called after every render, only if something was rendered that frame
  1059. viewer.addEventListener('postRender', (ev)=>{
  1060. // canvas is rendered, or re-rendered for progressive rendering
  1061. console.log(ev);
  1062. })
  1063. // Listen to viewer.setDirty() calls
  1064. viewer.addEventListener('update', (ev)=>{
  1065. // viewer.setDirty() was called by some plugin or code
  1066. console.log(ev);
  1067. })
  1068. // to remove an event listener, first keep a reference to the callback
  1069. const callback = (ev)=>{ return }
  1070. viewer.addEventListener('preFrame', callback)
  1071. // then remove it
  1072. viewer.removeEventListener('preFrame', callback)
  1073. // Add a callback to be called only once for an event
  1074. viewer.doOnce('postFrame', () => viewer.canvas.toDataURL('image/png'))
  1075. // Enable/disable rendering in the viewer
  1076. viewer.renderEnabled = false
  1077. // do something with the canvas or load assets
  1078. await viewer.load('https://example.com/file.glb')
  1079. await viewer.load('https://example.com/file1.glb')
  1080. await viewer.load('https://example.com/file2.glb')
  1081. viewer.renderEnabled = true // all the assets will be rendered together in the next frame
  1082. ```
  1083. Check the [IViewerEvent](https://threepipe.org/docs/interfaces/IViewerEvent.html) interface for all the event types.
  1084. [`viewer.addEventListener`](https://threepipe.org/docs/classes/ThreeViewer.html#addEventListener) - Adds a callback to be called on the given event. The callback is called with an [IViewerEvent](https://threepipe.org/docs/interfaces/IViewerEvent.html) object.
  1085. [`viewer.removeEventListener`](https://threepipe.org/docs/classes/ThreeViewer.html#removeEventListener) - Removes a callback from the given event.
  1086. [`viewer.doOnce`](https://threepipe.org/docs/classes/ThreeViewer.html#doOnce) - Adds a callback to be called only once for the given event. The listener will be added and automatically removed after the first call.
  1087. ### Utility Functions
  1088. ```typescript
  1089. import {ThreeViewer} from 'threepipe'
  1090. const viewer = new ThreeViewer({...})
  1091. // Set the final render size directly and fit in container based on mode.
  1092. viewer.setRenderSize({width: 800, height: 600}, 'cover')
  1093. // Set size of the canvas
  1094. viewer.setSize({width: 800, height: 600})
  1095. // Set the render scale
  1096. viewer.renderManager.renderScale = Math.min(window.devicePixelRatio, 2)
  1097. // Traverse scene objects
  1098. viewer.traverseSceneObjects((object) => {
  1099. console.log(object)
  1100. // do something with object
  1101. })
  1102. // If the size is set by css or manually by javascript use `resize` to update the viewer
  1103. viewer.resize()
  1104. // Trigger re-render with `setDirty` when something changes and viewer is not notified internally
  1105. viewer.setDirty()
  1106. // Get snapshot of the canvas as a blob
  1107. const blob = await viewer.getScreenshotBlob({mimeTye: 'image/png', quality: 90})
  1108. // Get snapshot of the canvas as a data url
  1109. const dataUrl = await viewer.getScreenshotDataUrl({mimeTye: 'image/jpeg', quality: 85})
  1110. // Dispose viewer and all resources
  1111. viewer.canvas.remove() // canvas needs to be removed separately from the DOM
  1112. viewer.dispose()
  1113. ```
  1114. [`viewer.setRenderSize`](https://threepipe.org/docs/classes/ThreeViewer.html#setRenderSize) - Sets the rendering resolution and fits the canvas in container based on the mode. The modes are `cover`, `contain`, `fill`, `scale-down` and `none`. The canvas size and render scale is calculated automatically to match the render render.
  1115. [`viewer.setSize`](https://threepipe.org/docs/classes/ThreeViewer.html#setSize) - Sets the size of the canvas and updates the renderer and the camera. If no width/height is passed, canvas is set to 100% of the container.
  1116. [`viewer.traverseSceneObjects`](https://threepipe.org/docs/classes/ThreeViewer.html#traverseSceneObjects) - Loop through all the objects in the scene model root hierarchy and calls the callback function with each object.
  1117. [`viewer.resize`](https://threepipe.org/docs/classes/ThreeViewer.html#resize) - Mark that the canvas is resized. If the size is changed, the renderer and all render targets are resized.
  1118. [`viewer.setDirty`](https://threepipe.org/docs/classes/ThreeViewer.html#setDirty) - Triggers re-render on next `requestAnimationFrame` call.
  1119. [`viewer.getScreenshotBlob`](https://threepipe.org/docs/classes/ThreeViewer.html#getScreenshotBlob) - Returns a blob of the canvas screenshot. The blob can be used to download the screenshot or upload to a server.
  1120. [`viewer.getScreenshotDataUrl`](https://threepipe.org/docs/classes/ThreeViewer.html#getScreenshotDataUrl) - Returns a data url of the canvas screenshot. The data url can be used to display the screenshot in an image element.
  1121. [`viewer.dispose`](https://threepipe.org/docs/classes/ThreeViewer.html#dispose) - Disposes the viewer and all its resources. Use this to dispose the viewer when it is no longer needed. Note: the canvas element is not removed from the DOM and needs to be removed separately.
  1122. ## RenderManager
  1123. Source Code: [src/viewer/ViewerRenderManager.ts](./src/viewer/ViewerRenderManager.ts), [src/rendering/RenderManager.ts](./src/rendering/RenderManager.ts), [src/rendering/RenderTargetManager.ts](./src/rendering/RenderTargetManager.ts)
  1124. API Reference: [ViewerRenderManager](https://threepipe.org/docs/classes/ViewerRenderManager.html), [RenderManager](https://threepipe.org/docs/classes/RenderManager.html), [RenderTargetManager](https://threepipe.org/docs/classes/RenderTargetManager.html)
  1125. It manages the rendering, composition/postprocessing of the scene and provides helpers for rendering and render target management.
  1126. ```typescript
  1127. const viewer = new ThreeViewer({...})
  1128. const renderManager = viewer.renderManager
  1129. // Get the effect composer
  1130. const composer = renderManager.composer
  1131. // Get the three.js webgl renderer
  1132. const renderer = renderManager.renderer
  1133. // Get the main Render Pass in the pipeline
  1134. const renderPass = renderManager.renderPass
  1135. // Get the main Screen Pass in the pipeline
  1136. const screenPass = renderManager.screenPass
  1137. // Set the render scale
  1138. renderManager.renderScale = Math.min(window.devicePixelRatio, 2)
  1139. // Register a custom composer pass
  1140. const customPass: IPipelinePass = new CustomPass()
  1141. renderManager.registerPass(customPass)
  1142. // Unregister a custom composer pass
  1143. renderManager.unregisterPass(customPass)
  1144. // The pipeline is automatically created and sorted based on dependencies in pipeline pass.
  1145. // To check the built pipeline
  1146. console.log(renderManager.pipeline)
  1147. // Set a custom render pipeline
  1148. renderManager.autoBuildPipeline = false
  1149. renderManager.pipeline = ['depth', 'render', 'screen']
  1150. // Check the total frames rendererd
  1151. console.log(renderManager.totalFrameCount)
  1152. // Get the current frame count in progressive rendering
  1153. console.log(renderManager.frameCount)
  1154. // Force reset shadows when some object is moved
  1155. renderManager.resetShadows()
  1156. // Render Target Management
  1157. // Get the main composer target
  1158. const composerTarget = renderManager.composerTarget
  1159. // clone the target to get a copy of the target with all the default options
  1160. const clonedTarget = composeTarget.clone()
  1161. // Create a render target, same size as the canvas. The target are automatically resized when the canvas is resized
  1162. const renderTarget = renderManager.createTarget({
  1163. sizeMultiplier: 1, // size multiplier from the canvas. 0.5 will be half width and height of the canvas
  1164. type: UnsignedByteType,
  1165. // ... // See CreateRenderTargetOptions for all options
  1166. })
  1167. // Create a render target of custom size
  1168. const renderTarget2 = renderManager.createTarget({
  1169. size: {
  1170. width: 1024,
  1171. height: 1024,
  1172. },
  1173. type: HalfFloatType,
  1174. // ...
  1175. })
  1176. // Dispose the render target
  1177. renderManager.disposeTarget(renderTarget)
  1178. // Create and release temporary targets for in-pass rendering.
  1179. const tempTarget = renderManager.getTempTarget({
  1180. sizeMultiplier: 0.5,
  1181. type: HalfFloatType,
  1182. // ...
  1183. })
  1184. // do something
  1185. renderManager.releaseTempTarget(tempTarget)
  1186. // Set how many temporary targets can remain in memory for a specific set of options
  1187. renderManager.maxTempPerKey = 10 // default = 5
  1188. // Copy/Blit a texture to the canvas or another render target with standard or a custom material
  1189. renderManager.blit(destination, {source: sourceTexture})
  1190. // Clear color of the canvas
  1191. renderManager.clearColor({r: 0, g: 0, b: 0, a: 1, depth: true, viewport: new Vector4()})
  1192. // Clear of a render target
  1193. renderManager.clearColor(renderTarget, {r: 0, g: 0, b: 0, a: 1, target: renderTarget})
  1194. // Export a render target to a blob. The type is automatically picked from exr to png based on the render target
  1195. const blob = renderManager.exportRenderTarget(renderTarget, 'auto')
  1196. // Export a render target to png/jpeg data url. This will clamp any floating point targets to fit in png/jpeg
  1197. const dataUrl = renderManager.renderTargetToDataUrl(renderTarget, 'image/png')
  1198. // Read render target pixels to array buffer. Returns Uint8Array|Uint16Array|Float32Array based on the render target type
  1199. const buffer = renderManager.renderTargetToBuffer(renderTarget)
  1200. ```
  1201. [`renderManager.composer`](https://threepipe.org/docs/classes/ViewerRenderManager.html#composer) - The three.js [EffectComposer](https://threejs.org/docs/#api/en/postprocessing/EffectComposer) used for rendering the pipeline.
  1202. [`renderManager.renderer`](https://threepipe.org/docs/classes/ViewerRenderManager.html#renderer) - The three.js [WebGLRenderer](https://threejs.org/docs/#api/en/renderers/WebGLRenderer) used for rendering
  1203. [`renderManager.context`](https://threepipe.org/docs/classes/ViewerRenderManager.html#context) - Access the WebGL rendering context for the canvas.
  1204. [`renderManager.renderPass`](https://threepipe.org/docs/classes/ViewerRenderManager.html#renderPass) - The main render pass used in the render pipeline. Instance of three.js [RenderPass](https://threejs.org/docs/#api/en/postprocessing/RenderPass) with extra features like z prepass, rgbm rendering, blurred transmission, msaa and other optimizations.
  1205. [`renderManager.screenPass`](https://threepipe.org/docs/classes/ViewerRenderManager.html#screenPass) - The main screen pass used in the render pipeline. Instance of three.js [ShaderPass](https://threejs.org/docs/#api/en/postprocessing/ShaderPass) with extra features like material extension, custom fragment, overriding read buffer, re-render to screen on change, etc
  1206. [`renderManager.renderScale`](https://threepipe.org/docs/classes/RenderManager.html#renderScale) - Sets the render scale. All targets are scaled by this factor. This is equivalent to calling `EffectComposer.setPixelRatio` and `WebGLRenderer.setPixelRatio` in three.js.
  1207. [`renderManager.resetShadows`](https://threepipe.org/docs/classes/RenderManager.html#resetShadows) - Resets all shadow maps in the scene. This is useful when some object is moved and the shadows need to be updated. This is automatically called when `scene.setDirty` or any `object.setDirty` is called, and during animation with plugins.
  1208. ### Rendering Pipeline
  1209. [`renderManager.registerPass`](https://threepipe.org/docs/classes/RenderManager.html#registerPass) - Registers a custom composer pass to the render pipeline. See [IPipelinePass](https://threepipe.org/docs/interfaces/IPipelinePass.html) interface.
  1210. [`renderManager.unregisterPass`](https://threepipe.org/docs/classes/RenderManager.html#unregisterPass) - Unregisters a custom composer pass from the render pipeline.
  1211. [`renderManager.pipeline`](https://threepipe.org/docs/classes/RenderManager.html#pipeline) - The render pipeline array. The array is automatically sorted based on dependencies in the pipeline passes.
  1212. [`renderManager.autoBuildPipeline`](https://threepipe.org/docs/classes/RenderManager.html#autoBuildPipeline) - If `true`, the pipeline is automatically created and sorted based on dependencies in pipeline pass. If `false`, the pipeline is built only once and is not changed after that. The default value is `true`.
  1213. [`renderManager.totalFrameCount`](https://threepipe.org/docs/classes/RenderManager.html#totalFrameCount) - The total frames rendered since the render manager was created.
  1214. [`renderManager.frameCount`](https://threepipe.org/docs/classes/RenderManager.html#frameCount) - The current frame count in progressive rendering. This is useful for progressive rendering effects like progressive shadows, gi, denoising, baking, anti-aliasing, and many other effects.
  1215. ### Render Targets management
  1216. [`renderManager.composerTarget`](https://threepipe.org/docs/classes/RenderManager.html#composerTarget), [`renderManager.composerTarget1`](https://threepipe.org/docs/classes/RenderManager.html#composerTarget1) - The main targets used in [EffectComposer2](https://threepipe.org/docs/classes/EffectComposer2)
  1217. [`renderManager.createTarget`](https://threepipe.org/docs/classes/RenderTargetManager.html#createTarget) - Creates a render target with the given options. The render target is automatically resized when the canvas is resized if `sizeMultiplier` is used. See [CreateRenderTargetOptions](https://threepipe.org/docs/interfaces/CreateRenderTargetOptions.html) for options
  1218. [`renderManager.disposeTarget`](https://threepipe.org/docs/classes/RenderTargetManager.html#disposeTarget) - Disposes a render target and removes it from the render target manager.
  1219. [`renderManager.getTempTarget`](https://threepipe.org/docs/classes/RenderTargetManager.html#getTempTarget) - Gets a temporary render target with the given options. The render target is automatically resized when the canvas is resized if `sizeMultiplier` is used. See [CreateRenderTargetOptions](https://threepipe.org/docs/interfaces/CreateRenderTargetOptions.html) for options
  1220. [`renderManager.releaseTempTarget`](https://threepipe.org/docs/classes/RenderTargetManager.html#releaseTempTarget) - Releases a temporary render target and adds it back to the render target manager.
  1221. [`renderManager.maxTempPerKey`](https://threepipe.org/docs/classes/RenderTargetManager.html#maxTempPerKey) - Sets how many temporary targets can remain in memory for a specific set of options. The default value is `5`.
  1222. ### Helpers
  1223. [`renderManager.blit`](https://threepipe.org/docs/classes/RenderManager.html#blit) - Blits a texture to the canvas or another render target with standard or a custom material. See [RendererBlitOptions](https://threepipe.org/docs/interfaces/RendererBlitOptions.html) for options.
  1224. [`renderManager.clearColor`](https://threepipe.org/docs/classes/RenderManager.html#clearColor) - Clears the color of the canvas or a render target.
  1225. [`renderManager.exportRenderTarget`](https://threepipe.org/docs/classes/RenderManager.html#exportRenderTarget) - Exports a render target to a blob. The type is automatically picked from exr to png based on the render target.
  1226. [`renderManager.renderTargetToDataUrl`](https://threepipe.org/docs/classes/RenderManager.html#renderTargetToDataUrl) - Exports a render target to png/jpeg data url string. This will clamp any floating point targets to fit in png/jpeg. See [RenderTargetToDataUrlOptions](https://threepipe.org/docs/interfaces/RenderTargetToDataUrlOptions.html) for options.
  1227. [`renderManager.renderTargetToBuffer`](https://threepipe.org/docs/classes/RenderManager.html#renderTargetToBuffer) - Reads render target pixels to a Uint8Array|Uint16Array|Float32Array array buffer.
  1228. ## RootScene
  1229. Source Code: [src/core/object/RootScene.ts](./src/core/object/RootScene.ts)
  1230. API Reference: [RootScene](https://threepipe.org/docs/classes/RootScene.html)
  1231. RootScene is the main scene that is rendered in the canvas.
  1232. It is an instance of three.js [Scene](https://threejs.org/docs/#api/en/scenes/Scene) with extra features including separation between model root and others,
  1233. backgroundColor, background map and background intensity,
  1234. environment map rotation and intensity, fixed env map direction patch, event bubbling in the scene hierarchy, scene config serialization, main camera management,
  1235. automatic active near far management based on scene bounds, disposing complete scene hierarchy, etc
  1236. ```typescript
  1237. const viewer = new ThreeViewer({...})
  1238. const scene = viewer.scene
  1239. // List oll loaded objects in the model root
  1240. console.log(scene.modelRoot.children)
  1241. // Set the background color
  1242. scene.setBackgroundColor('#ffffff')
  1243. // or
  1244. // scene.backgroundColor = new Color('#ffffff')
  1245. // or
  1246. // scene.backgroundColor.set('#ffffff')
  1247. // scene.onBackgroundChange() // this must be called when not using a setter or set function.
  1248. // Set a texture as background (or use viewer.setBackgroundMap). When both color and texture are set, they are multiplied
  1249. scene.background = customTexture
  1250. // Set the background same as the environment map
  1251. scene.background = 'environment' // background is automatically changed when the environment changes.
  1252. // or
  1253. // scene.background = scene.environment
  1254. // Set the background intensity
  1255. scene.backgroundIntensity = 2
  1256. // Set a texture as environment map (or use viewer.setEnvironmentMap)
  1257. scene.environment = customTexture
  1258. // Set the environment intensity
  1259. scene.envMapIntensity = 2
  1260. // Set the environment map rotation
  1261. scene.environment.rotation = Math.PI / 2
  1262. // Set Fixed env direction (rotate environment according the the camera)
  1263. scene.fixedEnvMapDirection = true
  1264. // Get the main camera used for rendering
  1265. const camera: PerspectiveCamera2 = scene.mainCamera
  1266. // Set camera props
  1267. camera.position.set(0, 0, 10)
  1268. camera.target.set(0, 0, 0)
  1269. camera.setDirty() // this needs to be called to notify the viewer to re-render the scene
  1270. // Traverse the model root hierarchy (or just use viewer.traverseSceneObjects)
  1271. scene.modelRoot.traverse((object) => {
  1272. console.log(object)
  1273. // do something with object
  1274. })
  1275. // Access the default camera (same as mainCamera if not changed explicitly)
  1276. const defaultCamera: ICamera = scene.defaultCamera
  1277. // Dispose all assets in the modelRoot
  1278. scene.disposeSceneModels()
  1279. // Remove all objects from the modelRoot
  1280. scene.clearSceneModels()
  1281. // Dispose the scene and all its resources and children
  1282. scene.dispose()
  1283. // Get bounds of the scene model root
  1284. const bounds = scene.getBounds(true, true) // true for precise bounds and ignore invisible
  1285. // Add an object to the scene or its model root depending on the options (or just use viewer.addSceneObject)
  1286. scene.addObject(object, {addToRoot: false}) // adds to the scene directly when addToRoot is true
  1287. // Load an imported model root from the asset importer
  1288. scene.loadModelRoot(object)
  1289. // notify that something has changed in the scene for re-render
  1290. scene.setDirty()
  1291. // notify that some object has changed in the scene for scene refresh(like shadow refresh, ground etc) and re-render
  1292. scene.refreshScene()
  1293. // or
  1294. scene.setDirty({refreshScene: true})
  1295. // set geometryChanged: false to prevent shadow recompute
  1296. scene.refreshScene({geometryChanged: false})
  1297. // refresh active near far. (in most cases this is done automatically and need not be called)
  1298. scene.refreshActiveNearFar()
  1299. ```
  1300. [`scene.modelRoot`](https://threepipe.org/docs/classes/RootScene.html#modelRoot) - The root object. All the objects loaded in the viewer are added to this object. And this is exported when exporting the gltf. Everything else like meta or UI objects can be added outside this.
  1301. [`scene.backgroundColor`](https://threepipe.org/docs/classes/RootScene.html#backgroundColor) - The background color of the scene. Can be a `Color | null`. This is not the same as `scene.background`. When both backgroundColor and background are set, they are multiplied.
  1302. [`scene.background`](https://threepipe.org/docs/classes/RootScene.html#background) - The background of the scene. This is the same as `scene.background` in three.js. This can be a texture or a color or null, but it's preferred to use `scene.backgroundColor` for color, and this for texture, then both can be used together.
  1303. [`scene.setBackgroundColor`](https://threepipe.org/docs/classes/RootScene.html#setBackgroundColor) - Set the background color from a string, number or color. Same as setting `backgroundColor` to a new color value.
  1304. [`scene.backgroundIntensity`](https://threepipe.org/docs/classes/RootScene.html#backgroundIntensity) - The background intensity of the scene. This is the same as `scene.backgroundIntensity` in three.js.
  1305. [`scene.environment`](https://threepipe.org/docs/classes/RootScene.html#environment) - The environment map of the scene. This is the same as `scene.environment` in three.js.
  1306. `scene.environment.rotation` - The rotation of the environment map around the y-axis.
  1307. [`scene.envMapIntensity`](https://threepipe.org/docs/classes/RootScene.html#envMapIntensity) - The environment intensity of the scene.
  1308. [`scene.fixedEnvMapDirection`](https://threepipe.org/docs/classes/RootScene.html#fixedEnvMapDirection) - If `true`, the environment map is rotated according to the camera. This is the same as `scene.fixedEnvMapDirection` in three.js.
  1309. [`scene.mainCamera`](https://threepipe.org/docs/classes/RootScene.html#mainCamera) - The main camera used for rendering. This is the same as `scene.mainCamera` in three.js.
  1310. [`scene.defaultCamera`](https://threepipe.org/docs/classes/RootScene.html#defaultCamera) - The default camera used for rendering. This is the same as `scene.defaultCamera` in three.js.
  1311. [`scene.disposeSceneModels`](https://threepipe.org/docs/classes/RootScene.html#disposeSceneModels) - Disposes all assets in the modelRoot.
  1312. [`scene.clearSceneModels`](https://threepipe.org/docs/classes/RootScene.html#clearSceneModels) - Removes all objects from the modelRoot.
  1313. [`scene.dispose`](https://threepipe.org/docs/classes/RootScene.html#dispose) - Disposes the scene and all its resources and children.
  1314. [`scene.getBounds`](https://threepipe.org/docs/classes/RootScene.html#getBounds) - Gets the bounds of the scene model root. Returns an instance of three.js [Box3](https://threejs.org/docs/#api/en/math/Box3) with min and max bounds according to parameters.
  1315. [`scene.addObject`](https://threepipe.org/docs/classes/RootScene.html#addObject) - Adds an object to the scene or its model root depending on the options. If `addToRoot` is `true`, the object is added to the model root, else it is added to the scene directly.
  1316. [`scene.setDirty`](https://threepipe.org/docs/classes/RootScene.html#setDirty) - Notifies that something has changed in the scene for re-render.
  1317. [`scene.refreshScene`](https://threepipe.org/docs/classes/RootScene.html#refreshScene) - Notifies that some object has changed in the scene for scene refresh(like shadow refresh, ground etc) and re-render. Slower than `setDirty`, as it refreshes shadows, updates bounds, etc.
  1318. [`scene.refreshActiveNearFar`](https://threepipe.org/docs/classes/RootScene.html#refreshActiveNearFar) - Refreshes active near far. (in most cases this is done automatically and need not be called)
  1319. [`scene.loadModelRoot`](https://threepipe.org/docs/classes/RootScene.html#loadModelRoot) - Loads an imported model root from the asset importer. This is used internally and in most cases, you don't need to call this.
  1320. ### Scene Events
  1321. RootScene dispatches many events that are useful when writing app logic or plugins
  1322. `'sceneUpdate'` - Listen to `refreshScene` called in RootScene. When some object changes.
  1323. `'addSceneObject'` - When a new object is added to the scene
  1324. `'mainCameraChange'` - When the main camera is changed to some other camera.
  1325. `'mainCameraUpdate'` - When some properties in the current main camera has changed.
  1326. `'environmentChanged'` - When the environment map changes
  1327. `'backgroundChanged'` - When the background map or color changes
  1328. `'materialUpdate`' - When a material in the scene has updated. (setDirty called on the material)
  1329. `'objectUpdate`' - When a object in the scene has updated. (setDirty called on the object)
  1330. `'textureUpdate`' - When a texture in the scene has updated. (setDirty called on the texture)
  1331. `'cameraUpdate`' - When a camera in the scene has updated.
  1332. (setDirty called on the camera)
  1333. `'geometryUpdate`' - When a geometry in the scene has updated.
  1334. (setDirty called on the geometry)
  1335. `'geometryChanged`' - When a geometry is changed on any mesh
  1336. `'materialChanged'` - When a material is changed on any mesh
  1337. Check [IObject3DEventTypes](https://threepipe.org/docs/interfaces/IObject3DEventTypes.html) and[ISceneEventTypes](https://threepipe.org/docs/interfaces/ISceneEventTypes.html) for more information.
  1338. ## ICamera
  1339. Source Code: [src/core/camera/PerspectiveCamera2.ts](./src/core/camera/PerspectiveCamera2.ts), [src/core/ICamera.ts](./src/core/ICamera.ts)
  1340. API Reference: [PerspectiveCamera2](https://threepipe.org/docs/classes/PerspectiveCamera2.html), [ICamera](https://threepipe.org/docs/interfaces/ICamera.html)
  1341. ICamera is an interface for a camera that extends the three.js [Camera](https://threejs.org/docs/#api/en/cameras/Camera).
  1342. PerspectiveCamera2 implements the interface,
  1343. extending from three.js [PerspectiveCamera](https://threejs.org/docs/#api/en/cameras/PerspectiveCamera) with extra features like target, automatic aspect management, automatic near far management(from RootScene), camera control attachment and hooks(like OrbitControls) and the ability to set as the main camera in the root scene.
  1344. ```typescript
  1345. import {OrbitControls3} from './OrbitControls3'
  1346. const viewer = new ThreeViewer({...})
  1347. const camera: PerspectiveCamera2 = viewer.scene.mainCamera
  1348. // Set the camera position
  1349. camera.position.set(0, 0, 10)
  1350. // Set the camera target (where the camera looks at)
  1351. camera.target.set(0, 0, 0)
  1352. // Set the camera fov
  1353. camera.fov = 45
  1354. // Set the camera aspect ratio
  1355. camera.autoAspect = false // disable automatic aspect management based on the canvas size
  1356. camera.aspect = 1
  1357. // Set camera near far bounds.
  1358. // Near, Far plane will be calculated automatically within these limits
  1359. // Try changing these values when encountering z-fighting issues or far-plane clipping
  1360. camera.minNearPlane = 0.5 // min near plane
  1361. camera.maxFarPlane = 10 // max far plane
  1362. // Set a custom camera near far
  1363. camera.autoNearFar = false // disable automatic near far management based on the scene bounds
  1364. camera.minNearPlane = 0.1 // near plane
  1365. camera.maxFarPlane = 1000 // far plane
  1366. // this needs to be called to notify the viewer to re-render the scene
  1367. // in most cases this is done internally. But calling this does not have much impact
  1368. camera.setDirty()
  1369. // Check if user can interact with the camera. Also checks if its the main camera.
  1370. console.log(camera.canUserInteract)
  1371. // Get the camera controls (orbit controls for the default camera)
  1372. const controls: OrbitControls3 = camera.controls
  1373. // Disable controls
  1374. controls.enabled = false
  1375. // Change the controls mode
  1376. camera.controlsMode = 'none' // this will remove the current controls.
  1377. // Register a custom camera controls
  1378. camera.setControlsCtor('customOrbit', (camera, domElement) => new CustomOrbitControls(camera, domElement))
  1379. // Set the camera controls
  1380. camera.controlsMode = 'customOrbit' // this will initialize the controls with the customOrbit constructor and set it on the camera
  1381. // Disable interactions to the camera. (eg when animating)
  1382. camera.setInteractions(false, 'animation')
  1383. // Enable interactions back
  1384. camera.setInteractions(true, 'animation') // this will enable interactions when all the keys have been set to true(which were set to false earlier)
  1385. // Force refresh aspect ratio (this is done automatically with a ResizeObserver on the canvas in the viewer)
  1386. camera.refreshAspect()
  1387. // Set the camera as the main camera
  1388. camera.activateMain()
  1389. // Deactivate the camera as the main camera
  1390. camera.deactivateMain()
  1391. ```
  1392. [`camera.target`](https://threepipe.org/docs/classes/PerspectiveCamera2.html#target) - The target of the camera. This is the same as `controls.target` in three.js. The target is always in world-space coordinates, as opposed to position, rotation, and scale which are always relative to their parent.
  1393. [`camera.autoAspect`](https://threepipe.org/docs/classes/PerspectiveCamera2.html#autoAspect) - If `true`, the aspect ratio is automatically calculated based on the canvas size.
  1394. [`camera.aspect`](https://threepipe.org/docs/classes/PerspectiveCamera2.html#aspect) - The aspect ratio of the camera. This is the same as `camera.aspect` in three.js. This is only used when `camera.autoAspect` is `false`.
  1395. [`camera.minNearPlane`](https://threepipe.org/docs/classes/PerspectiveCamera2.html#minNearPlane) - The minimum near plane of the camera. This is the same as `camera.near` in three.js when `camera.autoNearFar` is `false`, otherwise it is the minimum near plane distance from the camera allowed when computing automatically
  1396. [`camera.maxFarPlane`](https://threepipe.org/docs/classes/PerspectiveCamera2.html#maxFarPlane) - The maximum far plane of the camera. This is the same as `camera.far` in three.js when `camera.autoNearFar` is `false`, otherwise it is the maximum far plane distance from the camera allowed when computing automatically
  1397. [`camera.autoNearFar`](https://threepipe.org/docs/classes/PerspectiveCamera2.html#autoNearFar) - If `true` (default), the near and far planes are automatically calculated based on the scene bounds.
  1398. [`camera.setDirty`](https://threepipe.org/docs/classes/PerspectiveCamera2.html#setDirty) - Notifies that something has changed in the camera for re-render.
  1399. [`camera.canUserInteract`](https://threepipe.org/docs/classes/PerspectiveCamera2.html#canUserInteract) - Checks if user can interact with the camera. Also checks if it's the main camera.
  1400. [`camera.controls`](https://threepipe.org/docs/classes/PerspectiveCamera2.html#controls) - Get the current camera controls set on the camera. This can be changed by changing `controlsMode`
  1401. [`camera.controlsMode`](https://threepipe.org/docs/classes/PerspectiveCamera2.html#controlsMode) - Get or set the current controls that are attached to the camera. More modes can be registered with `setControlsCtor`. Default for the default camera is `orbit` and `none` for any new cameras.
  1402. [`camera.setControlsCtor`](https://threepipe.org/docs/classes/PerspectiveCamera2.html#setControlsCtor) - Register a custom camera controls constructor. The controls can be set by setting `controlsMode` to the key/name of the controls.
  1403. [`camera.setInteractions`](https://threepipe.org/docs/classes/PerspectiveCamera2.html#setInteractions) - If `true`, the camera can be interacted with. This is useful when animating the camera or using the window scroll or programmatically automating the viewer. Using this multiple plugins can disable interactions and it will be enabled again when all of them enable it back.
  1404. [`camera.refreshAspect`](https://threepipe.org/docs/classes/PerspectiveCamera2.html#refreshAspect) - Force refresh aspect ratio (this is done automatically with a ResizeObserver on the canvas in the viewer or when `viewer.resize()` is called)
  1405. [`camera.activateMain`](https://threepipe.org/docs/classes/PerspectiveCamera2.html#activateMain) - Set the camera as the main camera. This is the same as doing `scene.mainCamera = camera`. The camera needs to be in the scene hierarchy for this to work.
  1406. [`camera.deactivateMain`](https://threepipe.org/docs/classes/PerspectiveCamera2.html#deactivateMain) - Deactivate the camera as the main camera.
  1407. See also [CameraViewPlugin](#cameraviewplugin) for camera focus animation.
  1408. Note: The constructor signature of `PerspectiveCamera2` is different `PerspectiveCamera`(from three.js), since it requires the canvas and the controlsMode during creation.
  1409. Because of this `PerspectiveCamera0` is provided with the same signature as `PerspectiveCamera` for compatibility, in case the controls functionality is not required.
  1410. ## AssetManager
  1411. Source Code: [src/assetmanager/AssetManager.ts](./src/assetmanager/AssetManager.ts)
  1412. API Reference: [AssetManager](https://threepipe.org/docs/classes/AssetManager.html)
  1413. `AssetManager` is a class that manages the loading and exporting of assets and provides helpers for caching assets. It is used internally in the viewer and can be used to load assets outside the viewer. It provides a modular framework for adding more asset loaders and exporters.
  1414. ```typescript
  1415. const viewer = new ThreeViewer({...})
  1416. const assetManager = viewer.assetManager
  1417. // Add an asset or an asset bundle
  1418. const assets = await assetManager.addAsset('https://example.com/model.zip')
  1419. // or
  1420. const assets1 = await assetManager.addAsset({
  1421. path: 'https://example.com/model.zip',
  1422. file: blob,
  1423. })
  1424. // Get the storage used in the asset manager for caching
  1425. const storage: Cache | Storage = assetManager.storage
  1426. // Get the importer. Provides low level functions to import assets
  1427. const importer = assetManager.importer
  1428. // import a file by asset or url
  1429. const file = await importer.import('https://example.com/model.gltf')
  1430. // Import a Map<string, File> from drag drop
  1431. const res = await importer.importFiles(mapOfFiles, {})
  1432. // Register a custom path that maps to a File object. Useful when some file types have path references to other files.
  1433. importer.registerFile('/myFile.png', file) // this returns the three.js loader for that kind of file.
  1434. // Unregister the path
  1435. importer.unregisterFile('/myFile.png')
  1436. // Unregister all files and clear the loader cache(memory, not storage)
  1437. importer.clearCache()
  1438. // Add custom importers (check extra load plugins for more examples)
  1439. importer.addImporter(new Importer(class extends PLYLoader implements ILoader {
  1440. transform(res: BufferGeometry, _: AnyOptions): Mesh | undefined {
  1441. return res ? new Mesh(res, new PhysicalMaterial({color: new Color(1, 1, 1)})) : undefined
  1442. }
  1443. }, ['ply'], ['text/plain+ply'], false))
  1444. // Get the exporter. Provides low level functions to export assets
  1445. const exporter = assetManager.exporter
  1446. // Export any IObject3D, IMaterial, ITexture, IRenderTarget
  1447. const exported = exporter.exportObject(obj, options)
  1448. // Add a custom exporter
  1449. exporter.addExporter({
  1450. ext: ['gltf', 'glb'], // file extensions
  1451. extensions: [], // extensions for the exporter
  1452. ctor: (assetExporter, iexporter) => {
  1453. return new GLTFExporter2()
  1454. }
  1455. })
  1456. // Material Manager
  1457. const materialManager = assetManager.materialManager
  1458. // Create a material of type
  1459. const mat1 = materialManager.create('physical')
  1460. const mat2 = materialManager.create('unlit')
  1461. // find or create a material by uuid
  1462. const mat3 = materialManager.findOrCreate('00000000-0000-0000-0000-000000000000', {color: '#ffffff'})
  1463. // find a material creation template
  1464. const template = materialManager.findTemplate('physical')
  1465. // Get all materials
  1466. const materials = materialManager.getAllMaterials()
  1467. // Get all materials of type
  1468. const materials2 = materialManager.getMaterialsOfType(PhysicalMaterial.TypeSlug)
  1469. // register a custom material to the manager for tracking and extensions
  1470. // Note all materials created in threepipe internally are registered automatically on creation or when added to any scene object.
  1471. materialManager.registerMaterial(customMat)
  1472. // unregister
  1473. materialManager.unregisterMaterial(customMat)
  1474. // clear all material references
  1475. materialManager.clearMaterials()
  1476. // Register a custom material template
  1477. materialManager.registerTemplate({
  1478. generator: (params: any) => new PhysicalMaterial(params),
  1479. name: 'custom',
  1480. materialType: PhysicalMaterial.TYPE,
  1481. params: {
  1482. color: '#ffffff',
  1483. roughness: 0.5,
  1484. metalness: 0.5,
  1485. },
  1486. })
  1487. const mat4 = materialManager.create('custom')
  1488. // convert a standard three.js material to threepipe material
  1489. const mat5 = materialManager.convertToIMaterial(new ShadowMaterial(), {materialTemplate: 'test'})
  1490. // register a custom material extension for all materials in the viewer
  1491. materialManager.registerMaterialExtension(customExtension)
  1492. // unregister
  1493. materialManager.unregisterMaterialExtension(customExtension)
  1494. // remove all extensions
  1495. materialManager.clearExtensions()
  1496. // Apply a material properties to other material(s) in the scene by name or uuid
  1497. materialManager.applyMaterial(goldMaterial, 'METAL') // this will copy the properties from goldMaterial to all the materials(or objects) in the viewer with the name METAL.
  1498. // export a material as JSON. Note: use AssetExporter instead to export all the embedded assets and properties properly.
  1499. const blob = materialManager.exportMaterial(mat)
  1500. // dispose manager and all materials.
  1501. materialManager.dispose()
  1502. ```
  1503. [`assetManager.addAsset`](https://threepipe.org/docs/classes/AssetManager.html#addAsset) - Add an asset or an asset bundle. Returns a promise that resolves to an array of asset objects. An asset can contain multiple objects, hence an array is returned. Use shorthand `viewer.load(path)` to load a single asset from a single file.
  1504. [`assetManager.storage`](https://threepipe.org/docs/classes/AssetManager.html#storage) - Get the storage used in the asset manager for caching. This is the storage that can be passed in the `ThreeViewer` contructor options.
  1505. [`assetManager.importer`](https://threepipe.org/docs/classes/AssetManager.html#importer) - Get the importer. Provides low-level functions to import assets. This is an instance of [AssetImporter](https://threepipe.org/docs/classes/AssetImporter.html).
  1506. [`assetManager.exporter`](https://threepipe.org/docs/classes/AssetManager.html#exporter) - Get the exporter. Provides low-level functions to export assets. This is an instance of [AssetExporter](https://threepipe.org/docs/classes/AssetExporter.html).
  1507. ### AssetImporter
  1508. [`importer.import`](https://threepipe.org/docs/classes/AssetImporter.html#import) - Import a file by asset or url. Returns a promise that resolves to a [File](https://threepipe.org/docs/classes/File.html) object.
  1509. [`importer.importFiles`](https://threepipe.org/docs/classes/AssetImporter.html#importFiles) - Import a Map<string, File> from drag and drop. Returns a promise that resolves to a Map<string, any[]> of imported object arrays.
  1510. [`importer.registerFile`](https://threepipe.org/docs/classes/AssetImporter.html#registerFile) - Register a custom path that maps to a File object. Useful when some file types have path references to other files. Like when importing a .zip with a .gltf file that references a .bin file, or when loading remote files from custom local cache implementation.
  1511. [`importer.unregisterFile`](https://threepipe.org/docs/classes/AssetImporter.html#unregisterFile) - Unregister the path.
  1512. [`importer.clearCache`](https://threepipe.org/docs/classes/AssetImporter.html#clearCache) - Unregister all the registered files and clear the loader cache(memory cache, not cache-storage).
  1513. [`importer.addImporter`](https://threepipe.org/docs/classes/AssetImporter.html#addImporter) - Add custom importers (check extra load plugins for more examples). This allows to pass a class to a ILoader, that is used to import assets. Loaders are only created when a file is being loaded of that type. And they remain in the loader cache until `clearCache` or `clearLoaderCache` is called.
  1514. ### AssetExporter
  1515. [`exporter.exportObject`](https://threepipe.org/docs/classes/AssetExporter.html#exportObject) - Export any IObject3D, IMaterial, ITexture, IRenderTarget. Returns a promise that resolves to an exported object. Use `viewer.export` or `AssetExporterPlugin`, which provide more features and shortcuts to export viewer, scene and plugins as well.
  1516. [`exporter.addExporter`](https://threepipe.org/docs/classes/AssetExporter.html#addExporter) - Add a custom exporter for a custom file type.
  1517. ### MaterialManager
  1518. [`materialManager.create`](https://threepipe.org/docs/classes/MaterialManager.html#create) - Create a new material of a given type and with passed properties. Returns an implementation of [IMaterial](https://threepipe.org/docs/interfaces/IMaterial.html).
  1519. [`materialManager.findOrCreate`](https://threepipe.org/docs/classes/MaterialManager.html#findOrCreate) - Find or create a material by uuid. Returns an instance of [IMaterial](https://threepipe.org/docs/interfaces/IMaterial.html). If a material with the uuid exists, it is returned, else a new material is created with the passed properties.
  1520. [`materialManager.findTemplate`](https://threepipe.org/docs/classes/MaterialManager.html#findTemplate) - Find a material creation template. Returns an instance of [IMaterialTemplate](https://threepipe.org/docs/interfaces/IMaterialTemplate.html). Material templates are used to create materials of a given type with default properties.
  1521. [`materialManager.getAllMaterials`](https://threepipe.org/docs/classes/MaterialManager.html#getAllMaterials) - Get all materials registered with the manager.
  1522. [`materialManager.getMaterialsOfType`](https://threepipe.org/docs/classes/MaterialManager.html#getMaterialsOfType) - Get all materials of a specific type. Pass in the typeslug from the class like `pmat` or `dmat` to identify the material.
  1523. [`materialManager.registerMaterial`](https://threepipe.org/docs/classes/MaterialManager.html#registerMaterial) - Register a new material to the manager for tracking and extensions. Note: all materials created in threepipe internally or any that are set to any object in the scene are registered automatically on creation or when used
  1524. [`materialManager.unregisterMaterial`](https://threepipe.org/docs/classes/MaterialManager.html#unregisterMaterial) - Unregister a material from the manager.
  1525. [`materialManager.clearMaterials`](https://threepipe.org/docs/classes/MaterialManager.html#clearMaterials) - Clear all registered material references.
  1526. [`materialManager.registerTemplate`](https://threepipe.org/docs/classes/MaterialManager.html#registerTemplate) - Register a custom material template. Requires an instance of [IMaterialTemplate](https://threepipe.org/docs/interfaces/IMaterialTemplate.html). Material templates are used to create materials of a given type with default properties.
  1527. [`materialManager.convertToIMaterial`](https://threepipe.org/docs/classes/MaterialManager.html#convertToIMaterial) - Convert/upgrade a standard three.js material to threepipe material, by making it conform to [IMaterial](https://threepipe.org/docs/interfaces/IMaterial.html).
  1528. [`materialManager.registerMaterialExtension`](https://threepipe.org/docs/classes/MaterialManager.html#registerMaterialExtension) - Register a custom material extension for all materials in the viewer. Requires an instance of [IMaterialExtension](https://threepipe.org/docs/interfaces/IMaterialExtension.html). Material extensions are used to add custom properties, methods, uniforms, defines, shader patches etc to predefined materials. The extensions are added to the material when the mateiral or extension is registered to the manager.
  1529. [`materialManager.unregisterMaterialExtension`](https://threepipe.org/docs/classes/MaterialManager.html#unregisterMaterialExtension) - Unregister a material extension from the manager.
  1530. [`materialManager.clearExtensions`](https://threepipe.org/docs/classes/MaterialManager.html#clearExtensions) - Remove all material extensions from the manager.
  1531. [`materialManager.applyMaterial`](https://threepipe.org/docs/classes/MaterialManager.html#applyMaterial) - Apply a material properties to other material(s) in the scene by name or uuid. This is useful when you want to change the properties of all materials with a given name or uuid. This can also be a regex, in that case a regex.match will be performed on the material/object name.
  1532. [`materialManager.exportMaterial`](https://threepipe.org/docs/classes/MaterialManager.html#exportMaterial) - Export a material as JSON. Note: use `viewer.export` or `AssetExporter` instead to export all the embedded assets properly.
  1533. [`materialManager.dispose`](https://threepipe.org/docs/classes/MaterialManager.html#dispose) - Dispose manager and all materials.
  1534. ## Other classes and interfaces
  1535. Threepipe provides various interfaces and classes for for three.js objects with upgraded features like UI events, serialization, etc.
  1536. These can be used while developing new apps to get better developer experience and features.
  1537. When standard three.js instances are added to the scene, they are automatically upgraded automatically at runtime to make them work with the rest of the framework.
  1538. Some important interfaces:
  1539. * [IObject3D](https://threepipe.org/docs/interfaces/IObject3D.html) - Interface for an extended version of three.js [Object3D](https://threejs.org/docs/#api/en/core/Object3D).
  1540. * [ILight](https://threepipe.org/docs/interfaces/ILight.html) - Interface for an extended version of three.js [Light](https://threejs.org/docs/#api/en/lights/Light).
  1541. * [ICamera](https://threepipe.org/docs/interfaces/ICamera.html) - Interface for an extended version of three.js [Camera](https://threejs.org/docs/#api/en/cameras/Camera).
  1542. * [IMaterial](https://threepipe.org/docs/interfaces/IMaterial.html) - Interface for an extended version of three.js [Material](https://threejs.org/docs/#api/en/materials/Material).
  1543. * [ITexture](https://threepipe.org/docs/interfaces/ITexture.html) - Interface for an extended version of three.js [Texture](https://threejs.org/docs/#api/en/textures/Texture).
  1544. * [IRenderTarget](https://threepipe.org/docs/interfaces/IRenderTarget.html) - Interface for an extended version of three.js [WebGLRenderTarget](https://threejs.org/docs/#api/en/renderers/WebGLRenderTarget).
  1545. * [IGeometry](https://threepipe.org/docs/interfaces/IGeometry.html) - Interface for an extended version of three.js [BufferGeometry](https://threejs.org/docs/#api/en/core/BufferGeometry).
  1546. * [IScene](https://threepipe.org/docs/interfaces/IScene.html) - Interface for an extended version of three.js [Scene](https://threejs.org/docs/#api/en/scenes/Scene).
  1547. * [IRenderManager](https://threepipe.org/docs/interfaces/IRenderManager.html) - Interface for rendering and render target manager.
  1548. Some important classes
  1549. * [Mesh2](https://threepipe.org/docs/classes/Mesh2.html) - Extends three.js [Mesh](https://threejs.org/docs/#api/en/objects/Mesh) and implements [IObject3D](https://threepipe.org/docs/interfaces/IObject3D.html).
  1550. * [PerspectiveCamera2](https://threepipe.org/docs/classes/PerspectiveCamera2.html) - Extends three.js [PerspectiveCamera](https://threejs.org/docs/#api/en/cameras/PerspectiveCamera) and implements [ICamera](https://threepipe.org/docs/interfaces/ICamera.html). (different constructor than PerspectiveCamera)
  1551. * [PerspectiveCamera0](https://threepipe.org/docs/classes/PerspectiveCamera0.html) - Extends three.js [PerspectiveCamera](https://threejs.org/docs/#api/en/cameras/PerspectiveCamera) and implements [ICamera](https://threepipe.org/docs/interfaces/ICamera.html). (same constructor than PerspectiveCamera)
  1552. * [BufferGeometry2](https://threepipe.org/docs/classes/BufferGeometry2.html) - Extends three.js [BufferGeometry](https://threejs.org/docs/#api/en/core/BufferGeometry) and implements [IGeometry](https://threepipe.org/docs/interfaces/IGeometry.html).
  1553. * [RootScene](https://threepipe.org/docs/classes/RootScene.html) - Extends three.js [Scene](https://threejs.org/docs/#api/en/scenes/Scene) and implements [IScene](https://threepipe.org/docs/interfaces/IScene.html).
  1554. * [RenderManager](https://threepipe.org/docs/classes/RenderManager.html) - Implements [IRenderManager](https://threepipe.org/docs/interfaces/IRenderManager.html).
  1555. * [PhysicalMaterial](https://threepipe.org/docs/classes/PhysicalMaterial.html) - Extends three.js [MeshPhysicalMaterial](https://threejs.org/docs/#api/en/materials/MeshPhysicalMaterial) and implements [IMaterial](https://threepipe.org/docs/interfaces/IMaterial.html).
  1556. * [UnlitMaterial](https://threepipe.org/docs/classes/UnlitMaterial.html) - Extends three.js [MeshBasicMaterial](https://threejs.org/docs/#api/en/materials/MeshBasicMaterial) and implements [IMaterial](https://threepipe.org/docs/interfaces/IMaterial.html).
  1557. * [LineMaterial2](https://threepipe.org/docs/classes/LineMaterial2.html) - Extends three.js [LineMaterial](https://threejs.org/docs/#api/en/materials/LineMaterial) and implements [IMaterial](https://threepipe.org/docs/interfaces/IMaterial.html).
  1558. * [UnlitLineMaterial](https://threepipe.org/docs/classes/UnlitLineMaterial.html) - Extends three.js [LineBasicMaterial](https://threejs.org/docs/#api/en/materials/LineBasicMaterial) and implements [IMaterial](https://threepipe.org/docs/interfaces/IMaterial.html).
  1559. * [DirectionalLight2](https://threepipe.org/docs/classes/DirectionalLight2.html) - Extends three.js [DirectionalLight](https://threejs.org/docs/#api/en/lights/DirectionalLight) and implements [ILight](https://threepipe.org/docs/interfaces/ILight.html).
  1560. * [SpotLight2](https://threepipe.org/docs/classes/SpotLight2.html) - Extends three.js [SpotLight](https://threejs.org/docs/#api/en/lights/SpotLight) and implements [ILight](https://threepipe.org/docs/interfaces/ILight.html).
  1561. * [PointLight2](https://threepipe.org/docs/classes/PointLight2.html) - Extends three.js [PointLight](https://threejs.org/docs/#api/en/lights/PointLight) and implements [ILight](https://threepipe.org/docs/interfaces/ILight.html).
  1562. * [HemisphereLight2](https://threepipe.org/docs/classes/HemisphereLight2.html) - Extends three.js [HemisphereLight](https://threejs.org/docs/#api/en/lights/HemisphereLight) and implements [ILight](https://threepipe.org/docs/interfaces/ILight.html).
  1563. * [AmbientLight2](https://threepipe.org/docs/classes/AmbientLight2.html) - Extends three.js [AmbientLight](https://threejs.org/docs/#api/en/lights/AmbientLight) and implements [ILight](https://threepipe.org/docs/interfaces/ILight.html).
  1564. * [RectAreaLight2](https://threepipe.org/docs/classes/RectAreaLight2.html) - Extends three.js [RectAreaLight](https://threejs.org/docs/#api/en/lights/RectAreaLight) and implements [ILight](https://threepipe.org/docs/interfaces/ILight.html).
  1565. # Threepipe Plugins
  1566. ThreePipe has a simple plugin system that allows you to easily add new features to the viewer. Plugins can be added to the viewer using the `addPlugin` and `addPluginSync` methods. The plugin system is designed to be modular and extensible. Plugins can be added to the viewer at any time and can be removed using the `removePlugin` and `removePluginSync` methods.
  1567. ## TonemapPlugin
  1568. [//]: # (todo: image)
  1569. [Example](https://threepipe.org/examples/#tonemap-plugin/) &mdash;
  1570. [Source Code](./src/plugins/postprocessing/TonemapPlugin.ts) &mdash;
  1571. [API Reference](https://threepipe.org/docs/classes/TonemapPlugin.html)
  1572. TonemapPlugin adds a post-processing material extension to the ScreenPass in render manager
  1573. that applies tonemapping to the color. The tonemapping operator can be changed
  1574. by setting the `toneMapping` property of the plugin. The default tonemapping operator is `ACESFilmicToneMapping`.
  1575. Other Tonemapping properties can be like `exposure`, `contrast` and `saturation`
  1576. TonemapPlugin is added by default in ThreeViewer unless `tonemap` is set to `false` in the options.
  1577. ## DropzonePlugin
  1578. [//]: # (todo: image)
  1579. [Example](https://threepipe.org/examples/#dropzone-plugin/) &mdash;
  1580. [Source Code](./src/plugins/interaction/DropzonePlugin.ts) &mdash;
  1581. [API Reference](https://threepipe.org/docs/classes/DropzonePlugin.html)
  1582. DropzonePlugin adds support for drag and drop of local files to automatically import, process and load them into the viewer.
  1583. DropzonePlugin can be added by default in ThreeViewer
  1584. by setting the `dropzone` property to `true` or an object of `DropzonePluginOptions` in the options.
  1585. ```typescript
  1586. import {DropzonePlugin, ThreeViewer} from 'threepipe'
  1587. const viewer = new ThreeViewer({
  1588. canvas: document.getElementById('mcanvas') as HTMLCanvasElement,
  1589. dropzone: true, // just set to true to enable drag drop functionatility in the viewer
  1590. })
  1591. ```
  1592. To set custom options,
  1593. pass an object of [DropzonePluginOptions](https://threepipe.org/docs/interfaces/DropzonePluginOptions.html) type to the `dropzone` property.
  1594. ```typescript
  1595. import {DropzonePlugin, ThreeViewer} from 'threepipe'
  1596. const viewer = new ThreeViewer({
  1597. canvas: document.getElementById('mcanvas') as HTMLCanvasElement,
  1598. dropzone: { // this can also be set to true and configured by getting a reference to the DropzonePlugin
  1599. allowedExtensions: ['gltf', 'glb', 'hdr', 'png', 'jpg', 'json', 'fbx', 'obj', 'bin', 'exr'], // only allow these file types. If undefined, all files are allowed.
  1600. addOptions: {
  1601. disposeSceneObjects: true, // auto dispose of old scene objects
  1602. autoSetEnvironment: true, // when hdr is dropped
  1603. autoSetBackground: true, // when any image is dropped
  1604. autoCenter: true, // auto center the object
  1605. autoScale: true, // auto scale according to radius
  1606. autoScaleRadius: 2,
  1607. license: 'Imported from dropzone', // Any license to set on imported objects
  1608. importConfig: true, // import config from file
  1609. },
  1610. // check more options in the DropzonePluginOptions interface
  1611. },
  1612. })
  1613. ```
  1614. ## ProgressivePlugin
  1615. [//]: # (todo: image)
  1616. [Example](https://threepipe.org/examples/#progressive-plugin/) &mdash;
  1617. [Source Code](./src/plugins/pipeline/ProgressivePlugin.ts) &mdash;
  1618. [API Reference](https://threepipe.org/docs/classes/ProgressivePlugin.html)
  1619. Progressive Plugin adds a post-render pass to blend the last frame with the current frame.
  1620. This is used as a dependency in other plugins for progressive rendering effect which is useful for progressive shadows, gi, denoising, baking, anti-aliasing, and many other effects. The helper function `convergedPromise` returns a new promise that can be used to wait for the progressive rendering to converge.
  1621. ## SSAAPlugin
  1622. [//]: # (todo: image)
  1623. [Example](https://threepipe.org/examples/#ssaa-plugin/) &mdash;
  1624. [Source Code](./src/plugins/pipeline/SSAAPlugin.ts) &mdash;
  1625. [API Reference](https://threepipe.org/docs/classes/SSAAPlugin.html)
  1626. SSAA Plugin adds support for [Super Sampling Anti-Aliasing](https://en.wikipedia.org/wiki/Supersampling) to the viewer. Simply add the plugin to the viewer to use it.
  1627. It jitters the camera view offset over multiple frames, which are then blended by the [ProgressivePlugin](#progressiveplugin) to create a higher quality image. This is useful for reducing aliasing artifacts in the scene.
  1628. By default, the pipeline only renders once per request animation frame. So we don't get any anti-aliasing while moving. For that, either use the TAA(Temporal Anti-aliasing) plugin or for the case of simple scenes - render multiple times per frame which can be done by setting `plugin.rendersPerFrame` or `viewer.rendersPerFrame`. Check out the [example](https://threepipe.org/examples/#ssaa-plugin/) to see the effect on frame rate.
  1629. ```typescript
  1630. const ssaa = viewer.addPluginSync(new SSAAPlugin())
  1631. ssaa.enabled = true // toggle jittering(if you want to set custom view offset)
  1632. ssaa.rendersPerFrame = 4 // render 4 times per frame (max 32 is useful)
  1633. ```
  1634. ## DepthBufferPlugin
  1635. [//]: # (todo: image)
  1636. [Example](https://threepipe.org/examples/#depth-buffer-plugin/) &mdash;
  1637. [Source Code](./src/plugins/pipeline/DepthBufferPlugin.ts) &mdash;
  1638. [API Reference](https://threepipe.org/docs/classes/DepthBufferPlugin.html)
  1639. Depth Buffer Plugin adds a pre-render pass to the render manager and renders a depth buffer to a target. The render target can be accessed by other plugins throughout the rendering pipeline to create effects like depth of field, SSAO, SSR, etc.
  1640. ```typescript
  1641. import {ThreeViewer, DepthBufferPlugin} from 'threepipe'
  1642. const viewer = new ThreeViewer({...})
  1643. const depthPlugin = viewer.addPluginSync(new DepthBufferPlugin(HalfFloatType))
  1644. const depthTarget = depthPlugin.target;
  1645. // Use the depth target by accesing `depthTarget.texture`.
  1646. ```
  1647. The depth values are based on camera near far values, which are controlled automatically by the viewer. To manually specify near, far values and limits, it can be set in the camera userData. Check the [example](https://threepipe.org/examples/#depth-buffer-plugin/) for more details.
  1648. ## NormalBufferPlugin
  1649. [//]: # (todo: image)
  1650. [Example](https://threepipe.org/examples/#normal-buffer-plugin/) &mdash;
  1651. [Source Code](./src/plugins/pipeline/NormalBufferPlugin.ts) &mdash;
  1652. [API Reference](https://threepipe.org/docs/classes/NormalBufferPlugin.html)
  1653. Normal Buffer Plugin adds a pre-render pass to the render manager and renders a normal buffer to a target. The render target can be accessed by other plugins throughout the rendering pipeline to create effects like SSAO, SSR, etc.
  1654. Note: Use [`GBufferPlugin`](#GBufferPlugin) if using both `DepthBufferPlugin` and `NormalBufferPlugin` to render both depth and normal buffers in a single pass.
  1655. ```typescript
  1656. import {ThreeViewer, NormalBufferPlugin} from 'threepipe'
  1657. const viewer = new ThreeViewer({...})
  1658. const normalPlugin = viewer.addPluginSync(new NormalBufferPlugin())
  1659. const normalTarget = normalPlugin.target;
  1660. // Use the normal target by accessing `normalTarget.texture`.
  1661. ```
  1662. ## GBufferPlugin
  1663. [//]: # (todo: image)
  1664. [Example](https://threepipe.org/examples/#gbuffer-plugin/) &mdash;
  1665. [Source Code](./src/plugins/pipeline/GBufferPlugin.ts) &mdash;
  1666. [API Reference](https://threepipe.org/docs/classes/GBufferPlugin.html)
  1667. GBuffer Plugin adds a pre-render pass to the render manager and renders depth+normals to a target and some customizable flags to another. The multiple render target and textures can be accessed by other plugins throughout the rendering pipeline to create effects like SSAO, SSR, etc.
  1668. ```typescript
  1669. import {ThreeViewer, GBufferPlugin} from 'threepipe'
  1670. const viewer = new ThreeViewer({...})
  1671. const gBufferPlugin = viewer.addPluginSync(new GBufferPlugin())
  1672. const gBuffer = gBufferPlugin.target;
  1673. const normalDepth = gBufferPlugin.normalDepthTexture;
  1674. const gBufferFlags = gBufferPlugin.flagsTexture;
  1675. ```
  1676. ## SSAOPlugin
  1677. [//]: # (todo: image)
  1678. [Example](https://threepipe.org/examples/#ssao-plugin/) &mdash;
  1679. [Source Code](./src/plugins/pipeline/SSAOPlugin.ts) &mdash;
  1680. [API Reference](https://threepipe.org/docs/classes/SSAOPlugin.html)
  1681. SSAO Plugin adds support for [Screen Space Ambient Occlusion](https://en.wikipedia.org/wiki/Screen_space_ambient_occlusion) to the viewer. Simply add the plugin to the viewer to use it.
  1682. This is done by adding a pre-render pass to the render manager which renders SSAO to a custom render target. SSAOPlugin depends on [GBufferPlugin](#gbufferplugin), and is automatically added if not already.
  1683. This render target is then used by all PhysicalMaterial(s) in the scene during the main RenderPass to get the AO data. SSAO can also be disabled from the UI of the material.
  1684. Note: Use with [ProgressivePlugin](#progressiveplugin) and `TemporalAAPlugin` for best results.
  1685. ```typescript
  1686. import {ThreeViewer, SSAOPlugin} from 'threepipe'
  1687. const viewer = new ThreeViewer({...})
  1688. const ssaoPlugin = viewer.addPluginSync(new SSAOPlugin())
  1689. // get the buffer.
  1690. console.log(ssaoPlugin.target);
  1691. // disable ssao for a material in the scene
  1692. material.userData.ssaoDisabled = true
  1693. ```
  1694. > In the target/buffer - The ssao data is in the `r` channel to remain compatible with ORM. `gba` contains the depth in vec3(xyz) format.
  1695. > Note that its `ssaoDisabled`, so setting it to `true` will disable the effect.
  1696. ## CanvasSnapshotPlugin
  1697. [//]: # (todo: image)
  1698. [Example](https://threepipe.org/examples/#canvas-snapshot-plugin/) &mdash;
  1699. [Source Code](./src/plugins/export/CanvasSnapshotPlugin.ts) &mdash;
  1700. [API Reference](https://threepipe.org/docs/classes/CanvasSnapshotPlugin.html)
  1701. Canvas Snapshot Plugin adds support for taking snapshots of the canvas and exporting them as images and data urls. It includes options to take snapshot of a region, mime type, quality render scale and scaling the output image. Check out the interface [CanvasSnapshotOptions](https://threepipe.org/docs/interfaces/CanvasSnapshotOptions.html) for more details.
  1702. ```typescript
  1703. import {ThreeViewer, CanvasSnapshotPlugin} from 'threepipe'
  1704. const viewer = new ThreeViewer({...})
  1705. const snapshotPlugin = viewer.addPluginSync(new CanvasSnapshotPlugin())
  1706. // download a snapshot.
  1707. await snapshotPlugin.downloadSnapshot('image.webp', { // all parameters are optional
  1708. scale: 1, // scale the final image
  1709. timeout: 0, // wait before taking the snapshot, in ms
  1710. quality: 0.9, // quality of the image (0-1) only for jpeg and webp
  1711. displayPixelRatio: 2, // render scale
  1712. mimeType: 'image/webp', // mime type of the image
  1713. waitForProgressive: true, // wait for progressive rendering to finish (ProgressivePlugin). true by default
  1714. rect: { // region to take snapshot. eg. crop center of the canvas
  1715. height: viewer.canvas.clientHeight / 2,
  1716. width: viewer.canvas.clientWidth / 2,
  1717. x: viewer.canvas.clientWidth / 4,
  1718. y: viewer.canvas.clientHeight / 4,
  1719. },
  1720. })
  1721. // get data url (string)
  1722. const dataUrl = await snapshotPlugin.getDataUrl({ // all parameters are optional
  1723. displayPixelRatio: 2, // render scale
  1724. mimeType: 'image/webp', // mime type of the image
  1725. })
  1726. // get File
  1727. const file = await snapshotPlugin.getFile('file.jpeg', { // all parameters are optional
  1728. mimeType: 'image/jpeg', // mime type of the image
  1729. })
  1730. ```
  1731. ## PickingPlugin
  1732. [//]: # (todo: image)
  1733. [Example](https://threepipe.org/examples/#picking-plugin/) &mdash;
  1734. [Source Code](./src/plugins/interaction/PickingPlugin.ts) &mdash;
  1735. [API Reference](https://threepipe.org/docs/classes/PickingPlugin.html)
  1736. Picking Plugin adds support for selecting and hovering over objects in the viewer with user interactions and selection widgets.
  1737. When the plugin is added to the viewer, it starts listening to the mouse move and click events over the canvas.
  1738. When an object is clicked, it is selected,
  1739. and if a UI plugin is added, the uiconfig for the selected object is populated in the interface.
  1740. The events `selectedObjectChanged`, `hoverObjectChanged`, and `hitObject` can be listened to on the plugin.
  1741. Picking plugin internally uses [ObjectPicker](https://threepipe.org/docs/classes/ObjectPicker.html),
  1742. check out the documentation or source code for more information.
  1743. ```typescript
  1744. import {ThreeViewer, PickingPlugin} from 'threepipe'
  1745. const viewer = new ThreeViewer({...})
  1746. const pickingPlugin = viewer.addPluginSync(new PickingPlugin())
  1747. // Hovering events are also supported, but since its computationally expensive for large scenes it is disabled by default.
  1748. pickingPlugin.hoverEnabled = true
  1749. pickingPlugin.addEventListener('hitObject', (e)=>{
  1750. // This is fired when the user clicks on the canvas.
  1751. // The selected object hasn't been changed yet, and we have the option to change it or disable selection at this point.
  1752. // e.intersects.selectedObject contains the object that the user clicked on.
  1753. console.log('Hit: ', e.intersects.selectedObject)
  1754. // It can be changed here
  1755. // e.intersects.selectedObject = e.intersects.selectedObject.parent // select the parent
  1756. // e.intersects.selectedObject = null // unselect
  1757. // Check other properties on the event like intersects, mouse position, normal etc.
  1758. console.log(e)
  1759. })
  1760. pickingPlugin.addEventListener('selectedObjectChanged', (e)=>{
  1761. // This is fired when the selected object is changed.
  1762. // e.object contains the new selected object. It can be null if nothing is selected.
  1763. console.log('Selected: ', e.object)
  1764. })
  1765. // Objects can be programmatically selected and unselected
  1766. // to select
  1767. pickingPlugin.setSelectedObject(object)
  1768. // get the selected object
  1769. console.log(pickingPlugin.getSelectedObject())
  1770. // to unselect
  1771. pickingPlugin.setSelectedObject(null)
  1772. // Select object with camera animation to the object
  1773. pickingPlugin.setSelectedObject(object, true)
  1774. pickingPlugin.addEventListener('hoverObjectChanged', (e)=>{
  1775. // This is fired when the hovered object is changed.
  1776. // e.object contains the new hovered object.
  1777. console.log('Hovering: ', e.object)
  1778. })
  1779. ```
  1780. ## FullScreenPlugin
  1781. [//]: # (todo: image)
  1782. [Example](https://threepipe.org/examples/#fullscreen-plugin/) &mdash;
  1783. [Source Code](./src/plugins/interaction/FullScreenPlugin.ts) &mdash;
  1784. [API Reference](https://threepipe.org/docs/classes/FullScreenPlugin.html)
  1785. A simple plugin that provides functions to enter, exit and toggle full screen mode and check if the viewer is in full screen mode. Either the canvas or the whole container can be set to full screen.
  1786. ```typescript
  1787. import {ThreeViewer, FullScreenPlugin} from 'threepipe'
  1788. const viewer = new ThreeViewer({...})
  1789. const fullscreen = viewer.addPluginSync(new FullScreenPlugin())
  1790. // enter full screen
  1791. await fullscreen.enter(viewer.container) // viewer.canvas is used if no element is passed
  1792. // exit full screen
  1793. await fullscreen.exit()
  1794. // toggle
  1795. await fullscreen.toggle(viewer.container)
  1796. // check if full screen
  1797. console.log(fullScreenPlugin.isFullScreen())
  1798. ```
  1799. ## AssetExporterPlugin
  1800. [//]: # (todo: image)
  1801. [Example](https://threepipe.org/examples/#asset-exporter-plugin/) &mdash;
  1802. [Source Code](./src/plugins/export/AssetExporterPlugin.ts) &mdash;
  1803. [API Reference](https://threepipe.org/docs/classes/AssetExporterPlugin.html)
  1804. Asset Exporter Plugin provides options and methods to export the scene, object GLB or Viewer Config.
  1805. All the functionality is available in the viewer(and `AssetExporter`) directly, this plugin only provides a ui-config and maintains state of the options which is saved as plugin configuration along with glb/vjson file
  1806. ```typescript
  1807. import {ThreeViewer, AssetExporterPlugin} from 'threepipe'
  1808. const viewer = new ThreeViewer({...})
  1809. const assetExporter = viewer.addPluginSync(new AssetExporterPlugin())
  1810. // check the existing options
  1811. console.log(assetExporter.exportOptions)
  1812. // enable/disable viewer config/json embedding in glb
  1813. assetExporter.viewerConfig = true
  1814. // set encryption
  1815. assetExporter.encrypt = true
  1816. assetExporter.encryptKey = 'superstrongpassword' // comment this to get prompted for a key during export.
  1817. // export scene as blob
  1818. const blob = assetExporter.exportScene()
  1819. // or export and download directly
  1820. assetExporter.downloadSceneGlb()
  1821. // export a specific object
  1822. const object = viewer.scene.getObjectByName('objectName')
  1823. const blob2 = assetExporter.exportObject(object, true) // true to also download
  1824. ```
  1825. Note: when downloading the model through the plugin, it uses viewer.export, which downloads the files by default, but uploads it to remote destinations when overloaded using `FileTransferPlugin`.
  1826. ## LoadingScreenPlugin
  1827. [//]: # (todo: image)
  1828. [Example](https://threepipe.org/examples/#loading-screen-plugin/) &mdash;
  1829. [Source Code](./src/plugins/interaction/LoadingScreenPlugin.ts) &mdash;
  1830. [API Reference](https://threepipe.org/docs/classes/LoadingScreenPlugin.html)
  1831. Loading Screen Plugin adds configurable overlay with a logo, loading text, spinner and the list of loading items. It also provides options to minimize and maximize the loading popup when there is no objects in the scene.
  1832. The overlay is automatically added to the viewer container and shown when any files are loading. Behaviour can be configured to change how its shown and hidden, and can even be triggered programmatically.
  1833. ```typescript
  1834. import {ThreeViewer, LoadingScreenPlugin} from 'threepipe'
  1835. const viewer = new ThreeViewer({...})
  1836. const loadingScreen = viewer.addPluginSync(new LoadingScreenPlugin())
  1837. loadingScreen.loadingTextHeader = 'Loading Helmet 3D Model'
  1838. loadingScreen.errorTextHeader = 'Error Loading Helmet 3D Model'
  1839. loadingScreen.showFileNames = true
  1840. loadingScreen.showProcessStates = true
  1841. loadingScreen.showProgress = true
  1842. loadingScreen.backgroundOpacity = 0.4 // 0-1
  1843. loadingScreen.backgroundBlur = 28 // px
  1844. ```
  1845. See also the base class [AAssetManagerProcessStatePlugin](https://threepipe.org/docs/classes/AAssetManagerProcessStatePlugin.html) to write a custom loading plugin.
  1846. ## InteractionPromptPlugin
  1847. [//]: # (todo: image)
  1848. [Example](https://threepipe.org/examples/#interaction-prompt-plugin/) &mdash;
  1849. [Source Code](./src/plugins/interaction/InteractionPromptPlugin.ts) &mdash;
  1850. [API Reference](https://threepipe.org/docs/classes/InteractionPromptPlugin.html)
  1851. Interaction Prompt Plugin adds a hand pointer icon over the canvas that moves to prompt the user to interact with the 3d scene. To use, simply add the plugin to the viewer.
  1852. The default pointer icon from [google/model-viewer](https://github.com/google/model-viewer) and can be configured with the `pointerIcon` property.
  1853. The pointer is automatically shown when some object is in the scene and the camera is not moving.
  1854. The animation starts after a delay and stops on user interaction. It then restarts after a delay after the user stops interacting
  1855. The plugin provides several options and functions to configure the automatic behaviour or trigger the animation manually.
  1856. ```typescript
  1857. import {ThreeViewer, InteractionPromptPlugin} from 'threepipe'
  1858. const viewer = new ThreeViewer({...})
  1859. const interactionPrompt = viewer.addPluginSync(new InteractionPromptPlugin())
  1860. // change duration
  1861. interactionPrompt.animationDuration = 3000
  1862. // change animation distance in pixels
  1863. interactionPrompt.animationDistance = 100
  1864. // disable auto start when the camera stops
  1865. interactionPrompt.autoStart = false
  1866. interactionPrompt.autoStop = false
  1867. // manually start and stop
  1868. interactionPrompt.startAnimation()
  1869. // ...
  1870. interactionPrompt.stopAnimation()
  1871. ```
  1872. Note - The pointer is automatically shown/hidden when animation is started/stopped.
  1873. ## TransformControlsPlugin
  1874. [//]: # (todo: image)
  1875. [Example](https://threepipe.org/examples/#transform-controls-plugin/) &mdash;
  1876. [Source Code](./src/plugins/interaction/TransformControlsPlugin.ts) &mdash;
  1877. [API Reference](https://threepipe.org/docs/classes/TransformControlsPlugin.html)
  1878. Transform Controls Plugin adds support for moving, rotating and scaling objects in the viewer with interactive widgets.
  1879. Under the hood, TransformControlsPlugin uses [TransformControls2](https://threepipe.org/docs/classes/TransformControls2) to provide the interactive controls, it is a extended version of three.js [TransformControls](https://threejs.org/docs/#examples/en/controls/TransformControls).
  1880. When the plugin is added to the viewer, it interfaces with the [PickingPlugin](#pickingplugin) and shows the control gizmos when an object is selected and hides them when the object is unselected.
  1881. If the `PickingPlugin` is not added to the viewer before the `TransformControlsPlugin`, it is added automatically with the plugin.
  1882. ```typescript
  1883. import {ThreeViewer, TransformControlsPlugin} from 'threepipe'
  1884. const viewer = new ThreeViewer({...})
  1885. const transfromControlsPlugin = viewer.addPluginSync(new TransformControlsPlugin())
  1886. // Get the underlying transform controls
  1887. console.log(transfromControlsPlugin.transformControls)
  1888. ```
  1889. ## ContactShadowGroundPlugin
  1890. [//]: # (todo: image)
  1891. [Example](https://threepipe.org/examples/#contact-shadow-ground-plugin/) &mdash;
  1892. [Source Code](./src/plugins/extras/ContactShadowGroundPlugin.ts) &mdash;
  1893. [API Reference](https://threepipe.org/docs/classes/ContactShadowGroundPlugin.html)
  1894. Contact Shadow Ground Plugin adds a ground plane with three.js contact shadows to the viewer scene.
  1895. The plane is added to the scene root at runtime and not saved with scene export. Instead the plugin settings are saved with the scene.
  1896. It inherits from the base class [BaseGroundPlugin](https://threepipe.org/docs/classes/BaseGroundPlugin.html) which provides generic ground plane functionality. Check the source code for more details. With the property `autoAdjustTransform`, the ground plane is automatically adjusted based on the bounding box of the scene.
  1897. ```typescript
  1898. import {ThreeViewer, ContactShadowGroundPlugin} from 'threepipe'
  1899. const viewer = new ThreeViewer({...})
  1900. viewer.addPluginSync(new ContactShadowGroundPlugin())
  1901. ```
  1902. ## GLTFAnimationPlugin
  1903. [//]: # (todo: image)
  1904. [Example](https://threepipe.org/examples/#gltf-animation-plugin/) &mdash;
  1905. [Source Code](./src/plugins/animation/GLTFAnimationPlugin.ts) &mdash;
  1906. [API Reference](https://threepipe.org/docs/classes/GLTFAnimationPlugin.html)
  1907. Manages playback of GLTF animations.
  1908. The GLTF animations can be created in any 3d software that supports GLTF export like Blender.
  1909. If animations from multiple files are loaded, they will be merged in a single root object and played together.
  1910. The time playback is managed automatically, but can be controlled manually by setting {@link autoIncrementTime} to false and using {@link setTime} to set the time.
  1911. This plugin is made for playing, pausing, stopping, all the animations at once, while it is possible to play individual animations, it is not recommended.
  1912. To play individual animations, with custom choreography, use the {@link GLTFAnimationPlugin.animations} property to get reference to the animation clips and actions. Create your own mixers and control the animation playback like in three.js
  1913. ## PopmotionPlugin
  1914. [//]: # (todo: image)
  1915. [Example](https://threepipe.org/examples/#popmotion-plugin/) &mdash;
  1916. [Source Code](./src/plugins/animation/PopmotionPlugin.ts) &mdash;
  1917. [API Reference](https://threepipe.org/docs/classes/PopmotionPlugin.html)
  1918. Provides animation/tweening capabilities to the viewer using the [popmotion.io](https://popmotion.io/) library.
  1919. Overrides the driver in popmotion to sync with the viewer and provide ways to store and stop animations.
  1920. ```typescript
  1921. import {PopmotionPlugin, ThreeViewer} from 'threepipe'
  1922. const viewer = new ThreeViewer({...})
  1923. const cube = viewer.scene.getObjectByName('cube');
  1924. const popmotion = viewer.addPluginSync(new PopmotionPlugin())
  1925. // Move the object cube 1 unit up.
  1926. const anim = popmotion.animateTarget(cube, 'position', {
  1927. to: cube.position.clone().add(new Vector3(0,1,0)),
  1928. duration: 500, // ms
  1929. onComplete: () => isMovedUp = true,
  1930. onStop: () => throw(new Error('Animation stopped')),
  1931. })
  1932. // Alternatively, set the property directly in onUpdate.
  1933. const anim1 = popmotion.animate({
  1934. from: cube.position.y,
  1935. to: cube.position.y + 1,
  1936. duration: 500, // ms
  1937. onUpdate: (v) => {
  1938. cube.position.setY(v)
  1939. cube.setDirty()
  1940. },
  1941. onComplete: () => isMovedUp = true,
  1942. onStop: () => throw(new Error('Animation stopped')),
  1943. onEnd: () => console.log('Animation ended'), // This runs after both onComplete and onStop
  1944. })
  1945. // await for animation. This promise will reject only if an exception is thrown in onStop or onComplete. onStop rejects if throwOnStop is true
  1946. await anim.promise.catch((e)=>{
  1947. console.log(e, 'animation stopped before completion')
  1948. });
  1949. // or stop the animation
  1950. // anim.stop()
  1951. // Animate the color
  1952. await popmotion.animateAsync({ // Also await for the animation.
  1953. from: '#' + cube.material.color.getHexString(),
  1954. to: '#' + new Color().setHSL(Math.random(), 1, 0.5).getHexString(),
  1955. duration: 1000, // 1s
  1956. onUpdate: (v) => {
  1957. cube.material.color.set(v)
  1958. cube.material.setDirty()
  1959. },
  1960. })
  1961. ```
  1962. Note: The animation is started when the animate or animateAsync function is called.
  1963. ## CameraViewPlugin
  1964. [//]: # (todo: image)
  1965. [Example](https://threepipe.org/examples/#camera-view-plugin/) &mdash;
  1966. [Source Code](./src/plugins/animation/CameraViewPlugin.ts) &mdash;
  1967. [API Reference](https://threepipe.org/docs/classes/CameraViewPlugin.html)
  1968. CameraViewPlugin adds support to save and load camera views, which can then be animated to.
  1969. It uses PopmotionPlugin internally to animate any camera to a saved view or to loop through all the saved views.
  1970. It also provides a UI to manage the views.
  1971. ```typescript
  1972. import {CameraViewPlugin, ThreeViewer, CameraView, Vector3, Quaternion, EasingFunctions, timeout} from 'threepipe'
  1973. const viewer = new ThreeViewer({...})
  1974. const cameraViewPlugin = viewer.addPluginSync(new CameraViewPlugin())
  1975. const intialView = cameraViewPlugin.getView()
  1976. // or = viewer.scene.mainCamera.getView()
  1977. // create a new view
  1978. const view = new CameraView(
  1979. 'My View', // name
  1980. new Vector3(0, 0, 10), // position
  1981. new Vector3(0, 0, 0), // target
  1982. new Quaternion(0, 0, 0, 1), // quaternion rotation
  1983. 1 // zoom
  1984. )
  1985. // or clone a view
  1986. const view2 = intialView.clone()
  1987. view2.position.add(new Vector3(0, 5, 0)) // move up 5 units
  1988. // animate the main camera to a view
  1989. await cameraViewPlugin.animateToView(
  1990. view,
  1991. 2000, // in ms, = 2sec
  1992. EasingFunctions.easeInOut,
  1993. ).catch(()=>console.log('Animation stopped'))
  1994. // stop any/all animations
  1995. cameraViewPlugin.stopAllAnimations()
  1996. // add views to the plugin
  1997. cameraViewPlugin.addView(view)
  1998. cameraViewPlugin.addView(view2)
  1999. cameraViewPlugin.addView(intialView)
  2000. cameraViewPlugin.addCurrentView() // adds the current view of the main camera
  2001. // loop through all the views once
  2002. cameraViewPlugin.animDuration = 2000 // default duration
  2003. cameraViewPlugin.animEase = EasingFunctions.easeInOutSine // default easing
  2004. await cameraViewPlugin.animateAllViews()
  2005. // loop through all the views forever
  2006. cameraViewPlugin.viewLooping = true
  2007. await timeout(10000) // wait for some time
  2008. // stop looping
  2009. cameraViewPlugin.viewLooping = false
  2010. ```
  2011. ## TransformAnimationPlugin
  2012. [//]: # (todo: image)
  2013. [Example](https://threepipe.org/examples/#transform-animation-plugin/) &mdash;
  2014. [Source Code](./src/plugins/animation/TransformAnimationPlugin.ts) &mdash;
  2015. [API Reference](https://threepipe.org/docs/classes/TransformAnimationPlugin.html)
  2016. TransformAnimationPlugin adds support to save and load transform(position, rotation, scale) states for objects in the scene, which can then be animated to.
  2017. It uses PopmotionPlugin internally to animate any object to a saved transform object.
  2018. The transformations are saved in the object userData, and can be created and interacted with from the plugin.
  2019. It also provides a UI to manage the states, this UI is added to the object's uiConfig and can be accessed using the object UI or PickingPlugin. Check the example for a working demo.
  2020. Sample Usage -
  2021. ```javascript
  2022. import {TransformAnimationPlugin, ThreeViewer, Vector3, Quaternion, EasingFunctions, timeout} from 'threepipe'
  2023. const viewer = new ThreeViewer({...})
  2024. const model = viewer.scene.getObjectByName('model')
  2025. const transformAnim = viewer.addPluginSync(new TransformAnimationPlugin())
  2026. // Save the current state of the model as a transform
  2027. transformAnim.addTransform(model, 'initial')
  2028. // Rotate/Move the model and save other transform states
  2029. // left
  2030. model.rotation.set(0, Math.PI / 2, 0)
  2031. model.setDirty?.()
  2032. transformAnim.addTransform(model, 'left')
  2033. // top
  2034. model.rotation.set(Math.PI / 2, 0, 0)
  2035. model.setDirty?.()
  2036. transformAnim.addTransform(model, 'top')
  2037. // up
  2038. model.position.set(0, 2, 0)
  2039. model.lookAt(viewer.scene.mainCamera.position)
  2040. model.setDirty?.()
  2041. transformAnim.addTransform(model, 'up')
  2042. // animate to a transform(from current position) in 1 sec
  2043. const anim = transformAnim.animateTransform(model, 'left', 1000)
  2044. // to stop the animation
  2045. // anim.stop()
  2046. // wait for the animation to finish
  2047. await anim.promise
  2048. // set a transform without animation
  2049. transformAnim.setTransform(model, 'top')
  2050. // await directly.
  2051. await transformAnim.animateToTransform(model, 'up', 1000)?.promise
  2052. ```
  2053. ## RenderTargetPreviewPlugin
  2054. [//]: # (todo: image)
  2055. [Example](https://threepipe.org/examples/#render-target-preview/) &mdash;
  2056. [Source Code](./src/plugins/ui/RenderTargetPreviewPlugin.ts) &mdash;
  2057. [API Reference](https://threepipe.org/docs/classes/RenderTargetPreviewPlugin.html)
  2058. RenderTargetPreviewPlugin is a useful development and debugging plugin that renders any registered render-target to the screen in small collapsable panels.
  2059. ```typescript
  2060. import {ThreeViewer, RenderTargetPreviewPlugin, NormalBufferPlugin} from 'threepipe'
  2061. const viewer = new ThreeViewer({...})
  2062. const normalPlugin = viewer.addPluginSync(new NormalBufferPlugin(HalfFloatType))
  2063. const previewPlugin = viewer.addPluginSync(new RenderTargetPreviewPlugin())
  2064. // Show the normal buffer in a panel
  2065. previewPlugin.addTarget(()=>normalPlugin.target, 'normal', false, false)
  2066. ```
  2067. ## GeometryUVPreviewPlugin
  2068. [//]: # (todo: image)
  2069. [Example](https://threepipe.org/examples/#geometry-uv-preview/) &mdash;
  2070. [Source Code](./src/plugins/ui/GeometryUVPreviewPlugin.ts) &mdash;
  2071. [API Reference](https://threepipe.org/docs/classes/GeometryUVPreviewPlugin.html)
  2072. GeometryUVPreviewPlugin is a useful development and debugging plugin
  2073. that adds a panel to the viewer to show the UVs of a geometry.
  2074. ```typescript
  2075. import {ThreeViewer, GeometryUVPreviewPlugin, SphereGeometry} from 'threepipe'
  2076. const viewer = new ThreeViewer({...})
  2077. const previewPlugin = viewer.addPluginSync(new GeometryUVPreviewPlugin())
  2078. const geometry = new SphereGeometry(1, 32, 32)
  2079. // Show the normal buffer in a panel
  2080. previewPlugin.addGeometry(geometry, 'sphere')
  2081. ```
  2082. ## FrameFadePlugin
  2083. [//]: # (todo: image)
  2084. [Example](https://threepipe.org/examples/#frame-fade-plugin/) &mdash;
  2085. [Source Code](./src/plugins/pipeline/FrameFadePlugin.ts) &mdash;
  2086. [API Reference](https://threepipe.org/docs/classes/FrameFadePlugin.html)
  2087. FrameFadePlugin adds a post-render pass to the render manager and blends the last frame with the current frame over time. This is useful for creating smooth transitions between frames for example when changing the camera position, material, object properties, etc to avoid a sudden jump.
  2088. ```typescript
  2089. import {ThreeViewer, FrameFadePlugin} from 'threepipe'
  2090. const viewer = new ThreeViewer({...})
  2091. const fadePlugin = viewer.addPluginSync(new FrameFadePlugin())
  2092. // Make some changes in the scene (any visual change that needs to be faded)
  2093. // Start transition and wait for it to finish
  2094. await fadePlugin.startTransition(400) // duration in ms
  2095. ```
  2096. To stop a transition, call `fadePlugin.stopTransition()`. This will immediately set the current frame to the last frame and stop the transition. The transition is also automatically stopped when the camera is moved or some pointer event occurs on the canvas.
  2097. The plugin automatically tracks `setDirty()` function calls in objects, materials and the scene. It can be triggerred by calling `setDirty` on any material or object in the scene. Check the [example](https://threepipe.org/examples/#frame-fade-plugin/) for a demo. This can be disabled by options in the plugin.
  2098. ## VignettePlugin
  2099. [//]: # (todo: image)
  2100. [Example](https://threepipe.org/examples/#vignette-plugin/) &mdash;
  2101. [Source Code](./src/plugins/postprocessing/VignettePlugin.ts) &mdash;
  2102. [API Reference](https://threepipe.org/docs/classes/VignettePlugin.html)
  2103. VignettePlugin adds a post-processing material extension to the ScreenPass in render manager
  2104. that applies a vignette effect to the final render. The parameters `power` and `color` can be changed to customize the effect.
  2105. ```typescript
  2106. import {ThreeViewer, VignettePlugin} from 'threepipe'
  2107. const viewer = new ThreeViewer({...})
  2108. const vignettePlugin = viewer.addPluginSync(VignettePlugin)
  2109. // Change the vignette color
  2110. vignettePlugin.power = 1
  2111. vignettePlugin.color = new Color(0.5, 0, 0)
  2112. // or
  2113. // vignettePlugin.color.set('#ff0000'); vignettePlugin.setDirty() // Call setDirty to tell the plugin that color has changed
  2114. ```
  2115. ## ChromaticAberrationPlugin
  2116. [//]: # (todo: image)
  2117. [Example](https://threepipe.org/examples/#chromatic-aberration-plugin/) &mdash;
  2118. [Source Code](./src/plugins/postprocessing/ChromaticAberrationPlugin.ts) &mdash;
  2119. [API Reference](https://threepipe.org/docs/classes/ChromaticAberrationPlugin.html)
  2120. ChromaticAberrationPlugin adds a post-processing material extension to the ScreenPass in render manager
  2121. that applies a chromatic-aberration effect to the final render. The parameter `intensity` can be changed to customize the effect.
  2122. ```typescript
  2123. import {ThreeViewer, ChromaticAberrationPlugin} from 'threepipe'
  2124. const viewer = new ThreeViewer({...})
  2125. const chromaticAberrationPlugin = viewer.addPluginSync(ChromaticAberrationPlugin)
  2126. // Change the chromaticAberration color
  2127. chromaticAberrationPlugin.intensity = 0.5
  2128. ```
  2129. ## FilmicGrainPlugin
  2130. [//]: # (todo: image)
  2131. [Example](https://threepipe.org/examples/#filmic-grain-plugin/) &mdash;
  2132. [Source Code](./src/plugins/postprocessing/FilmicGrainPlugin.ts) &mdash;
  2133. [API Reference](https://threepipe.org/docs/classes/FilmicGrainPlugin.html)
  2134. FilmicGrainPlugin adds a post-processing material extension to the ScreenPass in render manager
  2135. that applies a filmic-grain effect to the final render. The parameters `power` and `color` can be changed to customize the effect.
  2136. ```typescript
  2137. import {ThreeViewer, FilmicGrainPlugin} from 'threepipe'
  2138. const viewer = new ThreeViewer({...})
  2139. const filmicGrainPlugin = viewer.addPluginSync(FilmicGrainPlugin)
  2140. // Change the filmicGrain color
  2141. filmicGrainPlugin.intensity = 10
  2142. filmicGrainPlugin.multiply = false
  2143. ```
  2144. ## NoiseBumpMaterialPlugin
  2145. [//]: # (todo: image)
  2146. [Example](https://threepipe.org/examples/#noise-bump-material-plugin/) &mdash;
  2147. [Source Code](./src/plugins/material/NoiseBumpMaterialPlugin.ts) &mdash;
  2148. [API Reference](https://threepipe.org/docs/classes/NoiseBumpMaterialPlugin.html)
  2149. NoiseBumpMaterialPlugin adds a material extension to PhysicalMaterial to add support for sparkle bump / noise bump by creating procedural bump map from noise to simulate sparkle flakes.
  2150. It uses voronoise function from blender along with several additions to generate the noise for the generation.
  2151. It also adds a UI to the material to edit the settings.
  2152. It uses `WEBGI_materials_noise_bump` glTF extension to save the settings in glTF/glb files.
  2153. ```typescript
  2154. import {ThreeViewer, NoiseBumpMaterialPlugin} from 'threepipe'
  2155. const viewer = new ThreeViewer({...})
  2156. const noiseBump = viewer.addPluginSync(NoiseBumpMaterialPlugin)
  2157. // Add noise bump to a material
  2158. NoiseBumpMaterialPlugin.AddNoiseBumpMaterial(material, {
  2159. flakeScale: 300,
  2160. })
  2161. // Change properties with code or use the UI
  2162. material.userData._noiseBumpMat!.bumpNoiseParams = [1, 1]
  2163. material.setDirty()
  2164. // Disable
  2165. material.userData._noiseBumpMat!.hasBump = false
  2166. material.setDirty()
  2167. ```
  2168. ## CustomBumpMapPlugin
  2169. [//]: # (todo: image)
  2170. [Example](https://threepipe.org/examples/#custom-bump-map-plugin/) &mdash;
  2171. [Source Code](./src/plugins/material/CustomBumpMapPlugin.ts) &mdash;
  2172. [API Reference](https://threepipe.org/docs/classes/CustomBumpMapPlugin.html)
  2173. CustomBumpMapPlugin adds a material extension to PhysicalMaterial to support custom bump maps.
  2174. A Custom bump map is similar to the built-in bump map, but allows using an extra bump map and scale to give a combined effect.
  2175. This plugin also has support for bicubic filtering of the custom bump map and is enabled by default.
  2176. It also adds a UI to the material to edit the settings.
  2177. It uses `WEBGI_materials_custom_bump_map` glTF extension to save the settings in glTF/glb files.
  2178. ```typescript
  2179. import {ThreeViewer, CustomBumpMapPlugin} from 'threepipe'
  2180. const viewer = new ThreeViewer({...})
  2181. const customBump = viewer.addPluginSync(CustomBumpMapPlugin)
  2182. // Add noise bump to a material
  2183. customBump.enableCustomBump(material, bumpMap, 0.2)
  2184. // Change properties with code or use the UI
  2185. material.userData._customBumpMat = texture
  2186. material.setDirty()
  2187. // Disable
  2188. material.userData._hasCustomBump = false
  2189. // or
  2190. material.userData._customBumpMat = null
  2191. material.setDirty()
  2192. ```
  2193. ## ClearcoatTintPlugin
  2194. [//]: # (todo: image)
  2195. [Example](https://threepipe.org/examples/#clearcoat-tint-plugin/) &mdash;
  2196. [Source Code](./src/plugins/material/ClearcoatTintPlugin.ts) &mdash;
  2197. [API Reference](https://threepipe.org/docs/classes/ClearcoatTintPlugin.html)
  2198. ClearcoatTintPlugin adds a material extension to PhysicalMaterial which adds tint and thickness to the built-in clearcoat properties.
  2199. It also adds a UI to the material to edit the settings.
  2200. It uses `WEBGI_materials_clearcoat_tint` glTF extension to save the settings in glTF/glb files.
  2201. ```typescript
  2202. import {ThreeViewer, ClearcoatTintPlugin} from 'threepipe'
  2203. const viewer = new ThreeViewer({...})
  2204. const clearcoatTint = viewer.addPluginSync(ClearcoatTintPlugin)
  2205. material.clearcoat = 1
  2206. // add initial properties
  2207. ClearcoatTintPlugin.AddClearcoatTint(material, {
  2208. tintColor: '#ff0000',
  2209. thickness: 1,
  2210. })
  2211. // Change properties with code or use the UI
  2212. material.userData._clearcoatTint!.tintColor = '#ff0000'
  2213. material.setDirty()
  2214. // Disable
  2215. material.userData._clearcoatTint.enableTint = false
  2216. material.setDirty()
  2217. ```
  2218. ## FragmentClippingExtensionPlugin
  2219. [//]: # (todo: image)
  2220. [Example](https://threepipe.org/examples/#fragment-clipping-extension-plugin/) &mdash;
  2221. [Source Code](./src/plugins/material/FragmentClippingExtensionPlugin.ts) &mdash;
  2222. [API Reference](https://threepipe.org/docs/classes/FragmentClippingExtensionPlugin.html)
  2223. FragmentClippingExtensionPlugin adds a material extension to PhysicalMaterial to add support for fragment clipping.
  2224. Fragment clipping allows to clip fragments of the material in screen space or world space based on a circle, rectangle, plane, sphere, etc.
  2225. It uses fixed SDFs with params defined by the user for clipping.
  2226. It also adds a UI to the material to edit the settings.
  2227. It uses `WEBGI_materials_fragment_clipping_extension` glTF extension to save the settings in glTF/glb files.
  2228. ```typescript
  2229. import {ThreeViewer, FragmentClippingExtensionPlugin} from 'threepipe'
  2230. const viewer = new ThreeViewer({...})
  2231. const fragmentClipping = viewer.addPluginSync(FragmentClippingExtensionPlugin)
  2232. // add initial properties
  2233. FragmentClippingExtensionPlugin.AddFragmentClipping(material, {
  2234. clipPosition: new Vector4(0.5, 0.5, 0, 0),
  2235. clipParams: new Vector4(0.1, 0.05, 0, 1),
  2236. })
  2237. // Change properties with code or use the UI
  2238. material.userData._fragmentClipping!.clipPosition.set(0, 0, 0, 0)
  2239. material.setDirty()
  2240. // Disable
  2241. material.userData._clearcoatTint.clipEnabled = false
  2242. material.setDirty()
  2243. ```
  2244. ## ParallaxMappingPlugin
  2245. [//]: # (todo: image)
  2246. [Example](https://threepipe.org/examples/#parallax-mapping-plugin/) &mdash;
  2247. [Source Code](./src/plugins/material/ParallaxMappingPlugin.ts) &mdash;
  2248. [API Reference](https://threepipe.org/docs/classes/ParallaxMappingPlugin.html)
  2249. `ParallaxMappingPlugin` adds a material extension to PhysicalMaterial to add support for [parallax relief mapping](https://en.wikipedia.org/wiki/Relief_mapping_(computer_graphics)). The idea is to walk along a ray that has entered the bumpmap's volume, finding the intersection point of the ray with the bumpmap. [Steep parallax mapping](https://en.wikipedia.org/wiki/Parallax_mapping) and [parallax occlusion mapping](https://en.wikipedia.org/wiki/Parallax_occlusion_mapping) are other common names for these techniques.
  2250. To use the plugin, add the plugin to the viewer and use the `bumpMap` in `PhysicalMaterial` normally. The max height is determined by the `bumpScale` in the material. This is assumed to be in world scale.
  2251. ```typescript
  2252. import {ThreeViewer, ParallaxMappingPlugin} from 'threepipe'
  2253. const viewer = new ThreeViewer({...})
  2254. const parallaxMapping = viewer.addPluginSync(ParallaxMappingPlugin)
  2255. // load or create an object
  2256. // set the bump map
  2257. object.material.bumpMap = await viewer.load<ITexture>(bumps[0]) || null
  2258. // set the bump scale
  2259. object.material.bumpScale = 0.1
  2260. // setDirty to notify the viewer to update.
  2261. object.material.setDirty()
  2262. ```
  2263. ### References and related links:
  2264. - WebGL implementation by Rabbid76 - [github.com/Rabbid76/graphics-snippets](https://github.com/Rabbid76/graphics-snippets/blob/master/html/technique/parallax_005_parallax_relief_mapping_derivative_tbn.html)
  2265. - Lesson on Parallax Occlusion Mapping in GLSL - [http://sunandblackcat.com/tipFullView.php?topicid=28](https://web.archive.org/web/20190128023901/http://sunandblackcat.com/tipFullView.php?topicid=28)
  2266. - Learn OpenGL - https://learnopengl.com/Advanced-Lighting/Parallax-Mapping
  2267. ## HDRiGroundPlugin
  2268. [//]: # (todo: image)
  2269. [Example](https://threepipe.org/examples/#hdri-ground-plugin/) &mdash;
  2270. [Source Code](./src/plugins/extras/HDRiGroundPlugin.ts) &mdash;
  2271. [API Reference](https://threepipe.org/docs/classes/HDRiGroundPlugin.html)
  2272. HDRiGroundPlugin patches the background shader in the renderer to add support for ground projected environment map/skybox. Works simply by setting the background same as the environemnt and enabling the plugin.
  2273. The world radius, tripod height, and origin position(center offset) can be set in the plugin.
  2274. The plugin is disabled by default when added. Set `.enabled` to enable it or pass `true` in the constructor.
  2275. If the background is not the same as the environment when enabled, the user will be prompted for this, unless `promptOnBackgroundMismatch` is set to `false` in the plugin.
  2276. ```typescript
  2277. import {ThreeViewer, HDRiGrounPlugin} from 'threepipe'
  2278. const viewer = new ThreeViewer({...})
  2279. const hdriGround = viewer.addPluginSync(new HDRiGrounPlugin())
  2280. // Load an hdr environment map
  2281. await viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr')
  2282. // set background to environment
  2283. viewer.scene.background = 'environment'
  2284. // or
  2285. // viewer.scene.background = viewer.scene.environemnt
  2286. // enable the plugin
  2287. hdriGround.enabled = true
  2288. ```
  2289. Check the [example](https://threepipe.org/examples/#hdri-ground-plugin/) for a demo.
  2290. ## VirtualCamerasPlugin
  2291. [//]: # (todo: image)
  2292. [Example](https://threepipe.org/examples/#virtual-cameras-plugin/) &mdash;
  2293. [Source Code](./src/plugins/rendering/VirtualCamerasPlugin.ts) &mdash;
  2294. [API Reference](https://threepipe.org/docs/classes/VirtualCamerasPlugin.html)
  2295. VirtualCamerasPlugin adds support for rendering to multiple virtual cameras in the viewer. These cameras are rendered in preRender callback just before the main camera is rendered. The virtual cameras can be added to the plugin and removed from it.
  2296. The feed to the virtual camera is rendered to a Render Target texture which can be accessed and re-rendered in the scene or used in other plugins.
  2297. ```typescript
  2298. import {ThreeViewer, VirtualCamerasPlugin} from 'threepipe'
  2299. const viewer = new ThreeViewer({...})
  2300. const virtualCameras = viewer.addPluginSync(new VirtualCamerasPlugin())
  2301. const camera = new PerspectiveCamera2('orbit', viewer.canvas, false, 45, 1)
  2302. camera.name = name
  2303. camera.position.set(0, 5, 0)
  2304. camera.target.set(0, 0.25, 0)
  2305. camera.userData.autoLookAtTarget = true // automatically look at the target (in setDirty)
  2306. camera.setDirty()
  2307. camera.addEventListener('update', ()=>{
  2308. viewer.setDirty() // if the camera is not added to the scene it wont update automatically when camera.setDirty is called(like from the UI)
  2309. })
  2310. const vCam = virtualCameras.addCamera(camera)
  2311. console.log(vCam.target) // target is a WebGLRenderTarget/IRenderTarget
  2312. ```
  2313. Check the [virtual camera](https://threepipe.org/examples/#virtual-camera/) example for using the texture in the scene.
  2314. ## EditorViewWidgetPlugin
  2315. [//]: # (todo: image)
  2316. [Example](https://threepipe.org/examples/#editor-view-widget-plugin/) &mdash;
  2317. [Source Code](./src/plugins/interaction/EditorViewWidgetPlugin.ts) &mdash;
  2318. [API Reference](https://threepipe.org/docs/classes/EditorViewWidgetPlugin.html)
  2319. EditorViewWidgetPlugin adds a ViewHelper in the parent of the viewer canvas to show the current camera view and allow the user to change the camera view to one of the primary world axes.
  2320. Simply add the plugin to the viewer to see the widget.
  2321. ```typescript
  2322. import {ThreeViewer, EditorViewWidgetPlugin} from 'threepipe'
  2323. const viewer = new ThreeViewer({...})
  2324. const plugin = viewer.addPluginSync(new EditorViewWidgetPlugin())
  2325. // to hide the widget
  2326. plugin.enabled = false
  2327. ```
  2328. ## Object3DWidgetsPlugin
  2329. [//]: # (todo: image)
  2330. [Example](https://threepipe.org/examples/#object3d-widgets-plugin/) &mdash;
  2331. [Source Code](./src/plugins/extras/Object3DWidgetsPlugin.ts) &mdash;
  2332. [API Reference](https://threepipe.org/docs/classes/Object3DWidgetsPlugin.html)
  2333. Object3DWidgetsPlugin adds support for light and camera helpers/gizmos in the viewer.
  2334. A helper is automatically created when any supported light or camera is added to the scene.
  2335. Simply add the plugin to the viewer to see the widget.
  2336. Support for additional types of helpers can be added dynamically or by other plugins by pushing a helper constructor to the `Object3DWidgetsPlugin.helpers` array, and calling `Object3DWidgetsPlugin.refresh()`.
  2337. The helper class prototype should implement the `IObject3DHelper` interface. Check `DirectionalLightHelper2` for an example.
  2338. ```typescript
  2339. import {ThreeViewer, Object3DWidgetsPlugin, Object3DGeneratorPlugin} from 'threepipe'
  2340. const viewer = new ThreeViewer({...})
  2341. // Add the plugin to add support
  2342. const plugin = viewer.addPluginSync(new Object3DWidgetsPlugin())
  2343. // Add some lights or cameras to the scene. (This can be done before adding the plugin as well)
  2344. // Using Object3DGeneratorPlugin to create a camera and add it to the scene.
  2345. const generator = viewer.getOrAddPluginSync(Object3DGeneratorPlugin)
  2346. generator.generate('camera-perspective', {
  2347. position: new Vector3(5, 5, 0),
  2348. name: 'My Camera'
  2349. })
  2350. // to hide the widgets
  2351. plugin.enabled = false
  2352. // to add support for a custom helper
  2353. plugin.helpers.push(MyCustomHelper)
  2354. plugin.refresh()
  2355. ```
  2356. ## Object3DGeneratorPlugin
  2357. [//]: # (todo: image)
  2358. [Example](https://threepipe.org/examples/#object3d-generator-plugin/) &mdash;
  2359. [Source Code](./src/plugins/extras/Object3DGeneratorPlugin.ts) &mdash;
  2360. [API Reference](https://threepipe.org/docs/classes/Object3DGeneratorPlugin.html)
  2361. Object3DGeneratorPlugin adds support for creating different types of lights and camera objects in the viewer.
  2362. Call the `generate` method with any type to generate a type of object(like lights, cameras, mesh etc).
  2363. Support for the following types of generators is included in the plugin:
  2364. * camera-perspective - Creates instance of `PerspectiveCamera2`
  2365. * light-directional - Creates instance of `DirectionalLight2`
  2366. * light-ambient - Creates instance of `AmbientLight2`
  2367. * light-point - Creates instance of `PointLight2`
  2368. * light-spot - Creates instance of `SpotLight2`
  2369. * light-hemisphere - Creates instance of `HemisphereLight2`
  2370. * light-rect-area - Creates instance of `RectAreaLight2`
  2371. Additional types of generators can be added dynamically or by other plugins by adding a custom generator function to the `Object3DGeneratorPlugin.generators` object. This is done by [GeometryGeneratorPlugin](#threepipeplugin-geometry-generator) to add various type of primitive objects like plane, sphere, etc
  2372. A custom generator can take in any kind object as parameters and should return an `IObject3D`.
  2373. Sample Usage
  2374. ```typescript
  2375. import {ThreeViewer, Object3DWidgetsPlugin, Object3DGeneratorPlugin, Mesh2} from 'threepipe'
  2376. const viewer = new ThreeViewer({...})
  2377. const generator = viewer.addPluginSync(Object3DGeneratorPlugin)
  2378. generator.generate('camera-perspective', {
  2379. position: new Vector3(5, 5, 0),
  2380. name: 'My Camera'
  2381. })
  2382. const light = generator.generate('light-spot', {
  2383. position: new Vector3(5, 0, 0),
  2384. })
  2385. // to add support for a custom helper
  2386. plugin.generators['custom-object'] = (params)=>{
  2387. const object = new Mesh2(new PlaneGeometry(1,1), new PhysicalMaterial())
  2388. object.name = params.name ?? 'Custom Mesh'
  2389. if(params.position) object.position.copy(params.position)
  2390. return object
  2391. }
  2392. const obj = generator.generate('custom-object', {
  2393. position: new Vector3(5, 0, 0),
  2394. })
  2395. // Add Object3DWidgetsPlugin to see the added lights and cameras.
  2396. viewer.addPluginSync(new Object3DWidgetsPlugin())
  2397. ```
  2398. Check the [example](https://threepipe.org/examples/#object3d-generator-plugin/) for the UI.
  2399. ## DeviceOrientationControlsPlugin
  2400. [//]: # (todo: image)
  2401. [Example](https://threepipe.org/examples/#device-orientation-controls-plugin/) &mdash;
  2402. [Source Code](./src/plugins/interaction/DeviceOrientationControlsPlugin.ts) &mdash;
  2403. [API Reference](https://threepipe.org/docs/classes/DeviceOrientationControlsPlugin.html)
  2404. DeviceOrientationControlsPlugin enables controlling the main camera rotation in the scene with device orientation. This only works on devices which have a gyroscope(but can also be emulated in devtools in chrome).
  2405. After the plugin is added, it adds support for setting `deviceOrientation` as the key in `scene.mainCamera.controlMode`.
  2406. When the controls is started (for the first time), the current camera rotation is and the device orientation is saved and used as reference. To reset the saved device orientation, call `resetView` in the controls.
  2407. Sample Usage
  2408. ```typescript
  2409. import {ThreeViewer, DeviceOrientationControlsPlugin, Mesh2} from 'threepipe'
  2410. const viewer = new ThreeViewer({...})
  2411. viewer.addPluginSync(DeviceOrientationControlsPlugin)
  2412. // after some user action
  2413. viewer.scene.mainCamera.controlsMode = 'deviceOrientation'
  2414. // to reset the saved device orientation
  2415. viewer.scene.mainCamera.controls.resetView()
  2416. // switch back to default orbit controls
  2417. viewer.scene.mainCamera.controlsMode = 'orbit'
  2418. ```
  2419. ## PointerLockControlsPlugin
  2420. [//]: # (todo: image)
  2421. [Example](https://threepipe.org/examples/#pointer-lock-controls-plugin/) &mdash;
  2422. [Source Code](./src/plugins/interaction/PointerLockControlsPlugin.ts) &mdash;
  2423. [API Reference](https://threepipe.org/docs/classes/PointerLockControlsPlugin.html)
  2424. PointerLockControlsPlugin adds support for using PointerLockControls from three.js. It works similar to controls in first person shooter, captures the mouse pointer and uses it to look around with the camera.
  2425. After the plugin is added, it adds support for setting `pointerLock` as the key in `scene.mainCamera.controlMode`.
  2426. Sample Usage
  2427. ```typescript
  2428. import {ThreeViewer, PointerLockControlsPlugin, Mesh2} from 'threepipe'
  2429. const viewer = new ThreeViewer({...})
  2430. viewer.addPluginSync(PointerLockControlsPlugin)
  2431. // after some user action
  2432. viewer.scene.mainCamera.controlsMode = 'pointerLock'
  2433. // listen to lock/unlock events
  2434. viewer.scene.mainCamera.controls?.addEventListener('lock', ()=> console.log('pointer locked'))
  2435. viewer.scene.mainCamera.controls?.addEventListener('unlock', ()=> console.log('pointer unlocked'))
  2436. // switch back to default orbit controls
  2437. viewer.scene.mainCamera.controlsMode = 'orbit'
  2438. ```
  2439. ## ThreeFirstPersonControlsPlugin
  2440. [//]: # (todo: image)
  2441. [Example](https://threepipe.org/examples/#three-first-person-controls-plugin/) &mdash;
  2442. [Source Code](./src/plugins/interaction/ThreeFirstPersonControlsPlugin.ts) &mdash;
  2443. [API Reference](https://threepipe.org/docs/classes/ThreeFirstPersonControlsPlugin.html)
  2444. ThreeFirstPersonControlsPlugin adds support for using FirstPersonControls from three.js. It works similar to idle look around in first person games, it does not captures the mouse pointer.
  2445. After the plugin is added, it adds support for setting `threeFirstPerson` as the key in `scene.mainCamera.controlMode`.
  2446. Sample Usage
  2447. ```typescript
  2448. import {ThreeViewer, ThreeFirstPersonControlsPlugin, Mesh2} from 'threepipe'
  2449. const viewer = new ThreeViewer({...})
  2450. viewer.addPluginSync(ThreeFirstPersonControlsPlugin)
  2451. // after some user action
  2452. viewer.scene.mainCamera.controlsMode = 'threeFirstPerson'
  2453. // switch back to default orbit controls
  2454. viewer.scene.mainCamera.controlsMode = 'orbit'
  2455. ```
  2456. ## GLTFKHRMaterialVariantsPlugin
  2457. [//]: # (todo: image)
  2458. [Example](https://threepipe.org/examples/#gltf-khr-material-variants-plugin/) &mdash;
  2459. [Source Code](./src/plugins/extras/GLTFKHRMaterialVariantsPlugin.ts) &mdash;
  2460. [API Reference](https://threepipe.org/docs/classes/GLTFKHRMaterialVariantsPlugin.html)
  2461. GLTFKHRMaterialVariantsPlugin adds support for importing and exporting glTF models with the `KHR_materials_variants` extension to load the model with different material variants/combinations. It also provides API and UI to change the current material variant.
  2462. The plugin automatically adds support for the extension when added to the viewer.
  2463. The materials are stored in `object.userData._variantMaterials` and are automatically loaded and saved when using the `GLTFLoader`.
  2464. Sample Usage
  2465. ```typescript
  2466. import {ThreeViewer, GLTFKHRMaterialVariantsPlugin, Mesh2} from 'threepipe'
  2467. const viewer = new ThreeViewer({...})
  2468. const variantsPlugin = viewer.addPluginSync(GLTFKHRMaterialVariantsPlugin)
  2469. // load some model
  2470. await viewer.load(model_url)
  2471. // list of all variants in the model (names and objects)
  2472. console.log(variantsPlugin.variants)
  2473. // change the selected variant
  2474. variantsPlugin.selectedVariant = 'beach'
  2475. ```
  2476. ### Links
  2477. - https://www.khronos.org/blog/blender-gltf-i-o-support-for-gltf-pbr-material-extensions
  2478. - https://www.khronos.org/blog/streamlining-3d-commerce-with-material-variant-support-in-gltf-assets
  2479. - https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_variants/README.md
  2480. ## Rhino3dmLoadPlugin
  2481. [Example](https://threepipe.org/examples/#rhino3dm-load/) &mdash;
  2482. [Source Code](./src/plugins/import/Rhino3dmLoadPlugin.ts) &mdash;
  2483. [API Reference](https://threepipe.org/docs/classes/Rhino3dmLoadPlugin.html)
  2484. Adds support for loading .3dm files generated by [Rhino 3D](https://www.rhino3d.com/). This plugin includes some changes with how 3dm files are loaded in three.js. The changes are around loading layer and primitive properties when set as reference in the 3dm files.
  2485. It also adds some helpful options to process the model after load.
  2486. ```typescript
  2487. import {Rhino3dmLoadPlugin} from 'threepipe'
  2488. const rhino3dmPlugin = viewer.addPluginSync(new Rhino3dmLoadPlugin())
  2489. rhino3dmPlugin.importMaterials = true // import materials source from 3dm file
  2490. rhino3dmPlugin.forceLayerMaterials = true // force material source to be layer in 3dm file.
  2491. rhino3dmPlugin.hideLineMesh = true // hide all lines and points in the model.
  2492. rhino3dmPlugin.replaceWithInstancedMesh = true // replace meshes with the same parent, geometry and material with a single instance mesh.
  2493. const mesh = await viewer.load('file.3dm')
  2494. ```
  2495. ## PLYLoadPlugin
  2496. [Example](https://threepipe.org/examples/#ply-load/) &mdash;
  2497. [Source Code](./src/plugins/import/PLYLoadPlugin.ts) &mdash;
  2498. [API Reference](https://threepipe.org/docs/classes/PLYLoadPlugin.html)
  2499. Adds support for loading .ply ([Polygon file format](https://en.wikipedia.org/wiki/PLY_(file_format))) files.
  2500. ```typescript
  2501. import {PLYLoadPlugin} from 'threepipe'
  2502. viewer.addPluginSync(new PLYLoadPlugin())
  2503. const mesh = await viewer.load('file.ply')
  2504. ```
  2505. ## USDZLoadPlugin
  2506. [Example](https://threepipe.org/examples/#usdz-load/) &mdash;
  2507. [Source Code](./src/plugins/import/USDZLoadPlugin.ts) &mdash;
  2508. [API Reference](https://threepipe.org/docs/classes/USDZLoadPlugin.html)
  2509. Adds support for loading .usdz and .usda ([Universal Scene Description](https://graphics.pixar.com/usd/docs/index.html)) files.
  2510. ```typescript
  2511. import {USDZLoadPlugin} from 'threepipe'
  2512. viewer.addPluginSync(new USDZLoadPlugin())
  2513. const mesh = await viewer.load('file.usdz')
  2514. const mesh2 = await viewer.load('file.usda')
  2515. ```
  2516. ## STLLoadPlugin
  2517. [Example](https://threepipe.org/examples/#stl-load/) &mdash;
  2518. [Source Code](./src/plugins/import/STLLoadPlugin.ts) &mdash;
  2519. [API Reference](https://threepipe.org/docs/classes/STLLoadPlugin.html)
  2520. Adds support for loading .stl ([Stereolithography](https://en.wikipedia.org/wiki/STL_(file_format))) files.
  2521. ```typescript
  2522. import {STLLoadPlugin} from 'threepipe'
  2523. viewer.addPluginSync(new STLLoadPlugin())
  2524. const mesh = await viewer.load('file.stl')
  2525. ```
  2526. ## KTX2LoadPlugin
  2527. [Example](https://threepipe.org/examples/#ktx2-load/) &mdash;
  2528. [Source Code](./src/plugins/import/KTX2LoadPlugin.ts) &mdash;
  2529. [API Reference](https://threepipe.org/docs/classes/KTX2LoadPlugin.html)
  2530. Adds support for loading .ktx2 ([Khronos Texture](https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/) files with asset manager and embedded in glTF files.
  2531. KTX2LoadPlugin also adds support for exporting loaded .ktx2 files in glTF files with the [KHR_texture_basisu](https://www.khronos.org/registry/KHR/textures/2.0-extensions/KHR_texture_basisu/) extension.
  2532. ```typescript
  2533. import {KTX2LoadPlugin} from 'threepipe'
  2534. viewer.addPluginSync(new KTX2LoadPlugin())
  2535. const texture = await viewer.load('file.ktx2')
  2536. ```
  2537. ## KTXLoadPlugin
  2538. [Example](https://threepipe.org/examples/#ktx-load/) &mdash;
  2539. [Source Code](./src/plugins/import/KTXLoadPlugin.ts) &mdash;
  2540. [API Reference](https://threepipe.org/docs/classes/KTXLoadPlugin.html)
  2541. Adds support for loading .ktx ([Khronos Texture](https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/) files.
  2542. Note: This plugin only adds support for loading .ktx file, and not exporting them in the bundled .glb. Use .ktx2 files instead of .ktx files for better compression and performance.
  2543. ```typescript
  2544. import {KTXLoadPlugin} from 'threepipe'
  2545. viewer.addPluginSync(new KTXLoadPlugin())
  2546. const texture = await viewer.load('file.ktx')
  2547. ```
  2548. ## GLTFMeshOptDecodePlugin
  2549. [Example](https://threepipe.org/examples/#gltf-meshopt-compression/) &mdash;
  2550. [Source Code](./src/plugins/import/GLTFMeshOptDecodePlugin.ts) &mdash;
  2551. [API Reference](https://threepipe.org/docs/classes/GLTFMeshOptDecodePlugin.html)
  2552. Loads the MeshOpt Decoder module from [meshoptimizer](https://github.com/zeux/meshoptimizer) library at runtime from a customisable cdn url.
  2553. The loaded module is set in `window.MeshoptDecoder` and then used by `GLTFLoader2` to decode files using [EXT_meshopt_compression](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Vendor/EXT_meshopt_compression/README.md) extension
  2554. ```typescript
  2555. import {GLTFMeshOptDecodePlugin} from 'threepipe'
  2556. const plugin = viewer.addPluginSync(new GLTFMeshOptDecodePlugin())
  2557. // await plugin.initialize() // optional, this happens when loading a gltf file with extension anyway
  2558. const texture = await viewer.load('file.glb')
  2559. ```
  2560. ## SimplifyModifierPlugin
  2561. [Example](https://threepipe.org/examples/#simplify-modifier-plugin/) &mdash;
  2562. [Source Code](./src/plugins/extras/SimplifyModifierPlugin.ts) &mdash;
  2563. [API Reference](https://threepipe.org/docs/classes/SimplifyModifierPlugin.html)
  2564. Boilerplate for implementing a plugin for simplifying geometries.
  2565. This is a base class and cannot be used directly.
  2566. A sample to use it:
  2567. ```typescript
  2568. class SimplifyModifierPluginImpl extends SimplifyModifierPlugin {
  2569. protected _simplify(geometry: IGeometry, count: number) {
  2570. return new SimplifyModifier().modify(geometry, count) as IGeometry
  2571. }
  2572. }
  2573. const plugin = viewer.addPluginSync(new SimplifyModifierPluginImpl())
  2574. const root = await viewer.load('file.glb')
  2575. plugin.simplifyAll(root, {factor: 0.75})
  2576. ```
  2577. Check the [example](https://threepipe.org/examples/#simplify-modifier-plugin/) for full implementation.
  2578. ## MeshOptSimplifyModifierPlugin
  2579. [Example](https://threepipe.org/examples/#meshopt-simplify-modifier-plugin/) &mdash;
  2580. [Source Code](./src/plugins/extras/MeshOptSimplifyModifierPlugin.ts) &mdash;
  2581. [API Reference](https://threepipe.org/docs/classes/MeshOptSimplifyModifierPlugin.html)
  2582. Simplify modifier using [meshoptimizer](https://github.com/zeux/meshoptimizer) library. It Loads the library at runtime from a customisable CDN URL.
  2583. Note: It does not guarantee that the geometry will be simplified to the exact target count.
  2584. ```typescript
  2585. const simplifyModifier = viewer.addPluginSync(new MeshOptSimplifyModifierPlugin())
  2586. const root = await viewer.load('file.glb')
  2587. simplifyModifier.simplifyAll(root, {factor: 0.75})
  2588. ```
  2589. # @threepipe Packages
  2590. Additional plugins can be found in the [plugins](plugins/) directory.
  2591. These add support for integrating with other libraries, adding new features, and other functionality with different licenses.
  2592. ## @threepipe/plugin-tweakpane
  2593. [Tweakpane](https://tweakpane.github.io/docs/) UI plugin for ThreePipe
  2594. [//]: # (todo: image)
  2595. [Example](https://threepipe.org/examples/#tweakpane-ui-plugin/) &mdash;
  2596. [Source Code](./plugins/tweakpane/src/TweakpaneUiPlugin.ts) &mdash;
  2597. [API Reference](https://threepipe.org/plugins/tweakpane/docs/classes/TweakpaneUiPlugin.html)
  2598. NPM: `npm install @threepipe/plugin-tweakpane`
  2599. CDN: https://threepipe.org/plugins/tweakpane/dist/index.mjs
  2600. TweakpaneUiPlugin adds support for using [uiconfig-tweakpane](https://github.com/repalash/uiconfig-tweakpane)
  2601. to create a configuration UI in applications using the [Tweakpane](https://tweakpane.github.io/docs/) library.
  2602. The plugin takes the [uiconfig](https://github.com/repalash/uiconfig.js)
  2603. that's defined in the viewer and all the objects to automatically render a UI in the browser.
  2604. ```typescript
  2605. import {IObject3D, ThreeViewer, TonemapPlugin} from 'threepipe'
  2606. import {TweakpaneUiPlugin} from '@threepipe/plugin-tweakpane'
  2607. const viewer = new ThreeViewer({...})
  2608. // Add the plugin
  2609. const plugin = viewer.addPluginSync(new TweakpaneUiPlugin(true)) // true to show expanded the UI by default
  2610. // Add the UI for the viewer
  2611. plugin.appendChild(viewer.uiConfig)
  2612. // Add UI for some plugins
  2613. plugin.setupPlugins(TonemapPlugin, DropzonePlugin)
  2614. ```
  2615. ## @threepipe/plugin-blueprintjs
  2616. [Blueprint.js](https://blueprintjs.com/) UI plugin for ThreePipe
  2617. [//]: # (todo: image)
  2618. [Example](https://threepipe.org/examples/#blueprintjs-ui-plugin/) &mdash;
  2619. [Source Code](./plugins/blueprintjs/src/BlueprintJsUiPlugin.ts) &mdash;
  2620. [API Reference](https://threepipe.org/plugins/blueprintjs/docs/classes/BlueprintJsUiPlugin.html)
  2621. NPM: `npm install @threepipe/plugin-blueprintjs`
  2622. CDN: https://threepipe.org/plugins/blueprintjs/dist/index.mjs
  2623. BlueprintJsUiPlugin adds support for using [uiconfig-blueprint](https://github.com/repalash/uiconfig-blueprint)
  2624. to create a configuration UI in applications using the [BlueprintJs](https://blueprintjs.com/) library.
  2625. The plugin takes the [uiconfig](https://github.com/repalash/uiconfig.js)
  2626. that's defined in the viewer and all the objects to automatically render a UI in the browser.
  2627. ```typescript
  2628. import {IObject3D, ThreeViewer, TonemapPlugin} from 'threepipe'
  2629. import {BlueprintJsUiPlugin} from '@threepipe/plugin-blueprintjs'
  2630. const viewer = new ThreeViewer({...})
  2631. // Add the plugin
  2632. const plugin = viewer.addPluginSync(new BlueprintJsUiPlugin(true)) // true to show expanded the UI by default
  2633. // Add the UI for the viewer
  2634. plugin.appendChild(viewer.uiConfig)
  2635. // Add UI for some plugins
  2636. plugin.setupPlugins(TonemapPlugin, DropzonePlugin)
  2637. ```
  2638. ## @threepipe/plugin-tweakpane-editor
  2639. Tweakpane Editor Plugin for ThreePipe
  2640. [//]: # (todo: image)
  2641. [Example](https://threepipe.org/examples/#tweakpane-editor/) &mdash;
  2642. [Source Code](./plugins/tweakpane-editor/src/TweakpaneEditorPlugin.ts) &mdash;
  2643. [API Reference](https://threepipe.org/plugins/tweakpane-editor/docs/classes/TweakpaneEditorPlugin.html)
  2644. NPM: `npm install @threepipe/plugin-tweakpane-editor`
  2645. CDN: https://threepipe.org/plugins/tweakpane-editor/dist/index.mjs
  2646. TweakpaneEditorPlugin uses TweakpaneUiPlugin to create an editor for editing viewer,
  2647. plugins, model and material configurations in the browser.
  2648. ```typescript
  2649. import {IObject3D, ThreeViewer, TonemapPlugin} from 'threepipe'
  2650. import {TweakpaneEditorPlugin} from '@threepipe/plugin-tweakpane-editor'
  2651. const viewer = new ThreeViewer({...})
  2652. viewer.addPluginSync(new TweakpaneUiPlugin(true))
  2653. const editor = viewer.addPluginSync(new TweakpaneEditorPlugin())
  2654. // Add some plugins to the viewer
  2655. await viewer.addPlugins([
  2656. new ViewerUiConfigPlugin(),
  2657. // new SceneUiConfigPlugin(), // this is already in ViewerUiPlugin
  2658. new DepthBufferPlugin(HalfFloatType, true, true),
  2659. new NormalBufferPlugin(HalfFloatType, false),
  2660. new RenderTargetPreviewPlugin(false),
  2661. ])
  2662. // Load the plugin UI in the editor and tweakpane ui with categories.
  2663. editor.loadPlugins({
  2664. ['Viewer']: [ViewerUiConfigPlugin, SceneUiConfigPlugin, DropzonePlugin, FullScreenPlugin],
  2665. ['GBuffer']: [DepthBufferPlugin, NormalBufferPlugin],
  2666. ['Post-processing']: [TonemapPlugin],
  2667. ['Debug']: [RenderTargetPreviewPlugin],
  2668. })
  2669. ```
  2670. ## @threepipe/plugin-configurator
  2671. Configurator Plugin implementations with basic UI for Threepipe.
  2672. Includes Material Configurator and Switch Node Configurator Plugins.
  2673. NPM: `npm install @threepipe/plugin-configurator`
  2674. CDN: https://threepipe.org/plugins/dist/configurator/index.mjs
  2675. ### MaterialConfiguratorPlugin
  2676. [//]: # (todo: image)
  2677. [Example](https://threepipe.org/examples/#material-configurator-plugin/) &mdash;
  2678. [Source Code](./plugins/configurator/src/MaterialConfiguratorPlugin.ts) &mdash;
  2679. [API Reference](https://threepipe.org/plugins/configurator/docs/classes/MaterialConfiguratorPlugin.html)
  2680. MaterialConfiguratorPlugin adds a UI to configure and switch between different material variations.
  2681. The variations of materials are mapped to material names or uuids in the scene.
  2682. These variations can be applied to the materials in the scene. (This copies the properties to the same material instances instead of assigning new materials)
  2683. The plugin interfaces with the picking plugin and also provides uiConfig to show and edit the variations.
  2684. This functionality is inherited from [MaterialConfiguratorBasePlugin](https://threepipe.org/docs/classes/MaterialConfiguratorBasePlugin.html).
  2685. Additionally, this plugin adds a simple Grid UI in the DOM over the viewer canvas to show various material variations and allow the user to apply them.
  2686. The UI can also be used in the editor to edit the variations and apply them.
  2687. To use, simply add the plugin in the viewer and configure using the created UI and UI Config. Note that `PickingPlugin` is required to be added before this to allow configurator.
  2688. To create a custom configurator UI, use the `MaterialConfiguratorBasePlugin` directly and call the function `applyVariation`, `getPreview` and `addVariation` to apply and add variations respectively.
  2689. [//]: # (TODO Add Example for custom UI)
  2690. ### SwitchNodePlugin
  2691. [//]: # (todo: image)
  2692. [Example](https://threepipe.org/examples/#switch-node-plugin/) &mdash;
  2693. [Source Code](./plugins/configurator/src/SwitchNodePlugin.ts) &mdash;
  2694. [API Reference](https://threepipe.org/plugins/configurator/docs/classes/SwitchNodePlugin.html)
  2695. SwitchNodePlugin adds a UI to configure and switch between different different object variations within a switch node object.
  2696. This plugin allows you to configure object variations with object names in a file and apply them in the scene.
  2697. Each SwitchNode is a parent object with multiple direct children. Only one child is visible at a time.
  2698. This works by toggling the `visible` property of the children of a parent object.
  2699. The plugin interfaces with the picking plugin and also provides uiConfig to show and edit the variations.
  2700. It also provides a function to create snapshot previews of individual variations. This creates a limited render of the object with the selected child visible.
  2701. To get a proper render, its better to render it offline and set the image as a preview.
  2702. This functionality is inherited from [SwitchNodeBasePlugin](https://threepipe.org/docs/classes/SwitchNodeBasePlugin.html).
  2703. Additionally, this plugin adds a simple Grid UI in the DOM over the viewer canvas to show various material variations and allow the user to apply them.
  2704. The UI can also be used in the editor to edit the variations and apply them.
  2705. To use, simply add the plugin in the viewer and configure using the created UI and UI Config. Note that `PickingPlugin` is required to be added before this to allow configurator.
  2706. To create a custom configurator UI, use the `SwitchNodeBasePlugin` directly and call the function `selectNode`, `getPreview` and `addNode` to apply and add variations respectively.
  2707. [//]: # (TODO Add Example for custom UI)
  2708. ## @threepipe/plugin-gltf-transform
  2709. Exports [GLTFDracoExportPlugin](https://threepipe.org/plugins/gltf-transform/docs/classes/GLTFDracoExportPlugin.html) that extends the default gltf exporter to compress the file after export.
  2710. [Example](https://threepipe.org/examples/#glb-draco-export/) &mdash;
  2711. [Source Code](plugins/gltf-transform/src/index.ts) &mdash;
  2712. [API Reference](https://threepipe.org/plugins/gltf-transform/docs)
  2713. NPM: `npm install @threepipe/plugin-gltf-transform`
  2714. To use, simply add the plugin to the viewer and export using the `viewer.export` or `viewer.exportScene` functions. This also adds UI options to `AssetExporterPlugin` which are used when exporting using the plugin or using `viewer.exportScene`
  2715. The plugin overloads the default gltf exporter in the asset manager with `GLTFDracoExporter`. Using the [gltf-transform](https://gltf-transform.donmccurdy.com/) library, it compresses the exported gltf file using the [khr_draco_mesh_compression](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_draco_mesh_compression/README.md) extension.
  2716. Note - Only `glb` export supported right now.
  2717. Sample Usage:
  2718. ```typescript
  2719. import {ThreeViewer, downloadBlob} from 'threepipe'
  2720. import {GLTFDracoExportPlugin} from '@threepipe/plugin-gltf-transform'
  2721. const viewer = new ThreeViewer({...})
  2722. viewer.addPluginSync(GLTFDracoExportPlugin)
  2723. await viewer.load('file.glb')
  2724. const blob = await viewer.exportScene({
  2725. compress: true, // this must be specified, by default it's false.
  2726. viewerConfig: true, // to export with viewer, scene and plugin settings
  2727. })
  2728. // download the file
  2729. downloadBlob(blob, 'scene.glb')
  2730. ```
  2731. ## @threepipe/plugin-network
  2732. Network/Cloud related plugin implementations for Threepipe.
  2733. Includes `AWSClientPlugin` and `TransfrSharePlugin`.
  2734. NPM: `npm install @threepipe/plugin-network`
  2735. CDN: https://threepipe.org/plugins/dist/network/index.mjs
  2736. ### TransfrSharePlugin
  2737. [//]: # (todo: image)
  2738. [Example](https://threepipe.org/examples/#transfr-share-plugin/) &mdash;
  2739. [Source Code](./plugins/network/src/TransfrSharePlugin.ts) &mdash;
  2740. [API Reference](https://threepipe.org/plugins/network/docs/classes/TransfrSharePlugin.html)
  2741. TransfrSharePlugin provides functionality to export and upload the scene or an object as glb and provide link to share/preview/edit the files.
  2742. It uses the options from the `AssetExporterPlugin` to export the scene or object, and can be configured using it's ui.
  2743. Uses the free service [transfr.one](https://transfr.one/) by default which deletes the files after a certain time, but the url can be changed to a custom backend or a self-hosted version of transfr.
  2744. Note: since the uploaded files are publicly accessible by anyone by default, it is recommended to encrypt the file using the exporter options or use a secure backend.
  2745. ```typescript
  2746. import {ThreeViewer} from 'threepipe'
  2747. import {TransfrSharePlugin} from '@threepipe/plugin-network'
  2748. const viewer = new ThreeViewer({...})
  2749. // Add the plugin
  2750. const sharePlugin = viewer.addPluginSync(new TransfrSharePlugin())
  2751. // when sharing, this query param is set to the model link
  2752. sharePlugin.queryParam = 'm' // this is the default
  2753. // used when clicking/calling Share page link
  2754. sharePlugin.pageUrl = window.location.href // this is the default
  2755. // used when clicking/calling Share viewer link
  2756. sharePlugin.baseUrls.viewer = 'https://threepipe.org/examples/model-viewer/index.html'
  2757. // used when clicking/calling Share editor link
  2758. sharePlugin.baseUrls.editor = 'https://threepipe.org/examples/tweakpane-editor/index.html'
  2759. // set to a custom server
  2760. // sharePlugin.serverUrl = 'https://example.com/'
  2761. // upload and get the link of the 3d model
  2762. const link = await sharePlugin.getLink()
  2763. // or upload and get the share link with a base page. And also copy to clipboard and shows a alert prompt(using viewer.dialog)
  2764. const link2 = await sharePlugin.shareLink('https://example.com/custom_viewer')
  2765. // or get the editor link directly
  2766. const link3 = await sharePlugin.shareEditorLink()
  2767. // to encrypt
  2768. const assetExporterPlugin = viewer.getPlugin(AssetExporterPlugin) // this is a dependency, so automatically added
  2769. assetExporterPlugin.encrypt = true
  2770. // assetExporterPlugin.encryptKey = 'password' // user will be prompted for password when exporting if this is commented
  2771. await sharePlugin.shareViewerLink()
  2772. ```
  2773. ### AWSClientPlugin
  2774. [//]: # (todo: image)
  2775. [Example](https://threepipe.org/examples/#aws-client-plugin/) &mdash;
  2776. [Source Code](./plugins/network/src/AWSClientPlugin.ts) &mdash;
  2777. [API Reference](https://threepipe.org/plugins/network/docs/classes/AWSClientPlugin.html)
  2778. Provides `fetch` function that performs a fetch request with AWS v4 signing.
  2779. This is useful for connecting to AWS services like S3 directly from the client.
  2780. It also interfaces with the `FileTransferPlugin` to directly upload file when exported with the viewer or the plugin.
  2781. Note: Make sure to use keys with limited privileges and correct CORS settings.
  2782. All the keys will be stored in plain text if `serializeSettings` is set to true
  2783. ```typescript
  2784. import {ThreeViewer} from 'threepipe'
  2785. import {AWSClientPlugin} from '@threepipe/plugin-network'
  2786. const viewer = new ThreeViewer({...})
  2787. const awsPlugin = viewer.addPluginSync(new AWSClientPlugin())
  2788. // set parameters and export. This can all be done from the UI also.
  2789. awsPlugin.accessKeyId = '00000000000000000000'
  2790. awsPlugin.accessKeySecret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
  2791. awsPlugin.endpointURL = 'https://s3.amazonaws.com/bucket/'
  2792. awsPlugin.pathPrefix = 'some/path/'
  2793. // or load a json file with the parameters
  2794. // the json file can be creating by entering the data in the UI and clicking the download preset json option.
  2795. await viewer.load('file.json')
  2796. // this will export the scene as glb
  2797. const blob = await viewer.exportScene()
  2798. // for a plugin config
  2799. // blob = await viewer.export(viewer.getPlugin(GroundPlugin))
  2800. // for a material
  2801. // blob = await viewer.export(object.material)
  2802. // for an object/mesh
  2803. // blob = await viewer.export(object, {exportExt: 'glb'})
  2804. // upload to s3. needs the parameters to be correct
  2805. await viewer.exportBlob(blob, 'filename.glb')
  2806. ```
  2807. Note: CORS should be enabled for the S3 bucket on the domain where the viewer is hosted. This requirement can be bypassed during development by setting `AWSClientPlugin.USE_PROXY = true`. A free proxy is already set by default and can be changed by setting `AWSClientPlugin.PROXY_URL`.
  2808. ## @threepipe/plugins-extra-importers
  2809. Exports several plugins to add support for various file types.
  2810. [Example](https://threepipe.org/examples/#extra-importer-plugins/) &mdash;
  2811. [Source Code](./plugins/extra-importers/src/index.ts) &mdash;
  2812. [API Reference](https://threepipe.org/plugins/extra-importers/docs)
  2813. NPM: `npm install @threepipe/plugins-extra-importers`
  2814. CDN: https://threepipe.org/plugins/extra-importers/dist/index.mjs
  2815. This package exports several plugins to add support for several file types using the following plugins
  2816. - [TDSLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/TDSLoadPlugin.html) - Load 3DS Max (.3ds) files
  2817. - [ThreeMFLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/ThreeMFLoadPlugin.html) - Load 3MF (.3mf) files
  2818. - [ColladaLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/ColladaLoadPlugin.html) - Load Collada (.dae) files
  2819. - [AMFLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/AMFLoadPlugin.html) - Load AMF (.amf) files
  2820. - [BVHLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/BVHLoadPlugin.html) - Load BVH (.bvh) files
  2821. - [VOXLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/VOXLoadPlugin.html) - Load MagicaVoxel (.vox) files
  2822. - [GCodeLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/GCodeLoadPlugin.html) - Load GCode (.gcode) files
  2823. - [MDDLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/MDDLoadPlugin.html) - Load MDD (.mdd) files
  2824. - [PCDLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/PCDLoadPlugin.html) - Load Point cloud data (.pcd) files
  2825. - [TiltLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/TiltLoadPlugin.html) - Load Tilt Brush (.tilt) files
  2826. - [VRMLLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/VRMLLoadPlugin.html) - Load VRML (.wrl) files
  2827. - [MPDLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/MPDLoadPlugin.html) - Load LDraw (.mpd) files
  2828. - [VTKLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/VTKLoadPlugin.html) - Load VTK (.vtk) files
  2829. - [XYZLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/XYZLoadPlugin.html) - Load XYZ (.xyz) files
  2830. To add all the plugins at once use `extraImporters`. This adds support for loading all the above file types.
  2831. ```typescript
  2832. import {ThreeViewer} from 'threepipe'
  2833. import {extraImporters} from '@threepipe/plugins-extra-importers'
  2834. const viewer = new ThreeViewer({...})
  2835. viewer.addPluginsSync(extraImporters)
  2836. // Now load any file as is.
  2837. const model = await viewer.load<IObject3D>('file.3mf')
  2838. // To load the file as a data url, use the correct mimetype
  2839. const model1 = await viewer.load<IObject3D>('data:model/3mf;base64,...')
  2840. ```
  2841. Remove the `<IObject3D>` if using javascript and not typescript.
  2842. ## @threepipe/plugin-blend-importer
  2843. Exports [BlendImporterPlugin](https://threepipe.org/plugins/blend-importer/docs/classes/BlendLoadPlugin.html) which adds support for loading .blend files.
  2844. It uses [js.blend](https://github.com/acweathersby/js.blend) for parsing blend file structure.
  2845. Note: This is still a WIP.
  2846. Currently working: `Mesh`, `BufferGeometry` and basic `PointLight`.
  2847. To be added: `PhysicalMaterial`, `UnlitMaterial` (similar to blender-gltf-io plugin)
  2848. [Example](https://threepipe.org/examples/#blend-load/) &mdash;
  2849. [Source Code](./plugins/blend-importer/src/index.ts) &mdash;
  2850. [API Reference](https://threepipe.org/plugins/blend-importer/docs)
  2851. NPM: `npm install @threepipe/plugin-blend-importer`
  2852. ```typescript
  2853. import {ThreeViewer} from 'threepipe'
  2854. import {BlendLoadPlugin} from '@threepipe/plugin-blend-importer'
  2855. const viewer = new ThreeViewer({...})
  2856. viewer.addPluginSync(BlendLoadPlugin)
  2857. // Now load any .blend file.
  2858. const model = await viewer.load<IObject3D>('path/to/file.blend')
  2859. // To load the file as a data url, use the correct mimetype
  2860. const model1 = await viewer.load<IObject3D>('data:application/x-blender;base64,...')
  2861. ```
  2862. [//]: # ( TODO: The plugin should parse and references to other assets and find them relative to the .blend file or the current location.)
  2863. ## @threepipe/plugin-geometry-generator
  2864. Exports [GeometryGeneratorPlugin](https://threepipe.org/plugins/geometry-generator/docs/classes/BlendLoadPlugin.html) with several Geometry generators to create parametric and updatable geometries like plane, circle, sphere, box, torus, cylinder, cone etc.
  2865. [Example](https://threepipe.org/examples/#geometry-generator-plugin/) &mdash;
  2866. [Source Code](./plugins/geometry-generator/src/index.ts) &mdash;
  2867. [API Reference](https://threepipe.org/plugins/geometry-generator/docs)
  2868. NPM: `npm install @threepipe/plugin-geometry-generator`
  2869. The generated geometries/meshes include the parameters in the userData and can be re-generated by changing the parameters from the UI or the plugin API.
  2870. Includes the following generator which inherit from [AGeometryGenerator](https://threepipe.org/plugins/geometry-generator/docs/classes/AGeometryGenerator.html):
  2871. - **plane**: [PlaneGeometryGenerator](https://threepipe.org/plugins/geometry-generator/docs/classes/PlaneGeometryGenerator),
  2872. - **sphere**: [SphereGeometryGenerator](https://threepipe.org/plugins/geometry-generator/docs/classes/SphereGeometryGenerator),
  2873. - **box**: [BoxGeometryGenerator](https://threepipe.org/plugins/geometry-generator/docs/classes/BoxGeometryGenerator),
  2874. - **circle**: [CircleGeometryGenerator](https://threepipe.org/plugins/geometry-generator/docs/classes/CircleGeometryGenerator),
  2875. - **torus**: [TorusGeometryGenerator](https://threepipe.org/plugins/geometry-generator/docs/classes/TorusGeometryGenerator),
  2876. - **cylinder**: [CylinderGeometryGenerator](https://threepipe.org/plugins/geometry-generator/docs/classes/CylinderGeometryGenerator),
  2877. Sample Usage:
  2878. ```typescript
  2879. import {ThreeViewer, UnlitMaterial} from 'threepipe'
  2880. import {GeometryGeneratorPlugin} from '@threepipe/plugin-geometry-generator'
  2881. const viewer = new ThreeViewer({...})
  2882. const generator = viewer.addPluginSync(GeometryGeneratorPlugin)
  2883. const sphere = generator.generateObject('sphere', {radius: 3})
  2884. viewer.scene.addObject(sphere)
  2885. // to update the geometry
  2886. generator.updateGeometry(sphere.geometry, {radius: 4, widthSegments: 100})
  2887. // to add a custom generator
  2888. generator.generators.custom = new CustomGenerator('custom') // Extend from AGeometryGenerator or implement GeometryGenerator interface
  2889. // refresh the ui so the new generator is available to select.
  2890. generator.uiConfig.uiRefresh?.()
  2891. // change the material type for all objects
  2892. generator.defaultMaterialClass = UnlitMaterial // by default its PhysicalMaterial
  2893. viewer.scene.addObject(generator.generateObject('box', {width: 2, height: 2, depth: 2}))
  2894. ```
  2895. ## @threepipe/plugin-gaussian-splatting
  2896. Exports [GaussianSplattingPlugin](https://threepipe.org/plugins/gaussian-splatting/docs/classes/GaussianSplattingPlugin.html) which adds support for loading .blend files.
  2897. It uses [`three-gaussian-splat`](./plugins/gaussian-splatting/src/three-gaussian-splat), a rewrite of [@zappar/three-guassian-splat](https://github.com/zappar-xr/three-gaussian-splat) (and [gsplat.js](https://github.com/huggingface/gsplat.js) and [antimatter15/splat](https://github.com/antimatter15/splat)) for loading splat files and rendering gaussian splats.
  2898. [Example](https://threepipe.org/examples/#splat-load/) &mdash;
  2899. [Source Code](./plugins/gaussian-splatting/src/index.ts) &mdash;
  2900. [API Reference](https://threepipe.org/plugins/gaussian-splatting/docs)
  2901. NPM: `npm install @threepipe/plugin-gaussian-splatting`
  2902. Note: This is still a WIP.
  2903. Currently working:
  2904. * Importing .splat files (just array buffer of gaussian splat attributes)
  2905. * ThreeGaussianSplatPlugin (Same as GaussianSplattingPlugin), add importer and update events to the viewer
  2906. * GaussianSplatMaterialExtension for adding gaussian splat functionality to any material like Unlit, Physical
  2907. * GaussianSplatMesh a subclass of Mesh2 for holding the gaussian splat geometry and a material with gaussian splat extension. also handles basic raycast in the splat geometry. (assuming simple points)
  2908. * GaussianSplatGeometry holds the geometry data and and the sort worker. Computes correct bounding box and sphere.
  2909. * SplatLoader for loading splat files and creating the geometry and material.
  2910. * GaussianSplatMaterialUnlit, GaussianSplatMaterialRaw
  2911. * GaussianSplatMaterialPhysical, working but normals are hardcoded to 0,1,0
  2912. TBD:
  2913. * Exporting/embedding splat files into glb
  2914. * Rendering to depth/gbuffer
  2915. * Estimate normals/read from file
  2916. * Lighting in GaussianSplatMaterialPhysical
  2917. ```typescript
  2918. import {ThreeViewer} from 'threepipe'
  2919. import {GaussianSplattingPlugin} from '@threepipe/plugin-gaussian-splatting'
  2920. const viewer = new ThreeViewer({...})
  2921. viewer.addPluginSync(GaussianSplattingPlugin)
  2922. // Now load any .splat file.
  2923. const model = await viewer.load<GaussianSplatMesh>('path/to/file.splat')
  2924. ```
  2925. ## @threepipe/plugin-svg-renderer
  2926. Exports [ThreeSVGRendererPlugin](https://threepipe.org/plugins/svg-renderer/docs/classes/ThreeSVGRendererPlugin.html) and [BasicSVGRendererPlugin](https://threepipe.org/plugins/svg-renderer/docs/classes/BasicSVGRendererPlugin.html) which provide support for rendering the 3d scene as [SVG(Scalable Vector Graphics)](https://developer.mozilla.org/en-US/docs/Web/SVG). The generated SVG is compatible with browser rendering and other software like figma, illustrator etc.
  2927. [Example](https://threepipe.org/examples/#three-svg-renderer/) &mdash;
  2928. [Source Code](./plugins/svg-renderer/src/index.ts) &mdash;
  2929. [API Reference](https://threepipe.org/plugins/svg-renderer/docs) &mdash;
  2930. [GPLV3 License](./plugins/svg-renderer/LICENSE)
  2931. NPM: `npm install @threepipe/plugin-svg-renderer`
  2932. Note: This is still a WIP. API might change slightly
  2933. `ThreeSVGRendererPlugin` uses [`three-svg-renderer`](./plugins/svg-renderer/src/three-svg-renderer), which is a modified version of [three-svg-renderer](https://www.npmjs.com/package/three-svg-renderer) (GPLV3 Licenced).
  2934. The plugin renderers meshes in the viewer scene to svg objects by computing polygons and contours of the geometry in view space. Check [LokiResearch/three-svg-renderer](https://github.com/LokiResearch/three-svg-renderer?tab=readme-ov-file#references) for more details.
  2935. In the modified version that is used here, support for some types of geometries is added and a rendered image in screen-space is used to create raster fill images for paths along with some other small changes. Check out the [Example](https://threepipe.org/examples/#three-svg-renderer/) for demo. See also [svg-geometry-playground example](https://threepipe.org/examples/#svg-geometry-playground/) for usage with other plugins `PickingPlugin`, `TransformControlsPlugin` and `GeometryGeneratorPlugin`.
  2936. Note that this does not support all the features of three.js and may not work with all types of materials and geometries. Check the examples for a list of sample models that do and don't work.
  2937. `BasicSVGRendererPlugin` is a sample plugin using [SVGRenderer](https://threejs.org/docs/index.html?q=svg#examples/en/renderers/SVGRenderer) from three.js addons. This renders all triangles in the scene to separate svg paths. Check the three.js docs for more details. Check out the [Example](https://threepipe.org/examples/#basic-svg-renderer/) for demo.
  2938. ```typescript
  2939. import {ThreeViewer} from 'threepipe'
  2940. import {ThreeSVGRendererPlugin} from '@threepipe/plugin-svg-renderer'
  2941. const viewer = new ThreeViewer({
  2942. ...,
  2943. rgbm: false, // this is required
  2944. })
  2945. const svgRender = viewer.addPluginSync(ThreeSVGRendererPlugin)
  2946. svgRender.autoRender = true // automatically render when camera or any object changes.
  2947. svgRender.autoMakeSvgObjects = true // automatically create SVG objects for all meshes in the scene.
  2948. // svgRender.makeSVGObject(object) // manually create SVG object for an object. (if autoMakeSvgObjects is false)
  2949. // Now load or generate any 3d model. Make sure its not very big. And the meshes are optimized.
  2950. const model = await viewer.load<IOBject3D>('path/to/file.glb')
  2951. // clear the background of the viewer
  2952. viewer.scene.backgroundColor = null
  2953. viewer.scene.background = null
  2954. // disable damping to get better experience.
  2955. viewer.scene.mainCamera.controls!.enableDamping = false
  2956. // hide the canvas to see the underlying svg node.
  2957. // note: do not set the display to none or remove the canvas as OrbitControls and other plugins might still be tracking the canvas.
  2958. viewer.canvas.style.opacity = '0'
  2959. // 3d pipeline can also be disabled like this if `drawImageFills` is `false` to get better performance. Do this only after loading the model.
  2960. // await viewer.doOnce('postFrame') // wait for the first frame to be rendered (for autoScale etc)
  2961. // viewer.renderManager.autoBuildPipeline = false
  2962. // viewer.renderManager.pipeline = [] // this will disable main viewer rendering
  2963. ```