threepipe
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

3 лет назад
3 лет назад
2 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
2 лет назад
2 лет назад
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476
  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](#examples)
  32. - [Table of Contents](#table-of-contents)
  33. - [Getting Started](#getting-started)
  34. - [HTML/JS Quickstart (CDN)](#htmljs-quickstart-cdn)
  35. - [NPM/YARN Package](#npmyarn)
  36. - [Installation](#installation)
  37. - [Loading a 3D Model](#loading-a-3d-model)
  38. - [License](#license)
  39. - [Status](#status)
  40. - [Documentation (API Reference)](#documentation)
  41. - [WebGi](#webgi)
  42. - [Contributing](#contributing)
  43. - [Features](#features)
  44. - [File Formats](#file-formats)
  45. - [Loading files](#loading-files)
  46. - [3D models](#3d-models)
  47. - [Materials](#materials)
  48. - [Images/Textures](#imagestextures)
  49. - [zip files](#zip-files)
  50. - [txt, json files](#txt-json-files)
  51. - [Data URLs](#data-urls)
  52. - [Local files, File and Blob](#local-files-file-and-blob)
  53. - [Background, Environment maps](#background-environment-maps)
  54. - [SVG strings](#svg-strings)
  55. - [Exporting files](#exporting-files)
  56. - [Exporting 3D models](#exporting-3d-models)
  57. - [Exporting Materials](#exporting-materials)
  58. - [Exporting Canvas Images](#exporting-canvas-images)
  59. - [Exporting Images/Textures](#exporting-imagestextures)
  60. - [Exporting Render Targets](#exporting-render-targets)
  61. - [Render Pipeline](#render-pipeline)
  62. - [Material Extension](#material-extension)
  63. - [UI Configuration](#ui-configuration)
  64. - [Serialization](#serialization)
  65. - [Plugin System](#plugin-system)
  66. - [Viewer API](#viewer-api)
  67. - [ThreeViewer](#threeviewer)
  68. - [RenderManager](#rendermanager)
  69. - [RootScene](#rootscene)
  70. - [ICamera](#icamera)
  71. - [AssetManager](#assetmanager)
  72. - [AssetImporter](#assetimporter)
  73. - [AssetExporter](#assetexporter)
  74. - [MaterialManager](#materialmanager)
  75. - [Plugins](#threepipe-plugins)
  76. - [TonemapPlugin](#tonemapplugin) - Add tonemap to the final screen pass
  77. - [DropzonePlugin](#dropzoneplugin) - Drag and drop local files to import and load
  78. - [ProgressivePlugin](#progressiveplugin) - Post-render pass to blend the last frame with the current frame
  79. - [DepthBufferPlugin](#depthbufferplugin) - Pre-rendering of depth buffer
  80. - [NormalBufferPlugin](#normalbufferplugin) - Pre-rendering of normal buffer
  81. - [GBufferPlugin](#depthnormalbufferplugin) - Pre-rendering of depth and normal buffers in a single pass buffer
  82. - [GLTFAnimationPlugin](#gltfanimationplugin) - Add support for playing and seeking gltf animations
  83. - [PopmotionPlugin](#popmotionplugin) - Integrates with popmotion.io library for animation/tweening
  84. - [RenderTargetPreviewPlugin](#rendertargetpreviewplugin) - Preview any render target in a UI panel over the canvas
  85. - [GeometryUVPreviewPlugin](#geometryuvpreviewplugin) - Preview UVs of any geometry in a UI panel over the canvas
  86. - [FrameFadePlugin](#framefadeplugin) - Post-render pass to smoothly fade to a new rendered frame over time
  87. - [Rhino3dmLoadPlugin](#rhino3dmloadplugin) - Add support for loading .3dm files
  88. - [PLYLoadPlugin](#plyloadplugin) - Add support for loading .ply files
  89. - [STLLoadPlugin](#stlloadplugin) - Add support for loading .stl files
  90. - [KTX2LoadPlugin](#ktx2loadplugin) - Add support for loading .ktx2 files
  91. - [KTXLoadPlugin](#ktxloadplugin) - Add support for loading .ktx files
  92. - [Packages](#threepipe-packages)
  93. - [@threepipe/plugin-tweakpane](#threepipeplugin-tweakpane) Tweakpane UI Plugin
  94. - [@threepipe/plugin-tweakpane-editor](#threepipeplugin-tweakpane-editor) - Tweakpane Editor Plugin
  95. - [@threepipe/plugin-extra-importers](#threepipeplugin-extra-importers) - Plugin for loading even more file types.
  96. ## Getting Started
  97. ### HTML/JS Quickstart (CDN)
  98. ```html
  99. <canvas id="three-canvas" style="width: 800px; height: 600px;"></canvas>
  100. <script type="module">
  101. import {ThreeViewer, DepthBufferPlugin} from 'https://threepipe.org/dist/index.mjs'
  102. const viewer = new ThreeViewer({canvas: document.getElementById('three-canvas')})
  103. // Add some plugins
  104. viewer.addPluginSync(new DepthBufferPlugin())
  105. // Load an environment map
  106. const envPromise = viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr')
  107. const modelPromise = viewer.load('https://threejs.org/examples/models/gltf/DamagedHelmet/glTF/DamagedHelmet.gltf', {
  108. autoCenter: true,
  109. autoScale: true,
  110. })
  111. Promise.all([envPromise, modelPromise]).then(([env, model]) => {
  112. console.log('Loaded', model, env, viewer)
  113. })
  114. </script>
  115. ```
  116. Check it in action: https://threepipe.org/examples/#html-sample/
  117. Check out the details about the [ThreeViewer API](#viewer-api) and more [plugins](#threepipe-plugins) below.
  118. ### NPM/YARN
  119. ### Installation
  120. ```bash
  121. npm install threepipe
  122. ```
  123. ### Loading a 3D Model
  124. First, create a canvas element in your HTML page:
  125. ```html
  126. <canvas id="three-canvas" style="width: 800px; height: 600px;"></canvas>
  127. ```
  128. Then, import the viewer and create a new instance:
  129. ```typescript
  130. import {ThreeViewer, IObject3D} from 'threepipe'
  131. // Create a viewer
  132. const viewer = new ThreeViewer({canvas: document.getElementById('three-canvas') as HTMLCanvasElement})
  133. // Load an environment map
  134. await viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr')
  135. // Load a model
  136. const result = await viewer.load<IObject3D>('https://threejs.org/examples/models/gltf/DamagedHelmet/glTF/DamagedHelmet.gltf', {
  137. autoCenter: true,
  138. autoScale: true,
  139. })
  140. ```
  141. That's it! You should now see a 3D model on your page.
  142. The 3D model can be opened in the [editor](TODO) 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.
  143. 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.
  144. Check out the GLTF Load example to see it in action or to check the JS equivalent code: https://threepipe.org/examples/#gltf-load/
  145. Check out the [Plugins](#plugins) section below to learn how to add additional functionality to the viewer.
  146. ## License
  147. 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).
  148. 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.
  149. ## Status
  150. 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.
  151. Check out [WebGi](https://webgi.xyz/) for an advanced tailor-made solution for e-commerce, jewelry, automobile, apparel, furniture etc.
  152. ## Documentation
  153. Check the list of all functions, classes and types in the [API Reference Docs](https://threepipe.org/docs/).
  154. ## WebGi
  155. 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.
  156. [Homepage](https://webgi.xyz/) &mdash; [Docs](https://webgi.xyz/docs/)
  157. [![Twitter](https://img.shields.io/twitter/url/https/twitter.com/repalash.svg?style=social&label=Follow%20%40pixotronics)](https://twitter.com/pixotronics)
  158. ## Contributing
  159. Contributions to ThreePipe are welcome and encouraged! Feel free to open issues and pull requests on the GitHub repository.
  160. # Features
  161. ## File Formats
  162. ThreePipe Asset Manager supports the import of the following file formats out of the box:
  163. * **Models**: gltf, glb, obj+mtl, fbx, drc
  164. * **Materials**: mat, pmat, bmat (json based), registered material template slugs
  165. * **Images**: webp, png, jpeg, jpg, svg, ico, avif, hdr, exr
  166. * **Misc**: json, vjson, zip, txt
  167. Plugins can add additional formats:
  168. * Models
  169. * 3dm - Using [Rhino3dmLoadPlugin](#Rhino3dmLoadPlugin)
  170. * ply - Using [PLYLoadPlugin](#PLYLoadPlugin)
  171. * usdz - Using [USDZLoadPlugin](#USDZLoadPlugin)
  172. * stl - Using [STLLoadPlugin](#STLLoadPlugin)
  173. * ktx - Using [KTXLoadPlugin](#KTXLoadPlugin)
  174. * ktx2 - Using [KTX2LoadPlugin](#KTX2LoadPlugin)
  175. Plugins to support more model formats are available in the package [@threepipe/plugin-extra-importers](#threepipeplugin-extra-importers) including .3ds,
  176. .3mf, .collada, .amf, .bvh, .vox, .gcode, .mdd, .pcd, .tilt, .wrl, .mpd, .vtk, .xyz
  177. ## Loading files
  178. ThreePipe uses the [AssetManager](https://threepipe.org/docs/classes/AssetManager.html) to load files.
  179. The AssetManager has support for loading files from URLs, local files and data URLs.
  180. 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.
  181. [viewer.load()](https://threepipe.org/docs/classes/ThreeViewer.html#load) is a high-level wrapper for loading files from the AssetManager.
  182. It automatically adds the loaded object to the scene and returns a promise that resolves to the loaded object,
  183. the materials are also automatically registered to the material manager.
  184. AssetManager internally uses [AssetImporter](https://threepipe.org/docs/classes/AssetImporter.html),
  185. which provides a low-level API
  186. for managing three.js [LoadingManager](https://threejs.org/docs/#api/en/loaders/LoadingManager)
  187. and adding and registering loaders for different file types.
  188. 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
  189. to import files from the `AssetImporter`.
  190. viewer.assetManager.loadImported()](https://threepipe.org/docs/classes/AssetManager.html#loadImported)
  191. can then be called to load the imported files after any processing.
  192. The `viewer.load()`, `viewer.assetManager.addAsset()`
  193. and `viewer.assetManager.addAssetSingle()` methods perform combination of `import` and `loadImported`.
  194. ### 3D models
  195. The 3d models are added to `viewer.scene.modelRoot` on `viewer.load` unless some option is specified.
  196. ```typescript
  197. const objectGlb = await viewer.load<IObject3D>('https://example.com/file.glb')
  198. const objectFbx = await viewer.load<IObject3D>('https://example.com/file.fbx')
  199. const objectObj = await viewer.load<IObject3D>('https://example.com/file.obj') // .mtl referenced in obj is automatically loaded
  200. // ... load any 3d model file as an object
  201. ```
  202. Here, we are casting to [IObject3D](https://threepipe.org/docs/interfaces/IObject3D.html) type
  203. to get the proper type and autocomplete for the object.
  204. `IObject3D` inherits [Object3D](https://threejs.org/docs/#api/en/core/Object3D) from three.js and adds some additional properties.
  205. For JavaScript, the type can be omitted.
  206. ```javascript
  207. const objectGlb = await viewer.load('https://example.com/file.glb')
  208. ```
  209. 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.
  210. ### Materials
  211. The materials downloaded as PMAT/BMAT/JSON etc from threepipe,
  212. webgi or the editor can be loaded
  213. and registered with the [MaterialManager](https://threepipe.org/docs/classes/MaterialManager)
  214. using the `viewer.load` method.
  215. Custom material types can also be registered by plugins(like dmat for diamonds), which can also be loaded automatically using the `viewer.load` method.
  216. ```typescript
  217. const pMaterial = await viewer.load<PhysicalMaterial>('https://example.com/file.pmat')
  218. const bMaterial = await viewer.load<UnlitMaterial>('https://example.com/file.bmat')
  219. // ... load any material file as a material
  220. ```
  221. 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.
  222. To assign the material on any object, set it to `object.material`
  223. ```typescript
  224. // find a loaded mesh in the scene
  225. const object = viewer.scene.getObjectByName('objectName');
  226. // assign the material
  227. object.material = pMaterial;
  228. ```
  229. To copy the properties without changing the material reference, use `material.copy()` or `material.setValues()` methods.
  230. ```typescript
  231. object.material.copy(pMaterial);
  232. // or use material manager to apply to multiple materials.
  233. viewer.assetManager.materialManager.applyMaterial(pMaterial, 'METAL') // apply props to all materials/objects with the name METAL
  234. ```
  235. TODO: add examples for material load and copy
  236. ### Images/Textures
  237. Images can be loaded using the `viewer.load` method.
  238. 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.
  239. More formats like ktx2, ktx, etc. can be added using plugins.
  240. ```typescript
  241. const texture = await viewer.load<ITexture>('https://example.com/file.png')
  242. // ... load any image file as a texture
  243. ```
  244. Casting to [ITexture](https://threepipe.org/docs/interfaces/ITexture.html) is optional
  245. but recommended to get the proper type and autocomplete for the texture.
  246. It inherits from three.js [Texture](https://threejs.org/docs/#api/en/textures/Texture) and adds some additional properties.
  247. To assign the texture on any material, set it to `material.map`
  248. ```typescript
  249. // find a loaded mesh in the scene
  250. const object = viewer.scene.getObjectByName('objectName');
  251. const material = object.material as PhysicalMaterial;
  252. // assign the texture
  253. material.map = texture;
  254. 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.
  255. ```
  256. Check out the image load example to see it in action or to check the JS equivalent code: https://threepipe.org/examples/#image-load/
  257. ### Zip files
  258. .zip files are automatically unzipped and the files are sent to re-load recursively when loaded with `viewer.load`.
  259. Any level of zip hierarchy is flattened.
  260. Loading files like .gltf with references to assets inside the zip file,
  261. any relative references are also automatically resolved.
  262. This is supported for file types like gltf, glb, obj,
  263. etc which support references to external files and has `root` set to `true in [IImporter](https://threepipe.org/docs/interfaces/IImporter.html).
  264. ```typescript
  265. const objectGltf = await viewer.load<IObject3D>('https://example.com/model.gltf.zip')
  266. ```
  267. 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.
  268. 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.
  269. ```typescript
  270. const textures = await viewer.assetManager.addAsset<ITexture[]>('https://example.com/textures.zip')
  271. const materials = await viewer.assetManager.addAsset<IMaterial[]>('https://example.com/materials.zip')
  272. ```
  273. The auto import of zip contents can be disabled to get the files and blobs in the zip
  274. ```typescript
  275. const zip = await viewer.load<any>('https://example.com/file.zip', {autoImportZipContents: false})
  276. ```
  277. TODO - add example for loading zip files.
  278. ### txt, json files
  279. Text and JSON files can be loaded using the `viewer.load` method and return strings and objects respectively.
  280. ```typescript
  281. const text = await viewer.load<string>('https://example.com/file.txt')
  282. const json = await viewer.load<any>('https://example.com/file.json')
  283. ```
  284. ### Data URLs
  285. 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.
  286. ```typescript
  287. const dataUrl = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA' // ... some data url
  288. const texture = await viewer.load<ITexture>(dataUrl)
  289. ```
  290. ### Local files, File and Blob
  291. 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.
  292. ```typescript
  293. const file: File|Blob = fileObject // create a new file, blob or get from input element
  294. const text = await viewer.load<IObject>({
  295. // a path/name is required to determine the proper importer by extension. `file.name` can also be used if available
  296. path: 'file.glb',
  297. file
  298. })
  299. ```
  300. The same can be done for any file type.
  301. 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.
  302. ### Background, Environment maps
  303. 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.
  304. ```typescript
  305. await viewer.setEnvironmentMap('https://example.com/file.hdr')
  306. await viewer.setBackgroundMap('https://example.com/file.png')
  307. ```
  308. The same texture can be set to both by setting `setBackground` or `setEnvironment` to true in the options:
  309. ```typescript
  310. await viewer.setEnvironmentMap('https://example.com/file.hdr', {setBackground: true})
  311. ```
  312. Check the HDR Load example to see it in action: https://threepipe.org/examples/#hdr-load/
  313. ### SVG strings
  314. SVG strings can be converted to data urls using the [svgUrl](https://repalash.com/ts-browser-helpers/functions/svgUrl.html) string template function
  315. ```typescript
  316. const svgDataUrl = svgUrl`<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"> ... </svg>`;
  317. const texture = await viewer.load<ITexture>(dataUrl)
  318. ```
  319. ### Custom file types
  320. Custom file importers/loaders can be registered to the `AssetImporter` using the `addImporter` method.
  321. ```typescript
  322. class CustomLoader extends FileLoader implements ILoader{
  323. constructor(manager?: LoadingManager) {
  324. super(manager);
  325. }
  326. load(url: string, onLoad: (data: any) => void, onProgress?: (event: ProgressEvent) => void, onError?: (event: ErrorEvent) => void): Mesh {
  327. this.setResponseType('json')
  328. return super.load(url, (json: any)=>{
  329. const mat = new PhysicalMaterial(json)
  330. onLoad?.(mat)
  331. }, onProgress, onError)
  332. }
  333. }
  334. viewer.assetManager.importer.addImporter(new Importer(CustomLoader, ['ext'], ['mime/type'], false))
  335. // load the file
  336. const mat = await viewer.load<PhysicalMaterial>('https://example.com/file.ext')
  337. ```
  338. ## Exporting files
  339. Threepipe has support for exporting various asset type with AssetManager,
  340. as well as support to export viewer and plugin configuration, arbitrary objects etc using the [serialization](#serialization) system.
  341. [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.
  342. AssetManager internally uses [AssetExporter](https://threepipe.org/docs/classes/AssetExporter.html) to export files.
  343. AssetExporter includes some basic exporters for glb, exr, textures,
  344. and materials and a system to register exporters for different file types with plugins or custom exporters.
  345. ### Exporting 3D models
  346. Export the root scene as glb
  347. ```typescript
  348. const blob = await viewer.exportScene({
  349. viewerConfig: true, // default = true. export all viewer and plugin configuration. if false only the model root object is exported.
  350. })
  351. // download the file
  352. downloadBlob(blob, 'scene.glb')
  353. ```
  354. Export a single object from the scene as glb
  355. ```typescript
  356. const object = viewer.scene.getObjectByName('objectName');
  357. const glb: Blob = await viewer.export(object, {
  358. exportExt: 'glb', // default = glb for models
  359. embedUrlImages: true, // default = false. embed images in glb even when url is available.
  360. })
  361. // download the file
  362. downloadBlob(glb, 'object.glb')
  363. ```
  364. Check the example [glb-export](https://threepipe.org/examples/#glb-export/) to see a demo.
  365. ### Exporting Materials
  366. Export a material
  367. ```typescript
  368. const material = viewer.assetManager.materialManager.findMaterialsByName('materialName')[0];
  369. // or
  370. // const material = viewer.scene.getObjectByName('objectName').material;
  371. const blob = await viewer.export(material)
  372. // download the file
  373. downloadBlob(blob, 'material.' + blob.ext)
  374. ```
  375. Check the example [pmat-material-export](https://threepipe.org/examples/#pmat-material-export/) to see a demo.
  376. ### Exporting Canvas Images
  377. Canvas Screenshot/snapshot can be exported as png, jpeg or webp(if supported by the browser)
  378. ```typescript
  379. const blob = await viewer.getScreenshotBlob({mimeType: 'image/' + type, quality: 0.85})
  380. // or to get data url:
  381. // const dataUrl = await viewer.getScreenshotDataUrl({mimeType: 'image/' + type, quality: 0.85})
  382. // download the file
  383. downloadBlob(blob, 'screenshot.' + blob.ext)
  384. ```
  385. Check the example [image-snapshot-export](https://threepipe.org/examples/#image-snapshot-export/) to see a demo.
  386. ### Exporting Textures
  387. Textures can be exported to JSON using `viewer.export` or `AssetExporter`
  388. ```typescript
  389. const texture = await viewer.load('https://example.com/file.jpeg')
  390. const blob = await viewer.export(texture)
  391. downloadBlob(blob, texture.name + '.' + blob.ext)
  392. ```
  393. Render target textures can be exported with `viewer.renderManager.exportRenderTarget` or `viewer.export`,
  394. read about [Exporting Render Targets](#exporting-render-targets) below.
  395. TODO: add examples for texture export
  396. Textures and Uint8 Data Textures can be exported as a data url or copied to a new canvas
  397. ```typescript
  398. // get a base64 data url
  399. const dataUrl = textureToDataUrl(texture, 4096, false, 'image/png') // texture or data texture, max-size, flipY, mimeType
  400. // or copy to a new canvas
  401. const canvas = textureToCanvas(texture, 4096) // texture or data texture, max-size
  402. ```
  403. Data Textures of type Half float and Float can be exported with `viewer.export`
  404. ```typescript
  405. const dataTex = await viewer.load('https://example.com/file.hdr')
  406. const blob = await viewer.export(dataTexture, {exportExt: 'exr'})
  407. ```
  408. Check the example [hdr-to-exr](https://threepipe.org/examples/#hdr-to-exr/) to see a demo of HDR to EXR conversion.
  409. TODO: add support to export unsigned byte textures as png, jpeg, webp
  410. ### Exporting Images
  411. Exporting Textures as Images with image of types ImageBitmap, HTMLImageElement,
  412. HTMLOrSVGImageElement, CanvasImageSource, HTMLCanvasElement,
  413. OffscreenCanvas can be exported to png data urls with [imageBitmapToBase64](https://repalash.com/ts-browser-helpers/functions/imageBitmapToBase64.html) function.
  414. ```typescript
  415. const texture = await viewer.load('https://example.com/file.jpeg')
  416. const dataUrl = await imageBitmapToBase64(texture.image, 'image/png', 0.85);
  417. ```
  418. TODO: add support for texture export as images in AssetExporter
  419. ### Exporting Render Targets
  420. Unsigned byte render targets can be exported as png, jpeg or webp(if supported by the browser)
  421. ```typescript
  422. const depthPlugin = viewer.addPluginSync(DepthBufferPlugin, UnsignedByteType)
  423. // wait for the first render
  424. const blob = await viewer.export(depthPlugin.target!, {exportExt: 'png'})
  425. if (blob) downloadBlob(blob, target.texture.name + '.' + blob.ext)
  426. ```
  427. Half float and float render targets can be exported as exr
  428. ```typescript
  429. const depthPlugin = viewer.addPluginSync(DepthBufferPlugin, HalfFloatType)
  430. // wait for the first render
  431. const blob = await viewer.export(depthPlugin.target!, {exportExt: 'exr'})
  432. if (blob) downloadBlob(blob, target.texture.name + '.' + blob.ext)
  433. ```
  434. Note: `exportExt` is determined automatically if not specified.
  435. ## Render pipeline
  436. 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.
  437. 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,
  438. but the pass management and sorting is managed by the RenderManager itself.
  439. The RenderManager inherits from [RenderTargetManager](https://threepipe.org/docs/classes/RenderTargetManager.html)
  440. which provides utilities for creating, tracking and destroying dedicated and temporary render targets.
  441. ### Render Targets
  442. Render targets can be created
  443. using the `viewer.renderManager.createTarget` and `viewer.renderManager.createTargetCustom` methods.
  444. These can then be disposed using the `viewer.renderManager.disposeTarget` method when not needed anymore.
  445. Or to create temp targets for one time use `viewer.renderManager.getTempTarget` and `viewer.renderManager.releaseTempTarget` methods.
  446. can be used.
  447. All created render targets are tracked in the RenderManager,
  448. and are resized and disposed automatically when needed along with the viewer.
  449. ```typescript
  450. const newTarget = viewer.renderManager.createTarget({sizeMultiplier: 1})
  451. // or
  452. const newTarget2 = viewer.renderManager.createTarget({size: {
  453. width: 1024,
  454. height: 1024,
  455. },
  456. type: HalfFloatType
  457. })
  458. // or clone an existing target
  459. const newTarget3 = viewer.renderManager.composerTarget.clone()
  460. // for multi-sample render target
  461. const newTarget4 = viewer.renderManager.createTarget({sizeMultiplier: 1, samples: 4})
  462. // or create a custom target
  463. const newTarget5 = viewer.renderManager.createTargetCustom(
  464. {width: 1024, height: 1024},
  465. {type: HalfFloatType},
  466. WebGLCubeRenderTarget
  467. )
  468. // dispose targets
  469. viewer.renderManager.disposeTarget(newTarget)
  470. viewer.renderManager.disposeTarget(newTarget2)
  471. viewer.renderManager.disposeTarget(newTarget3)
  472. viewer.renderManager.disposeTarget(newTarget4)
  473. viewer.renderManager.disposeTarget(newTarget5)
  474. // get a temporary target
  475. const tempTarget = viewer.renderManager.getTempTarget({sizeMultiplier: 1})
  476. // release the temporary target
  477. viewer.renderManager.releaseTempTarget(tempTarget)
  478. ```
  479. Note: Render targets created with a sizeMultiplier are automatically resized when the canvas is resized.
  480. ### Passes
  481. By default, the render pipeline includes 2 passes -
  482. [RenderPass](https://threejs.org/docs/#api/en/postprocessing/RenderPass) for rendering the scene hierarchy and [ScreenPass](https://threejs.org/docs/#api/en/postprocessing/ShaderPass)
  483. for rendering the final output on the canvas.
  484. More passes can be added and removed from the pipeline
  485. using the [registerPass](https://threepipe.org/docs/classes/RenderManager.html#registerPass) and [unregisterPass](https://threepipe.org/docs/classes/RenderManager.html#unregisterPass) methods.
  486. The pipeline passes need
  487. to follow the interface of [IPipelinePass](https://threepipe.org/docs/interfaces/IPipelinePass.html) and [IPipelinePassPlugin](https://threepipe.org/docs/interfaces/IPipelinePassPlugin.html).
  488. Which adds some important parameters over the three.js Pass,
  489. like pass id and support for defining where the pass should be added in the pipeline and it's dependants.
  490. ```typescript
  491. const pass = new GBufferRenderPass('customPass', viewer.renderManager.createTarget({sizeMultiplier: 1}))
  492. pass.before = ['render'] // Add the pass before the render pass
  493. pass.after = [] // Add the pass after these passes (none in this case)
  494. pass.required = ['render'] // render pass is required to be in the pipeline for this
  495. viewer.renderManager.registerPass(pass)
  496. ```
  497. Note:
  498. See [PipelinePassPlugin](https://threepipe.org/docs/classes/PipelinePassPlugin.html) for an abstract plugin
  499. that provides the boilerplate to create a plugin that registers a custom pass in the pipeline.
  500. Check [NormalBufferPlugin](https://threepipe.org/docs/classes/NormalBufferPlugin.html) for an example of that.
  501. Note: All effects in post-processing or material extension need not be a separate pass in the pipeline.
  502. Most effects can be achieved with either extending the scene object material shaders or the Screen Pass material shader
  503. using [Material extension](#material-extension) system
  504. ## Material Extension
  505. Threepipe includes a Material extension system along with a material manager.
  506. The material manager is used to register materials and material extensions.
  507. The material extensions are used to extend any material in the scene,
  508. or any plugin/pass with additional uniforms, defines, shader snippets and provides hooks.
  509. The material extensions are automatically applied to all materials in the scene that are compatible,
  510. when the extension is registered or when the material is added to the scene.
  511. Threepipe includes several built-in materials like
  512. [PhysicalMaterial](https://threepipe.org/docs/classes/PhysicalMaterial.html),
  513. [UnlitMaterial](https://threepipe.org/docs/classes/UnlitMaterial.html),
  514. [ExtendedShaderMaterial](https://threepipe.org/docs/classes/ExtendedShaderMaterial.html)
  515. that include support for extending the material.
  516. Any three.js material can be made extendable,
  517. check the `ShaderPass2` class for a simple example that adds support for material extension to three.js ShaderPass.
  518. The material extensions must follow the [MaterialExtension](https://threepipe.org/docs/interfaces/MaterialExtension.html) interface.
  519. Many plugins create their own material extensions either for the scene materials or shader passes(like the screen pass).
  520. Some plugins like `DepthBufferPlugin` also provides helper material extensions for other custom plugins
  521. to fetch value in the depth buffer.
  522. A sample material extension
  523. ```typescript
  524. const extension: MaterialExtension = {
  525. shaderExtender: (shader)=> {
  526. // change the shader properties like shader.fragmentShader, etc
  527. },
  528. parsFragmentSnippet: ` // add some code before the main function in the fragment shader
  529. uniform sampler2D tTexture;
  530. uniform float opacity;
  531. `,
  532. extraUniforms: {
  533. tTexture: ()=>({value: getTexture()}),
  534. opacity: {value: 1}
  535. // add additional uniforms, these can be IUniform or functions that return IUniform
  536. },
  537. extraDefines: {
  538. ['DEPTH_PACKING']: BasicDepthPacking,
  539. ['SOME_DEFINE']: ()=>"1",
  540. // add additional defines, these can be values or functions that return values
  541. },
  542. priority: 100, // priority when using multiple extensions on the same material
  543. isCompatible: (material) => material.isMeshBasicMaterial, // check if the material is compatible with this extension,
  544. computeCacheKey: (material) => material.uuid, // a custom cache key for the material extension. Shader is recompiled when this is changed
  545. onObjectRender: (object: Object3D, material: IMaterial) => {
  546. // called when some object is rendererd which has a material with this extension.
  547. },
  548. // uiConfig
  549. // check more properties and hooks in the MaterialExtension interface
  550. }
  551. // The extension can be registered to all the materials using the MaterialManager
  552. viewer.assetManager.materialManager.registerMaterialExtension(extension)
  553. // or register it on a single material (like the Screen Pass)
  554. viewer.renderManager.screenPass.material.registerMaterialExtensions([extension])
  555. ```
  556. ## UI Configuration
  557. Most of the classes and plugins in Threepipe include [uiconfig.js](https://repalash.com/uiconfig.js/) support
  558. and can be used to create configuration UIs, 3d configurators and even full-editors.
  559. The UIs are automatically generated based on the configuration object under `.uiConfig` property on all objects.
  560. These are of type [UiObjectConfig](https://repalash.com/uiconfig.js/interfaces/UiObjectConfig.html).
  561. In some classes, the ui configs are also generated using typescript decorators.
  562. The `uiConfig` is also added to all three.js objects and materials when they are added to the scene.
  563. The UIs can be generated at runtime using any of the UI plugins like [TweakpaneUIPlugin](#threepipeplugin-tweakpane).
  564. An example showing how to create a UI for a material
  565. ```typescript
  566. const ui = viewer.addPluginSync(TweakpaneUiPlugin)
  567. const object = viewer.scene.getObjectByName('objectName');
  568. const material = object.material as PhysicalMaterial;
  569. ui.appendChild(material.uiConfig)
  570. ```
  571. See it in action: https://threepipe.org/examples/#material-uiconfig/
  572. Check more examples showing [Viewer UI](https://threepipe.org/examples/#viewer-uiconfig/),
  573. [Scene UI](https://threepipe.org/examples/#scene-uiconfig/),
  574. [Object UI](https://threepipe.org/examples/#object-uiconfig/), [Camera UI](https://threepipe.org/examples/#camera-uiconfig/)
  575. [TweakpaneEditorPlugin](#threepipeplugin-tweakpane-editor) further uses the Tweakpane configuration panel along with various plugins to create an 3d editor.
  576. Custom UI configuration can be created to generate custom UI for the editor or tweaking.
  577. 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.
  578. Here is a sample of extending the orbit controls class with decorators to automatically generate UI.
  579. ```typescript
  580. @uiPanelContainer('Orbit Controls')
  581. export class OrbitControlsWithUi extends OrbitControls implements IUiConfigContainer {
  582. // for autocomplete
  583. uiConfig?: UiObjectConfig<void, 'panel'>
  584. @uiToggle() enabled = true
  585. @uiToggle() dollyZoom = false
  586. @uiToggle() enableDamping = true
  587. @uiInput() dampingFactor = 0.08
  588. @uiToggle() autoRotate = false
  589. @uiInput() autoRotateSpeed = 2.0
  590. @uiToggle() enableZoom = true
  591. @uiInput() zoomSpeed = 0.15
  592. @uiInput() maxZoomSpeed = 0.20
  593. @uiToggle() enableRotate = true
  594. @uiInput() rotateSpeed = 2.0
  595. @uiToggle() enablePan = true
  596. @uiInput() panSpeed = 1.0
  597. @uiInput() autoPushTarget = false
  598. @uiInput() autoPullTarget = false
  599. @uiInput() minDistance = 0.35
  600. @uiInput() maxDistance = 1000
  601. @uiInput() minZoom = 0.01
  602. @uiInput() maxZoom = 1000
  603. @uiInput() minPolarAngle = 0
  604. @uiInput() maxPolarAngle = Math.PI
  605. @uiInput() minAzimuthAngle = -10000 // should be -Infinity but this breaks the UI
  606. @uiInput() maxAzimuthAngle = 10000
  607. }
  608. ```
  609. Check out the full source code:
  610. [./src/three/controls/OrbitControls3.ts](./src/three/controls/OrbitControls3.ts) for proper implementation
  611. See it in action: https://threepipe.org/examples/#camera-uiconfig/ Open the Camera UI and click on the Orbit Controls panel.
  612. There are many available decorators like `uiToggle`, `uiSlider`, `uiInput`, `uiNumber`, `uiColor`, `uiImage`.
  613. Check the complete list in the [uiconfig.js documentation](https://repalash.com/uiconfig.js/).
  614. The UI configuration can also be created using json objects in both typescript and javascript
  615. ```javascript
  616. const viewer = new ThreeViewer({...})
  617. const ui = viewer.addPluginSync(TweakpaneUiPlugin)
  618. const state = {
  619. position: new Vector3(),
  620. scale: 1,
  621. }
  622. ui.appendChild({
  623. type: 'folder',
  624. label: 'Custom UI',
  625. children: [
  626. {
  627. type: 'vec3',
  628. label: 'Position',
  629. property: [state, 'position']
  630. },
  631. {
  632. type: 'slider',
  633. label: ()=>'Scale', // everything can be a function as well.
  634. property: [state, 'scale'],
  635. bounds: [1, 2],
  636. stepSize: 0.1,
  637. }
  638. ]
  639. })
  640. ```
  641. TODO: create example/codepen for this
  642. ## Serialization
  643. Easy serialization of all threepipe and most three.js objects are supported out of the box using the Asset Manager.
  644. Fine control over serialization is also supported
  645. using the [ThreeSerialization](https://threepipe.org/docs/classes/ThreeSerialization.html) class
  646. Call `ThreeSerialization.serialize` on any object to serialize it.
  647. and `ThreeSerialization.deserialize` to deserialize the serialized object.
  648. This is done by performing a nested serialization of all the properties of the object.
  649. It's possible to implement custom serializers for custom types and classes and is done for three.js primitives,
  650. objects and plugins in threepipe
  651. To make a custom data class that is serializable,
  652. mark it using `@serializable` decorator and any properties using `@serialize` decorator.
  653. ```typescript
  654. @serializable('DataClass')
  655. class DataClass{
  656. @serialize() prop1 = 1
  657. @serialize() prop2 = 'string'
  658. @serialize() prop3 = new Vector3()
  659. @serialize() prop4 = new PhysicalMaterial()
  660. @serialize() prop4 = {
  661. prop1: 1,
  662. prop2: 'string',
  663. prop3: new Vector3(),
  664. prop4: new PhysicalMaterial(),
  665. }
  666. }
  667. const data = new DataClass()
  668. const serialized = ThreeSerialization.serialize(data)
  669. const deserialized = ThreeSerialization.deserialize(serialized)
  670. ```
  671. The classes without a `@serializable` decorator are serialized as plain objects.
  672. These can still include `@serialize` decorator to mark the properties are serializable
  673. but these classes cannot be deserialized into a new instance of the class.
  674. The ThreeViewer and plugins are an example of these.
  675. When deserialized they need an object to deserialize into.
  676. This ensures there is always just one instance.
  677. With this, the serialization system works like `toJSON` and `fromJSON` methods in three.js.
  678. Check the [plugin system](#plugin-system) below for more details on how to mark properties as serializable for plugins.
  679. ```typescript
  680. class CustomClass{
  681. @serialize() prop1 = 1
  682. @serialize() prop2 = 'string'
  683. @serialize() prop3 = new Vector3()
  684. @serialize() prop4 = new PhysicalMaterial()
  685. }
  686. const obj = new DataClass()
  687. const serialized = ThreeSerialization.serialize(data)
  688. // now to deserialize we need to pass in the object to deserialize into
  689. ThreeSerialization.deserialize(serialized, obj)
  690. ```
  691. ## Plugin System
  692. Threepipe includes a plugin system for adding additional features to the viewer in a modular way.
  693. The plugins can be added synchronously or asynchronously using `viewer.addPluginSync` and `viewer.addPlugin` methods respectively.
  694. It is recommended to create custom plugins for reusable features,
  695. as they provide built-in features for ui configuration,
  696. serialization, integration with editors etc and are easy to manage and tree-shake in the code.
  697. Check out the list of plugins in the [Plugin List](#threepipe-plugins) section below.
  698. To create new plugins,
  699. 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.
  700. The only difference is that in async the `onAdded` and `onRemove` functions are async
  701. Here is a sample plugin
  702. ```typescript
  703. @uiFolder("Sample Plugin") // This creates a folder in the Ui. (Supported by TweakpaneUiPlugin)
  704. export class SamplePlugin extends AViewerPluginSync<"sample-1" | "sample-2"> {
  705. // These are the list of events that this plugin can dispatch.
  706. static readonly PluginType = "SamplePlugin"; // This is required for serialization and handling plugins. Also used in viewer.getPluginByType()
  707. @uiToggle() // This creates a checkbox in the Ui. (Supported by TweakpaneUiPlugin)
  708. @serialize() // Adds this property to the list of serializable. This is also used when serializing to glb in AssetExporter.
  709. enabled = true;
  710. // A plugin can have custom properties.
  711. @uiSlider("Some Number", [0, 100], 1) // Adds a slider to the Ui, with custom bounds and step size (Supported by TweakpaneUiPlugin)
  712. @serialize("someNumber")
  713. @onChange(SamplePlugin.prototype._updateParams) // this function will be called whenevr this value changes.
  714. val1 = 0;
  715. // A plugin can have custom properties.
  716. @uiInput("Some Text") // Adds a slider to the Ui, with custom bounds and step size (Supported by TweakpaneUiPlugin)
  717. @onChange(SamplePlugin.prototype._updateParams) // this function will be called whenevr this value changes.
  718. @serialize()
  719. val2 = "Hello";
  720. @uiButton("Print Counters") // Adds a button to the Ui. (Supported by TweakpaneUiPlugin)
  721. public printValues = () => {
  722. console.log(this.val1, this.val2);
  723. this.dispatchEvent({ type: "sample-1", detail: { sample: this.val1 } }); // This will dispatch an event.
  724. }
  725. constructor() {
  726. super();
  727. this._updateParams = this._updateParams.bind(this);
  728. }
  729. private _updateParams() {
  730. console.log("Parameters updated.");
  731. this.dispatchEvent({ type: "sample-2" }); // This will dispatch an event.
  732. }
  733. onAdded(v: ThreeViewer): void {
  734. super.onAdded(v);
  735. // Do some initialization here.
  736. this.val1 = 0;
  737. this.val2 = "Hello";
  738. v.addEventListener("preRender", this._preRender);
  739. v.addEventListener("postRender", this._postRender);
  740. v.addEventListener("preFrame", this._preFrame);
  741. v.addEventListener("postFrame", this._postFrame);
  742. this._viewer!.scene.addEventListener("addSceneObject", this._objectAdded); // this._viewer can also be used while this plugin is attached.
  743. }
  744. onRemove(v: ThreeViewer): void {
  745. // remove dispose objects
  746. v.removeEventListener("preRender", this._preRender);
  747. v.removeEventListener("postRender", this._postRender);
  748. v.removeEventListener("preFrame", this._preFrame);
  749. v.removeEventListener("postFrame", this._postFrame);
  750. this._viewer!.scene.removeEventListener("addSceneObject", this._objectAdded); // this._viewer can also be used while this plugin is attached.
  751. super.onRemove(v);
  752. }
  753. private _objectAdded = (ev: IEvent<any>) => {
  754. console.log("A new object, texture or material is added to the scene.", ev.object);
  755. };
  756. private _preFrame = (ev: IEvent<any>) => {
  757. // 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()
  758. };
  759. private _preRender = (ev: IEvent<any>) => {
  760. // This is called before each frame is rendered, only when the viewer is dirty.
  761. };
  762. // postFrame and postRender work the same way as preFrame and preRender.
  763. }
  764. ```
  765. Notes:
  766. * 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`
  767. * 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.
  768. * Event listeners and other hooks can be added and removed in `onAdded` and `onRemove` functions for the viewer and other plugins.
  769. * 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)
  770. * All Plugins which inherit from AViewerPlugin support serialisation. Create property `serializeWithViewer = false` to disable serialization with the viewer in config and glb or `toJSON: any = undefined` to disable serialisation entirely
  771. * plugin.toJSON() and plugin.fromJSON() or ThreeSerialization can be used to serialize and deserialize plugins. viewer.exportPluginConfig and viewer.importPluginConfig also exist for this.
  772. * @serialize('label') decorator can be used to mark any public/private variable as serialisable. label (optional) corresponds to the key in JSON.
  773. * @serialize supports instances of ITexture, IMaterial, all primitive types, simple JS objects, three.js math classes(Vector2, Vector3, Matrix3...), and some more.
  774. * uiDecorators can be used to mark properties and functions that will be shown in the Ui. The Ui shows up automatically when TweakpaneUiPlugin is added to the viewer. Plugins have special features in the UI for download preset and saving state.
  775. Check various plugins in the source code for more examples.
  776. # Viewer API
  777. [ThreeViewer](https://threepipe.org/docs/classes/ThreeViewer.html) - is the main entry point to 3d rendering on the canvas.
  778. - `.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
  779. - `.renderer`: [IWebGLRenderer](https://threepipe.org/docs/interfaces/IWebGLRenderer.html) - for rendering. Instance of three.js [WebGLRenderer](https://threejs.org/docs/#api/en/renderers/WebGLRenderer)
  780. - `.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)
  781. - `.context`: [WebGLRenderingContext](https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext) - WebGL rendering context
  782. - `.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
  783. - `.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.
  784. - `.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)
  785. - `.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)
  786. - `.assetManager`: [AssetManager](https://threepipe.org/docs/classes/AssetManager.html) - Asset manager for loading, managing and exporting assets
  787. - `.importer`: [AssetImporter](https://threepipe.org/docs/classes/AssetImporter.html) - for importing assets
  788. - `.exporter`: [AssetExporter](https://threepipe.org/docs/classes/AssetExporter.html) - for exporting assets
  789. - `.materialManager`: [MaterialManager](https://threepipe.org/docs/classes/MaterialManager.html) - for managing materials and material extensions
  790. - `.plugins`: `Record`<`string`, [IViewerPlugin](https://threepipe.org/docs/interfaces/IViewerPlugin.html)> - Plugins added to the viewer
  791. - `.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.
  792. ## ThreeViewer
  793. Source Code: [src/viewer/ThreeViewer.ts](./src/viewer/ThreeViewer.ts)
  794. API Reference: [ThreeViewer](https://threepipe.org/docs/classes/ThreeViewer.html)
  795. `ThreeViewer` is the main entry point to the viewer. It provides all the API for managing the scene, camera, rendering, plugins, etc.
  796. It is initialized with either a canvas element or a `HTMLElement` for the container.
  797. The canvas element is used for rendering, and the options are used to configure the viewer.
  798. If the canvas element is not provided, a new canvas element is created and appended to the container.
  799. More options can be passed in the constructor to configure various built-in plugins and rendering features in the viewer.
  800. ### Constructor
  801. ```typescript
  802. import {ThreeViewer} from 'threepipe'
  803. const viewer = new ThreeViewer({
  804. canvas: document.getElementById('mcanvas') as HTMLCanvasElement,
  805. // or a container like:
  806. // container: document.getElementById('mcontainer'),
  807. // container: document.body,
  808. // Set the render scale to render at device resolution
  809. renderScale: window.devicePixelRatio,
  810. // modify the screen shader: See ScreenPass and ScreenPass.glsl for more details
  811. screenShader: `diffuseColor = diffuseColor * 2.0;`,
  812. // Add TonemapPlugin
  813. tonemap: true,
  814. // Use MSAA(anti-aliasing)
  815. msaa: false,
  816. // Use Uint8 RGBM HDR Render Pipeline. Provides better performance with post-processing. RenderManager Uses Half-float if set to false.
  817. rgbm: true,
  818. // Use rendered gbuffer as depth-prepass / z-prepass.
  819. zPrepass: false,
  820. // Options for AssetManager
  821. assetManager: {
  822. // Use a custom CacheStorage
  823. storage: caches.open('threepipe-assetmanager'),
  824. },
  825. // Use DropzonePlugin to add support for file drag and drop
  826. // Enable and set properties
  827. dropzone: {
  828. // Set allowed extensions
  829. allowedExtensions: ['png', 'glb', 'gltf'],
  830. // Automatically add downloaded assets
  831. autoAdd: true
  832. // autoImport: true,
  833. // domElement: document.body,
  834. // addOptions: { ... }
  835. // importOptions: { ... }
  836. }
  837. // By default its false
  838. // dropzone: false,
  839. // To Enable without options
  840. // dropzone: true
  841. })
  842. ```
  843. Check the interface [ThreeViewerOptions](https://threepipe.org/docs/interfaces/ThreeViewerOptions.html) for all the options.
  844. To dispose off the viewer and all its resources call [`viewer.dispose()`](https://threepipe.org/docs/classes/ThreeViewer.html#dispose) method.
  845. To dispose only the scene objects and not the complete viewer, use `viewer.scene.disposeSceneModels()`
  846. ### Plugin Functions
  847. ```typescript
  848. import {ThreeViewer, TonemapPlugin, DepthBufferPlugin, NormalBufferPlugin} from 'threepipe'
  849. const viewer = new ThreeViewer({...})
  850. // Add a plugin
  851. const plugin = viewer.addPluginSync(new TonemapPlugin())
  852. // plugins can be added with just the class also
  853. const plugin = viewer.addPluginSync(TonemapPlugin)
  854. // Add multiple plugins at once
  855. viewer.addPluginsSync([
  856. TonemapPlugin,
  857. new NormalBufferPlugin(),
  858. DepthBufferPlugin,
  859. // ...
  860. ])
  861. // Get a plugin
  862. const plugin = viewer.getPlugin(TonemapPlugin)
  863. // Get or add a plugin, when not sure if the plugin is already added
  864. const plugin = viewer.getOrAddPluginSync(TonemapPlugin)
  865. // Remove a plugin
  866. viewer.removePluginSync(TonemapPlugin)
  867. ```
  868. Note: all sync functions above have async counterparts like `addPlugin`, `getOrAddPlugin`,
  869. `removePlugin` that are used for async plugins.
  870. There are no async plugins built-in to threepipe yet.
  871. ### Import/Export Functions
  872. ```typescript
  873. import {ThreeViewer} from 'threepipe'
  874. const viewer = new ThreeViewer({...})
  875. // Load a 3d model
  876. const object = await viewer.load<IObject3D>('https://example.com/file.glb')
  877. // Load a material
  878. const material = await viewer.load<PhysicalMaterial>('https://example.com/file.pmat')
  879. // Load an image
  880. const texture = await viewer.load<ITexture>('https://example.com/file.png')
  881. // Import a model without adding to the scene
  882. const imported = await viewer.import('https://example.com/file.glb')
  883. // Export the complete scene with viewer configuraion
  884. const exportedScene = await viewer.exportScene({})
  885. // Export an object
  886. const exported = await viewer.export(object)
  887. // Export a material
  888. const exportedMaterial = await viewer.export(material)
  889. // Export a texture
  890. const exportedTexture = await viewer.export(texture)
  891. // Export viewer and plugins configurations
  892. const exportedConfig = await viewer.export(viewer)
  893. // Export plugin configuration
  894. const exportedPlugin = await viewer.exportPlugin(viewer.getPlugin(PluginClass))
  895. // Set Background Image
  896. await viewer.setBackgroundMap('https://example.com/file.png')
  897. // Set Environment Map
  898. await viewer.setEnvironmentMap('https://example.com/file.hdr')
  899. // Add an imported object or a created three.js object to the scene
  900. viewer.addSceneObject(imported)
  901. ```
  902. [`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.
  903. [`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.
  904. [`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.
  905. [`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.
  906. [`viewer.exportPlugin`](https://threepipe.org/docs/classes/ThreeViewer.html#exportPlugin) - Exports a plugin configuration and returns a blob.
  907. [`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.
  908. [`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.
  909. [`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.
  910. ### Frame/Rendering Events
  911. ```typescript
  912. import {ThreeViewer} from 'threepipe'
  913. const viewer = new ThreeViewer({...})
  914. // Add a callback to be called before every frame, irrespective of whether enything is being rendered that frame
  915. viewer.addEventListener('preFrame', (ev)=>{
  916. console.log(ev);
  917. // change something
  918. viewer.setDirty() // let the viewer know to re-render the scene from this frame
  919. })
  920. // Add a callback to be called after every frame, irrespective of whether enything was rendered that frame
  921. viewer.addEventListener('postFrame', (ev)=>{
  922. console.log(ev);
  923. // change something
  924. viewer.setDirty() // let the viewer know to re-render the scene from next frame
  925. })
  926. // Add a callback to be called before every render, only if something is being rendered that frame
  927. viewer.addEventListener('preRender', (ev)=>{
  928. // canvas is about to be rendered, or re-rendered for progressive rendering
  929. console.log(ev, viewer.renderManager.frameCount);
  930. })
  931. // Add a callback to be called after every render, only if something was rendered that frame
  932. viewer.addEventListener('postRender', (ev)=>{
  933. // canvas is rendered, or re-rendered for progressive rendering
  934. console.log(ev);
  935. })
  936. // Listen to viewer.setDirty() calls
  937. viewer.addEventListener('update', (ev)=>{
  938. // viewer.setDirty() was called by some plugin or code
  939. console.log(ev);
  940. })
  941. // to remove an event listener, first keep a reference to the callback
  942. const callback = (ev)=>{ return }
  943. viewer.addEventListener('preFrame', callback)
  944. // then remove it
  945. viewer.removeEventListener('preFrame', callback)
  946. // Add a callback to be called only once for an event
  947. viewer.doOnce('postFrame', () => viewer.canvas.toDataURL('image/png'))
  948. // Enable/disable rendering in the viewer
  949. viewer.renderEnabled = false
  950. // do something with the canvas or load assets
  951. await viewer.load('https://example.com/file.glb')
  952. await viewer.load('https://example.com/file1.glb')
  953. await viewer.load('https://example.com/file2.glb')
  954. viewer.renderEnabled = true // all the assets will be rendered together in the next frame
  955. ```
  956. Check the [IViewerEvent](https://threepipe.org/docs/interfaces/IViewerEvent.html) interface for all the event types.
  957. [`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.
  958. [`viewer.removeEventListener`](https://threepipe.org/docs/classes/ThreeViewer.html#removeEventListener) - Removes a callback from the given event.
  959. [`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.
  960. ### Utility Functions
  961. ```typescript
  962. import {ThreeViewer} from 'threepipe'
  963. const viewer = new ThreeViewer({...})
  964. // Set size
  965. viewer.setSize({width: 800, height: 600})
  966. // Traverse scene objects
  967. viewer.traverseSceneObjects((object) => {
  968. console.log(object)
  969. // do something with object
  970. })
  971. // If the size is set by css or manually by javascript use `resize` to update the viewer
  972. viewer.resize()
  973. // Trigger re-render with `setDirty` when something changes and viewer is not notified internally
  974. viewer.setDirty()
  975. // Get snapshot of the canvas as a blob
  976. const blob = await viewer.getScreenshotBlob({mimeTye: 'image/png', quality: 90})
  977. // Get snapshot of the canvas as a data url
  978. const dataUrl = await viewer.getScreenshotDataUrl({mimeTye: 'image/jpeg', quality: 85})
  979. // Dispose viewer and all resources
  980. viewer.canvas.remove() // canvas needs to be removed separately from the DOM
  981. viewer.dispose()
  982. ```
  983. [`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.
  984. [`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.
  985. [`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.
  986. [`viewer.setDirty`](https://threepipe.org/docs/classes/ThreeViewer.html#setDirty) - Triggers re-render on next `requestAnimationFrame` call.
  987. [`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.
  988. [`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.
  989. [`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.
  990. ## RenderManager
  991. 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)
  992. 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)
  993. It manages the rendering, composition/postprocessing of the scene and provides helpers for rendering and render target management.
  994. ```typescript
  995. const viewer = new ThreeViewer({...})
  996. const renderManager = viewer.renderManager
  997. // Get the effect composer
  998. const composer = renderManager.composer
  999. // Get the three.js webgl renderer
  1000. const renderer = renderManager.renderer
  1001. // Get the main Render Pass in the pipeline
  1002. const renderPass = renderManager.renderPass
  1003. // Get the main Screen Pass in the pipeline
  1004. const screenPass = renderManager.screenPass
  1005. // Set the render scale
  1006. renderManager.renderScale = Math.min(window.devicePixelRatio, 2)
  1007. // Register a custom composer pass
  1008. const customPass: IPipelinePass = new CustomPass()
  1009. renderManager.registerPass(customPass)
  1010. // Unregister a custom composer pass
  1011. renderManager.unregisterPass(customPass)
  1012. // The pipeline is automatically created and sorted based on dependencies in pipeline pass.
  1013. // To check the built pipeline
  1014. console.log(renderManager.pipeline)
  1015. // Set a custom render pipeline
  1016. renderManager.autoBuildPipeline = false
  1017. renderManager.pipeline = ['depth', 'render', 'screen']
  1018. // Check the total frames rendererd
  1019. console.log(renderManager.totalFrameCount)
  1020. // Get the current frame count in progressive rendering
  1021. console.log(renderManager.frameCount)
  1022. // Force reset shadows when some object is moved
  1023. renderManager.resetShadows()
  1024. // Render Target Management
  1025. // Get the main composer target
  1026. const composerTarget = renderManager.composerTarget
  1027. // clone the target to get a copy of the target with all the default options
  1028. const clonedTarget = composeTarget.clone()
  1029. // Create a render target, same size as the canvas. The target are automatically resized when the canvas is resized
  1030. const renderTarget = renderManager.createTarget({
  1031. sizeMultiplier: 1, // size multiplier from the canvas. 0.5 will be half width and height of the canvas
  1032. type: UnsignedByteType,
  1033. // ... // See CreateRenderTargetOptions for all options
  1034. })
  1035. // Create a render target of custom size
  1036. const renderTarget = renderManager.createTarget({
  1037. size: {
  1038. width: 1024,
  1039. height: 1024,
  1040. },
  1041. type: HalfFloatType,
  1042. // ...
  1043. })
  1044. // Dispose the render target
  1045. renderManager.disposeTarget(renderTarget)
  1046. // Create and release temporary targets for in-pass rendering.
  1047. const tempTarget = renderManager.getTempTarget({
  1048. sizeMultiplier: 0.5,
  1049. type: HalfFloatType,
  1050. // ...
  1051. })
  1052. // do something
  1053. renderManager.releaseTempTarget(tempTarget)
  1054. // Set how many temporary targets can remain in memory for a specific set of options
  1055. renderManager.maxTempPerKey = 10 // default = 5
  1056. // Copy/Blit a texture to the canvas or another render target with standard or a custom material
  1057. renderManager.blit(destination, {source: sourceTexture})
  1058. // Clear color of the canvas
  1059. renderManager.clearColor({r: 0, g: 0, b: 0, a: 1, depth: true, viewport: new Vector4(...)})
  1060. // Clear of a render target
  1061. renderManager.clearColor(renderTarget, {r: 0, g: 0, b: 0, a: 1, target: renderTarget})
  1062. // Export a render target to a blob. The type is automatically picked from exr to png based on the render target
  1063. const blob = renderManager.exportRenderTarget(renderTarget, 'auto')
  1064. // Export a render target to png/jpeg data url. This will clamp any floating point targets to fit in png/jpeg
  1065. const dataUrl = renderManager.renderTargetToDataUrl(renderTarget, 'image/png')
  1066. // Read render target pixels to array buffer. Returns Uint8Array|Uint16Array|Float32Array based on the render target type
  1067. const buffer = renderManager.renderTargetToBuffer(renderTarget)
  1068. ```
  1069. [`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.
  1070. [`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
  1071. [`renderManager.context`](https://threepipe.org/docs/classes/ViewerRenderManager.html#context) - Access the WebGL rendering context for the canvas.
  1072. [`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.
  1073. [`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
  1074. [`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.
  1075. [`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.
  1076. ### Rendering Pipeline
  1077. [`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.
  1078. [`renderManager.unregisterPass`](https://threepipe.org/docs/classes/RenderManager.html#unregisterPass) - Unregisters a custom composer pass from the render pipeline.
  1079. [`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.
  1080. [`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`.
  1081. [`renderManager.totalFrameCount`](https://threepipe.org/docs/classes/RenderManager.html#totalFrameCount) - The total frames rendered since the render manager was created.
  1082. [`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.
  1083. ### Render Targets management
  1084. [`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)
  1085. [`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
  1086. [`renderManager.disposeTarget`](https://threepipe.org/docs/classes/RenderTargetManager.html#disposeTarget) - Disposes a render target and removes it from the render target manager.
  1087. [`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
  1088. [`renderManager.releaseTempTarget`](https://threepipe.org/docs/classes/RenderTargetManager.html#releaseTempTarget) - Releases a temporary render target and adds it back to the render target manager.
  1089. [`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`.
  1090. ### Helpers
  1091. [`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.
  1092. [`renderManager.clearColor`](https://threepipe.org/docs/classes/RenderManager.html#clearColor) - Clears the color of the canvas or a render target.
  1093. [`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.
  1094. [`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.
  1095. [`renderManager.renderTargetToBuffer`](https://threepipe.org/docs/classes/RenderManager.html#renderTargetToBuffer) - Reads render target pixels to a Uint8Array|Uint16Array|Float32Array array buffer.
  1096. ## RootScene
  1097. Source Code: [src/core/object/RootScene.ts](./src/core/object/RootScene.ts)
  1098. API Reference: [RootScene](https://threepipe.org/docs/classes/RootScene.html)
  1099. RootScene is the main scene that is rendered in the canvas.
  1100. 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,
  1101. backgroundColor, background map and background intensity,
  1102. environment map rotation and intensity, fixed env map direction patch, event bubbling in the scene hierarchy, scene config serialization, main camera management,
  1103. automatic active near far management based on scene bounds, disposing complete scene hierarchy, etc
  1104. ```typescript
  1105. const viewer = new ThreeViewer({...})
  1106. const scene = viewer.scene
  1107. // List oll loaded objects in the model root
  1108. console.log(scene.modelRoot.children)
  1109. // Set the background color
  1110. scene.setBackgroundColor('#ffffff')
  1111. // or
  1112. // scene.backgroundColor = new Color('#ffffff')
  1113. // or
  1114. // scene.backgroundColor.set('#ffffff')
  1115. // scene.onBackgroundChange() // this must be called when not using a setter or set function.
  1116. // Set a texture as background (or use viewer.setBackgroundMap). When both color and texture are set, they are multiplied
  1117. scene.background = customTexture
  1118. // Set the background same as the environment map
  1119. scene.background = 'environment' // background is automatically changed when the environment changes.
  1120. // or
  1121. // scene.background = scene.environment
  1122. // Set the background intensity
  1123. scene.backgroundIntensity = 2
  1124. // Set a texture as environment map (or use viewer.setEnvironmentMap)
  1125. scene.environment = customTexture
  1126. // Set the environment intensity
  1127. scene.envMapIntensity = 2
  1128. // Set the environment map rotation
  1129. scene.environment.rotation = Math.PI / 2
  1130. // Set Fixed env direction (rotate environment according the the camera)
  1131. scene.fixedEnvMapDirection = true
  1132. // Get the main camera used for rendering
  1133. const camera: PerspectiveCamera2 = scene.mainCamera
  1134. // Set camera props
  1135. camera.position.set(0, 0, 10)
  1136. camera.target.set(0, 0, 0)
  1137. camera.setDirty() // this needs to be called to notify the viewer to re-render the scene
  1138. // Traverse the model root hierarchy (or just use viewer.traverseSceneObjects)
  1139. scene.modelRoot.traverse((object) => {
  1140. console.log(object)
  1141. // do something with object
  1142. })
  1143. // Access the default camera (same as mainCamera if not changed explicitly)
  1144. const defaultCamera: ICamera = scene.defaultCamera
  1145. // Dispose all assets in the modelRoot
  1146. scene.disposeSceneModels()
  1147. // Remove all objects from the modelRoot
  1148. scene.clearSceneModels()
  1149. // Dispose the scene and all its resources and children
  1150. scene.dispose()
  1151. // Get bounds of the scene model root
  1152. const bounds = scene.getBounds(true, true) // true for precise bounds and ignore invisible
  1153. // Add an object to the scene or its model root depending on the options (or just use viewer.addSceneObject)
  1154. scene.addObject(object, {addToRoot: false}) // adds to the scene directly when addToRoot is true
  1155. // Load an imported model root from the asset importer
  1156. scene.loadModelRoot(object)
  1157. // notify that something has changed in the scene for re-render
  1158. scene.setDirty()
  1159. // notify that some object has changed in the scene for scene refresh(like shadow refresh, ground etc) and re-render
  1160. scene.refreshScene()
  1161. // or
  1162. scene.setDirty({refreshScene: true})
  1163. // set geometryChanged: false to prevent shadow recompute
  1164. scene.refreshScene({geometryChanged: false})
  1165. // refresh active near far. (in most cases this is done automatically and need not be called)
  1166. scene.refreshActiveNearFar()
  1167. ```
  1168. [`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.
  1169. [`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.
  1170. [`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.
  1171. [`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.
  1172. [`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.
  1173. [`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.
  1174. `scene.environment.rotation` - The rotation of the environment map around the y-axis.
  1175. [`scene.envMapIntensity`](https://threepipe.org/docs/classes/RootScene.html#envMapIntensity) - The environment intensity of the scene.
  1176. [`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.
  1177. [`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.
  1178. [`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.
  1179. [`scene.disposeSceneModels`](https://threepipe.org/docs/classes/RootScene.html#disposeSceneModels) - Disposes all assets in the modelRoot.
  1180. [`scene.clearSceneModels`](https://threepipe.org/docs/classes/RootScene.html#clearSceneModels) - Removes all objects from the modelRoot.
  1181. [`scene.dispose`](https://threepipe.org/docs/classes/RootScene.html#dispose) - Disposes the scene and all its resources and children.
  1182. [`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.
  1183. [`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.
  1184. [`scene.setDirty`](https://threepipe.org/docs/classes/RootScene.html#setDirty) - Notifies that something has changed in the scene for re-render.
  1185. [`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.
  1186. [`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)
  1187. [`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.
  1188. ### Scene Events
  1189. RootScene dispatches many events that are useful when writing app logic or plugins
  1190. `'sceneUpdate'` - Listen to `refreshScene` called in RootScene. When some object changes.
  1191. `'addSceneObject'` - When a new object is added to the scene
  1192. `'mainCameraChange'` - When the main camera is changed to some other camera.
  1193. `'mainCameraUpdate'` - When some properties in the current main camera has changed.
  1194. `'environmentChanged'` - When the environment map changes
  1195. `'backgroundChanged'` - When the background map or color changes
  1196. `'materialUpdate`' - When a material in the scene has updated. (setDirty called on the material)
  1197. `'objectUpdate`' - When a object in the scene has updated. (setDirty called on the object)
  1198. `'textureUpdate`' - When a texture in the scene has updated. (setDirty called on the texture)
  1199. `'cameraUpdate`' - When a camera in the scene has updated.
  1200. (setDirty called on the camera)
  1201. `'geometryUpdate`' - When a geometry in the scene has updated.
  1202. (setDirty called on the geometry)
  1203. `'geometryChanged`' - When a geometry is changed on any mesh
  1204. `'materialChanged'` - When a material is changed on any mesh
  1205. Check [IObject3DEventTypes](https://threepipe.org/docs/interfaces/IObject3DEventTypes.html) and[ISceneEventTypes](https://threepipe.org/docs/interfaces/ISceneEventTypes.html) for more information.
  1206. ## ICamera
  1207. Source Code: [src/core/camera/PerspectiveCamera2.ts](./src/core/camera/PerspectiveCamera2.ts), [src/core/ICamera.ts](./src/core/ICamera.ts)
  1208. API Reference: [PerspectiveCamera2](https://threepipe.org/docs/classes/PerspectiveCamera2.html), [ICamera](https://threepipe.org/docs/interfaces/ICamera.html)
  1209. ICamera is an interface for a camera that extends the three.js [Camera](https://threejs.org/docs/#api/en/cameras/Camera).
  1210. PerspectiveCamera2 implements the interface,
  1211. 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.
  1212. ```typescript
  1213. import {OrbitControls3} from './OrbitControls3'
  1214. const viewer = new ThreeViewer({...})
  1215. const camera: PerspectiveCamera2 = viewer.scene.mainCamera
  1216. // Set the camera position
  1217. camera.position.set(0, 0, 10)
  1218. // Set the camera target (where the camera looks at)
  1219. camera.target.set(0, 0, 0)
  1220. // Set the camera fov
  1221. camera.fov = 45
  1222. // Set the camera aspect ratio
  1223. camera.autoAspect = false // disable automatic aspect management based on the canvas size
  1224. camera.aspect = 1
  1225. // Set camera near far bounds.
  1226. // Near, Far plane will be calculated automatically within these limits
  1227. // Try changing these values when encountering z-fighting issues or far-plane clipping
  1228. camera.minNearPlane = 0.5 // min near plane
  1229. camera.maxFarPlane = 10 // max far plane
  1230. // Set a custom camera near far
  1231. camera.autoNearFar = false // disable automatic near far management based on the scene bounds
  1232. camera.minNearPlane = 0.1 // near plane
  1233. camera.maxFarPlane = 1000 // far plane
  1234. // this needs to be called to notify the viewer to re-render the scene
  1235. // in most cases this is done internally. But calling this does not have much impact
  1236. camera.setDirty()
  1237. // Check if user can interact with the camera. Also checks if its the main camera.
  1238. console.log(camera.canUserInteract)
  1239. // Get the camera controls (orbit controls for the default camera)
  1240. const controls: OrbitControls3 = camera.controls
  1241. // Disable controls
  1242. controls.enabled = false
  1243. // Change the controls mode
  1244. camera.controlsMode = 'none' // this will remove the current controls.
  1245. // Register a custom camera controls
  1246. camera.setControlsCtor('customOrbit', (camera, domElement) => new CustomOrbitControls(camera, domElement))
  1247. // Set the camera controls
  1248. camera.controlsMode = 'customOrbit' // this will initialize the controls with the customOrbit constructor and set it on the camera
  1249. // Disable interactions to the camera. (eg when animating)
  1250. camera.interactionsEnabled = false
  1251. // Force refresh aspect ratio (this is done automatically with a ResizeObserver on the canvas in the viewer)
  1252. camera.refreshAspect()
  1253. // Set the camera as the main camera
  1254. camera.activateMain()
  1255. // Deactivate the camera as the main camera
  1256. camera.deactivateMain()
  1257. ```
  1258. [`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.
  1259. [`camera.autoAspect`](https://threepipe.org/docs/classes/PerspectiveCamera2.html#autoAspect) - If `true`, the aspect ratio is automatically calculated based on the canvas size.
  1260. [`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`.
  1261. [`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
  1262. [`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
  1263. [`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.
  1264. [`camera.setDirty`](https://threepipe.org/docs/classes/PerspectiveCamera2.html#setDirty) - Notifies that something has changed in the camera for re-render.
  1265. [`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.
  1266. [`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`
  1267. [`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.
  1268. [`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.
  1269. [`camera.interactionsEnabled`](https://threepipe.org/docs/classes/PerspectiveCamera2.html#interactionsEnabled) - 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.
  1270. [`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)
  1271. [`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.
  1272. [`camera.deactivateMain`](https://threepipe.org/docs/classes/PerspectiveCamera2.html#deactivateMain) - Deactivate the camera as the main camera.
  1273. ## AssetManager
  1274. Source Code: [src/assetmanager/AssetManager.ts](./src/assetmanager/AssetManager.ts)
  1275. API Reference: [AssetManager](https://threepipe.org/docs/classes/AssetManager.html)
  1276. `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.
  1277. ```typescript
  1278. const viewer = new ThreeViewer({...})
  1279. const assetManager = viewer.assetManager
  1280. // Add an asset or an asset bundle
  1281. const assets = await assetManager.addAsset('https://example.com/model.zip')
  1282. // or
  1283. const assets = await assetManager.addAsset({
  1284. path: 'https://example.com/model.zip',
  1285. file: blob,
  1286. })
  1287. // Get the storage used in the asset manager for caching
  1288. const storage: Cache | Storage = assetManager.storage
  1289. // Get the importer. Provides low level functions to import assets
  1290. const importer = assetManager.importer
  1291. // import a file by asset or url
  1292. const file = await importer.import('https://example.com/model.gltf')
  1293. // Import a Map<string, File> from drag drop
  1294. const res = await importer.importFiles(mapOfFiles, {})
  1295. // Register a custom path that maps to a File object. Useful when some file types have path references to other files.
  1296. importer.registerFile('/myFile.png', file) // this returns the three.js loader for that kind of file.
  1297. // Unregister the path
  1298. importer.unregisterFile('/myFile.png')
  1299. // Unregister all files and clear the loader cache(memory, not storage)
  1300. importer.clearCache()
  1301. // Add custom importers (check extra load plugins for more examples)
  1302. importer.addImporter(new Importer(class extends PLYLoader implements ILoader {
  1303. transform(res: BufferGeometry, _: AnyOptions): Mesh | undefined {
  1304. return res ? new Mesh(res, new PhysicalMaterial({color: new Color(1, 1, 1)})) : undefined
  1305. }
  1306. }, ['ply'], ['text/plain+ply'], false))
  1307. // Get the exporter. Provides low level functions to export assets
  1308. const exporter = assetManager.exporter
  1309. // Export any IObject3D, IMaterial, ITexture, IRenderTarget
  1310. const exported = exporter.exportObject(obj, options)
  1311. // Add a custom exporter
  1312. exporter.addExporter({
  1313. ext: ['gltf', 'glb'], // file extensions
  1314. extensions: [], // extensions for the exporter
  1315. ctor: (assetExporter, iexporter) => {
  1316. return new GLTFExporter2()
  1317. }
  1318. })
  1319. // Material Manager
  1320. const materialManager = assetManager.materialManager
  1321. // Create a material of type
  1322. const mat = materialManager.create('physical')
  1323. const mat2 = materialManager.create('unlit')
  1324. // find or create a material by uuid
  1325. const mat = materialManager.findOrCreate('00000000-0000-0000-0000-000000000000', {color: '#ffffff'})
  1326. // find a material creation template
  1327. const template = materialManager.findTemplate('physical')
  1328. // Get all materials
  1329. const materials = materialManager.getAllMaterials()
  1330. // Get all materials of type
  1331. const materials = materialManager.getMaterialsOfType(PhysicalMaterial.TypeSlug)
  1332. // register a custom material to the manager for tracking and extensions
  1333. // Note all materials created in threepipe internally are registered automatically on creation or when added to any scene object.
  1334. materialManager.registerMaterial(customMat)
  1335. // unregister
  1336. materialManager.unregisterMaterial(customMat)
  1337. // clear all material references
  1338. materialManager.clearMaterials()
  1339. // Register a custom material template
  1340. materialManager.registerTemplate({
  1341. generator: (params: any) => new PhysicalMaterial(params),
  1342. name: 'custom',
  1343. materialType: PhysicalMaterial.TYPE,
  1344. params: {
  1345. color: '#ffffff',
  1346. roughness: 0.5,
  1347. metalness: 0.5,
  1348. },
  1349. })
  1350. const mat3 = materialManager.create('custom')
  1351. // convert a standard three.js material to threepipe material
  1352. const mat4 = materialManager.convertToIMaterial(new ShadowMaterial(), {materialTemplate: 'test'})
  1353. // register a custom material extension for all materials in the viewer
  1354. materialManager.registerMaterialExtension(customExtension)
  1355. // unregister
  1356. materialManager.unregisterMaterialExtension(customExtension)
  1357. // remove all extensions
  1358. materialManager.clearExtensions()
  1359. // Apply a material properties to other material(s) in the scene by name or uuid
  1360. materialManager.applyMaterial(goldMaterial, 'METAL') // this will copy the properties from goldMaterial to all the materials(or objects) in the viewer with the name METAL.
  1361. // export a material as JSON. Note: use AssetExporter instead to export all the embedded assets and properties properly.
  1362. const blob = materialManager.exportMaterial(mat)
  1363. // dispose manager and all materials.
  1364. materialManager.dispose()
  1365. ```
  1366. [`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.
  1367. [`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.
  1368. [`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).
  1369. [`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).
  1370. ### AssetImporter
  1371. [`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.
  1372. [`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.
  1373. [`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.
  1374. [`importer.unregisterFile`](https://threepipe.org/docs/classes/AssetImporter.html#unregisterFile) - Unregister the path.
  1375. [`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).
  1376. [`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.
  1377. ### AssetExporter
  1378. [`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.
  1379. [`exporter.addExporter`](https://threepipe.org/docs/classes/AssetExporter.html#addExporter) - Add a custom exporter for a custom file type.
  1380. ### MaterialManager
  1381. [`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).
  1382. [`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.
  1383. [`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.
  1384. [`materialManager.getAllMaterials`](https://threepipe.org/docs/classes/MaterialManager.html#getAllMaterials) - Get all materials registered with the manager.
  1385. [`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.
  1386. [`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
  1387. [`materialManager.unregisterMaterial`](https://threepipe.org/docs/classes/MaterialManager.html#unregisterMaterial) - Unregister a material from the manager.
  1388. [`materialManager.clearMaterials`](https://threepipe.org/docs/classes/MaterialManager.html#clearMaterials) - Clear all registered material references.
  1389. [`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.
  1390. [`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).
  1391. [`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.
  1392. [`materialManager.unregisterMaterialExtension`](https://threepipe.org/docs/classes/MaterialManager.html#unregisterMaterialExtension) - Unregister a material extension from the manager.
  1393. [`materialManager.clearExtensions`](https://threepipe.org/docs/classes/MaterialManager.html#clearExtensions) - Remove all material extensions from the manager.
  1394. [`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.
  1395. [`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.
  1396. [`materialManager.dispose`](https://threepipe.org/docs/classes/MaterialManager.html#dispose) - Dispose manager and all materials.
  1397. # Threepipe Plugins
  1398. 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.
  1399. ## TonemapPlugin
  1400. [//]: # (todo: image)
  1401. Example: https://threepipe.org/examples/#tonemap-plugin/
  1402. Source Code: [src/plugins/postprocessing/TonemapPlugin.ts](./src/plugins/postprocessing/TonemapPlugin.ts)
  1403. API Reference: [TonemapPlugin](https://threepipe.org/docs/classes/TonemapPlugin.html)
  1404. TonemapPlugin adds a post-processing material extension to the ScreenPass in render manager
  1405. that applies tonemapping to the color. The tonemapping operator can be changed
  1406. by setting the `toneMapping` property of the plugin. The default tonemapping operator is `ACESFilmicToneMapping`.
  1407. Other Tonemapping properties can be like `exposure`, `contrast` and `saturation`
  1408. TonemapPlugin is added by default in ThreeViewer unless `tonemap` is set to `false` in the options.
  1409. ## DropzonePlugin
  1410. [//]: # (todo: image)
  1411. Example: https://threepipe.org/examples/#dropzone-plugin/
  1412. Source Code: [src/plugins/interaction/DropzonePlugin.ts](./src/plugins/interaction/DropzonePlugin.ts)
  1413. API Reference: [DropzonePlugin](https://threepipe.org/docs/classes/DropzonePlugin.html)
  1414. DropzonePlugin adds support for drag and drop of local files to automatically import, process and load them into the viewer.
  1415. DropzonePlugin can be added by default in ThreeViewer
  1416. by setting the `dropzone` property to `true` or an object of `DropzonePluginOptions` in the options.
  1417. ```typescript
  1418. import {DropzonePlugin, ThreeViewer} from 'threepipe'
  1419. const viewer = new ThreeViewer({
  1420. canvas: document.getElementById('mcanvas') as HTMLCanvasElement,
  1421. dropzone: true, // just set to true to enable drag drop functionatility in the viewer
  1422. })
  1423. ```
  1424. To set custom options,
  1425. pass an object of [DropzonePluginOptions](https://threepipe.org/docs/interfaces/DropzonePluginOptions.html) type to the `dropzone` property.
  1426. ```typescript
  1427. import {DropzonePlugin, ThreeViewer} from 'threepipe'
  1428. const viewer = new ThreeViewer({
  1429. canvas: document.getElementById('mcanvas') as HTMLCanvasElement,
  1430. dropzone: { // this can also be set to true and configured by getting a reference to the DropzonePlugin
  1431. allowedExtensions: ['gltf', 'glb', 'hdr', 'png', 'jpg', 'json', 'fbx', 'obj', 'bin', 'exr'], // only allow these file types. If undefined, all files are allowed.
  1432. addOptions: {
  1433. disposeSceneObjects: true, // auto dispose of old scene objects
  1434. autoSetEnvironment: true, // when hdr is dropped
  1435. autoSetBackground: true, // when any image is dropped
  1436. autoCenter: true, // auto center the object
  1437. autoScale: true, // auto scale according to radius
  1438. autoScaleRadius: 2,
  1439. license: 'Imported from dropzone', // Any license to set on imported objects
  1440. importConfig: true, // import config from file
  1441. },
  1442. // check more options in the DropzonePluginOptions interface
  1443. },
  1444. })
  1445. ```
  1446. ## ProgressivePlugin
  1447. [//]: # (todo: image)
  1448. Example: https://threepipe.org/examples/#progressive-plugin/
  1449. Source Code: [src/plugins/postprocessing/ProgressivePlugin.ts](./src/plugins/pipeline/ProgressivePlugin.ts)
  1450. API Reference: [ProgressivePlugin](https://threepipe.org/docs/classes/ProgressivePlugin.html)
  1451. Progressive Plugin adds a post-render pass to blend the last frame with the current frame.
  1452. 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.
  1453. ## DepthBufferPlugin
  1454. [//]: # (todo: image)
  1455. Example: https://threepipe.org/examples/#depth-buffer-plugin/
  1456. Source Code: [src/plugins/pipeline/DepthBufferPlugin.ts](./src/plugins/pipeline/DepthBufferPlugin.ts)
  1457. API Reference: [DepthBufferPlugin](https://threepipe.org/docs/classes/DepthBufferPlugin.html)
  1458. 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.
  1459. ```typescript
  1460. import {ThreeViewer, DepthBufferPlugin} from 'threepipe'
  1461. const viewer = new ThreeViewer({...})
  1462. const depthPlugin = viewer.addPluginSync(new DepthBufferPlugin(HalfFloatType))
  1463. const depthTarget = depthPlugin.target;
  1464. // Use the depth target by accesing `depthTarget.texture`.
  1465. ```
  1466. 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.
  1467. ## NormalBufferPlugin
  1468. [//]: # (todo: image)
  1469. Example: https://threepipe.org/examples/#normal-buffer-plugin/
  1470. Source Code: [src/plugins/pipeline/NormalBufferPlugin.ts](./src/plugins/pipeline/NormalBufferPlugin.ts)
  1471. API Reference: [NormalBufferPlugin](https://threepipe.org/docs/classes/NormalBufferPlugin.html)
  1472. 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.
  1473. Note: Use [`DepthNormalBufferPlugin`](#DepthNormalBufferPlugin) if using both `DepthBufferPlugin` and `NormalBufferPlugin` to render both depth and normal buffers in a single pass.
  1474. ```typescript
  1475. import {ThreeViewer, NormalBufferPlugin} from 'threepipe'
  1476. const viewer = new ThreeViewer({...})
  1477. const normalPlugin = viewer.addPluginSync(new NormalBufferPlugin())
  1478. const normalTarget = normalPlugin.target;
  1479. // Use the normal target by accessing `normalTarget.texture`.
  1480. ```
  1481. ## GBufferPlugin
  1482. todo
  1483. ## GLTFAnimationPlugin
  1484. [//]: # (todo: image)
  1485. Example: https://threepipe.org/examples/#gltf-animation-plugin/
  1486. Source Code: [src/plugins/animation/GLTFAnimationPlugin.ts](./src/plugins/animation/GLTFAnimationPlugin.ts)
  1487. API Reference: [GLTFAnimationPlugin](https://threepipe.org/docs/classes/GLTFAnimationPlugin.html)
  1488. Manages playback of GLTF animations.
  1489. The GLTF animations can be created in any 3d software that supports GLTF export like Blender.
  1490. If animations from multiple files are loaded, they will be merged in a single root object and played together.
  1491. 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.
  1492. 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.
  1493. 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
  1494. ## PopmotionPlugin
  1495. [//]: # (todo: image)
  1496. Example: https://threepipe.org/examples/#popmotion-plugin/
  1497. Source Code: [src/plugins/animation/PopmotionPlugin.ts](./src/plugins/animation/PopmotionPlugin.ts)
  1498. API Reference: [PopmotionPlugin](https://threepipe.org/docs/classes/PopmotionPlugin.html)
  1499. Provides animation/tweening capabilities to the viewer using the [popmotion.io](https://popmotion.io/) library.
  1500. Overrides the driver in popmotion to sync with the viewer and provide ways to store and stop animations.
  1501. ```typescript
  1502. import {PopmotionPlugin, ThreeViewer} from 'threepipe'
  1503. const viewer = new ThreeViewer({...})
  1504. const cube = viewer.scene.getObjectByName('cube');
  1505. const popmotion = viewer.addPluginSync(new PopmotionPlugin())
  1506. // Move the object cube 1 unit up.
  1507. const anim = popmotion.animate({
  1508. from: cube.position.y,
  1509. to: cube.position.y + 1,
  1510. duration: 500, // ms
  1511. onUpdate: (v) => {
  1512. cube.position.setY(v)
  1513. cube.setDirty()
  1514. },
  1515. onComplete: () => isMovedUp = !isMovedUp,
  1516. })
  1517. // await for animation
  1518. await anim.promise;
  1519. // or stop the animation
  1520. // anim.stop()
  1521. // Animate the color
  1522. await popmotion.animateAsync({ // Also await for the animation.
  1523. from: '#' + cube.material.color.getHexString(),
  1524. to: '#' + new Color().setHSL(Math.random(), 1, 0.5).getHexString(),
  1525. duration: 500,
  1526. onUpdate: (v) => {
  1527. cube.material.color.set(v)
  1528. cube.material.setDirty()
  1529. },
  1530. })
  1531. ```
  1532. Note: The animation is started when the animate or animateAsync function is called.
  1533. ## RenderTargetPreviewPlugin
  1534. [//]: # (todo: image)
  1535. Example: https://threepipe.org/examples/#render-target-preview/
  1536. Source Code: [src/plugins/ui/RenderTargetPreviewPlugin.ts](./src/plugins/ui/RenderTargetPreviewPlugin.ts)
  1537. API Reference: [RenderTargetPreviewPlugin](https://threepipe.org/docs/classes/RenderTargetPreviewPlugin.html)
  1538. RenderTargetPreviewPlugin is a useful development and debugging plugin that renders any registered render-target to the screen in small collapsable panels.
  1539. ```typescript
  1540. import {ThreeViewer, RenderTargetPreviewPlugin, NormalBufferPlugin} from 'threepipe'
  1541. const viewer = new ThreeViewer({...})
  1542. const normalPlugin = viewer.addPluginSync(new NormalBufferPlugin(HalfFloatType))
  1543. const previewPlugin = viewer.addPluginSync(new RenderTargetPreviewPlugin())
  1544. // Show the normal buffer in a panel
  1545. previewPlugin.addTarget(()=>normalPlugin.target, 'normal', false, false)
  1546. ```
  1547. ## GeometryUVPreviewPlugin
  1548. [//]: # (todo: image)
  1549. Example: https://threepipe.org/examples/#geometry-uv-preview/
  1550. Source Code: [src/plugins/ui/GeometryUVPreviewPlugin.ts](./src/plugins/ui/GeometryUVPreviewPlugin.ts)
  1551. API Reference: [GeometryUVPreviewPlugin](https://threepipe.org/docs/classes/GeometryUVPreviewPlugin.html)
  1552. GeometryUVPreviewPlugin is a useful development and debugging plugin
  1553. that adds a panel to the viewer to show the UVs of a geometry.
  1554. ```typescript
  1555. import {ThreeViewer, GeometryUVPreviewPlugin, SphereGeometry} from 'threepipe'
  1556. const viewer = new ThreeViewer({...})
  1557. const previewPlugin = viewer.addPluginSync(new GeometryUVPreviewPlugin())
  1558. const geometry = new SphereGeometry(1, 32, 32)
  1559. // Show the normal buffer in a panel
  1560. previewPlugin.addGeometry(geometry, 'sphere')
  1561. ```
  1562. ## FrameFadePlugin
  1563. [//]: # (todo: image)
  1564. Example: https://threepipe.org/examples/#frame-fade-plugin/
  1565. Source Code: [src/plugins/pipeline/FrameFadePlugin.ts](./src/plugins/pipeline/FrameFadePlugin.ts)
  1566. API Reference: [FrameFadePlugin](https://threepipe.org/docs/classes/FrameFadePlugin.html)
  1567. 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.
  1568. ```typescript
  1569. import {ThreeViewer, FrameFadePlugin} from 'threepipe'
  1570. const viewer = new ThreeViewer({...})
  1571. const fadePlugin = viewer.addPluginSync(new FrameFadePlugin())
  1572. // Make some changes in the scene (any visual change that needs to be faded)
  1573. // Start transition and wait for it to finish
  1574. await fadePlugin.startTransition(400) // duration in ms
  1575. ```
  1576. 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.
  1577. 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.
  1578. ## Rhino3dmLoadPlugin
  1579. Example: https://threepipe.org/examples/#rhino3dm-load/
  1580. Source Code: [src/plugins/import/Rhino3dmLoadPlugin.ts](./src/plugins/import/Rhino3dmLoadPlugin.ts)
  1581. API Reference: [Rhino3dmLoadPlugin](https://threepipe.org/docs/classes/Rhino3dmLoadPlugin.html)
  1582. 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.
  1583. ```typescript
  1584. import {Rhino3dmLoadPlugin} from 'threepipe'
  1585. viewer.addPluginSync(new Rhino3dmLoadPlugin())
  1586. const mesh = await viewer.load('file.3dm')
  1587. ```
  1588. ## PLYLoadPlugin
  1589. Example: https://threepipe.org/examples/#ply-load/
  1590. Source Code: [src/plugins/import/PLYLoadPlugin.ts](./src/plugins/import/PLYLoadPlugin.ts)
  1591. API Reference: [PLYLoadPlugin](https://threepipe.org/docs/classes/PLYLoadPlugin.html)
  1592. Adds support for loading .ply ([Polygon file format](https://en.wikipedia.org/wiki/PLY_(file_format))) files.
  1593. ```typescript
  1594. import {PLYLoadPlugin} from 'threepipe'
  1595. viewer.addPluginSync(new PLYLoadPlugin())
  1596. const mesh = await viewer.load('file.ply')
  1597. ```
  1598. ## USDZLoadPlugin
  1599. Example: https://threepipe.org/examples/#usdz-load/
  1600. Source Code: [src/plugins/import/USDZLoadPlugin.ts](./src/plugins/import/USDZLoadPlugin.ts)
  1601. API Reference: [USDZLoadPlugin](https://threepipe.org/docs/classes/USDZLoadPlugin.html)
  1602. Adds support for loading .usdz and .usda ([Universal Scene Description](https://graphics.pixar.com/usd/docs/index.html)) files.
  1603. ```typescript
  1604. import {USDZLoadPlugin} from 'threepipe'
  1605. viewer.addPluginSync(new USDZLoadPlugin())
  1606. const mesh = await viewer.load('file.usdz')
  1607. const mesh2 = await viewer.load('file.usda')
  1608. ```
  1609. ## STLLoadPlugin
  1610. Example: https://threepipe.org/examples/#stl-load/
  1611. Source Code: [src/plugins/import/STLLoadPlugin.ts](./src/plugins/import/STLLoadPlugin.ts)
  1612. API Reference: [STLLoadPlugin](https://threepipe.org/docs/classes/STLLoadPlugin.html)
  1613. Adds support for loading .stl ([Stereolithography](https://en.wikipedia.org/wiki/STL_(file_format))) files.
  1614. ```typescript
  1615. import {STLLoadPlugin} from 'threepipe'
  1616. viewer.addPluginSync(new STLLoadPlugin())
  1617. const mesh = await viewer.load('file.stl')
  1618. ```
  1619. ## KTX2LoadPlugin
  1620. Example: https://threepipe.org/examples/#ktx2-load/
  1621. Source Code: [src/plugins/import/KTX2LoadPlugin.ts](./src/plugins/import/KTX2LoadPlugin.ts)
  1622. API Reference: [KTX2LoadPlugin](https://threepipe.org/docs/classes/KTX2LoadPlugin.html)
  1623. Adds support for loading .ktx2 ([Khronos Texture](https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/) files.
  1624. 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.
  1625. ```typescript
  1626. import {KTX2LoadPlugin} from 'threepipe'
  1627. viewer.addPluginSync(new KTX2LoadPlugin())
  1628. const texture = await viewer.load('file.ktx2')
  1629. ```
  1630. ## KTXLoadPlugin
  1631. Example: https://threepipe.org/examples/#ktx-load/
  1632. Source Code: [src/plugins/import/KTXLoadPlugin.ts](./src/plugins/import/KTXLoadPlugin.ts)
  1633. API Reference: [KTXLoadPlugin](https://threepipe.org/docs/classes/KTXLoadPlugin.html)
  1634. Adds support for loading .ktx ([Khronos Texture](https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/) files.
  1635. 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.
  1636. ```typescript
  1637. import {KTXLoadPlugin} from 'threepipe'
  1638. viewer.addPluginSync(new KTXLoadPlugin())
  1639. const texture = await viewer.load('file.ktx')
  1640. ```
  1641. # @threepipe Packages
  1642. Additional plugins can be found in the [plugins](plugins/) directory.
  1643. These add support for integrating with other libraries, adding new features, and other functionality with different licenses.
  1644. ## @threepipe/plugin-tweakpane
  1645. Tewakpane UI plugin for ThreePipe
  1646. [//]: # (todo: image)
  1647. Example: https://threepipe.org/examples/#viewer-uiconfig/
  1648. Source Code: [plugins/tweakpane/src/TweakpaneUiPlugin.ts](plugins/tweakpane/src/TweakpaneUiPlugin.ts)
  1649. API Reference: [TweakpaneUiPlugin](https://threepipe.org/plugins/tweakpane/docs/classes/TweakpaneUiPlugin.html)
  1650. NPM: `npm install @threepipe/plugin-tweakpane`
  1651. CDN: https://threepipe.org/plugins/tweakpane/dist/index.mjs
  1652. TweakpaneUiPlugin adds support for using [uiconfig-tweakpane](https://github.com/repalash/uiconfig-tweakpane)
  1653. to create a configuration UI in applications using the [Tweakpane](https://cocopon.github.io/tweakpane/) library.
  1654. The plugin takes the [uiconfig](https://github.com/repalash/uiconfig.js)
  1655. that's defined in the viewer and all the objects to automatically render a UI in the browser.
  1656. ```typescript
  1657. import {IObject3D, ThreeViewer, TonemapPlugin} from 'threepipe'
  1658. import {TweakpaneUiPlugin} from '@threepipe/plugin-tweakpane'
  1659. const viewer = new ThreeViewer({...})
  1660. // Add the plugin
  1661. const plugin = viewer.addPluginSync(new TweakpaneUiPlugin(true)) // true to show expanded the UI by default
  1662. // Add the UI for the viewer
  1663. plugin.appendChild(viewer.uiConfig)
  1664. // Add UI for some plugins
  1665. plugin.setupPlugins(TonemapPlugin, DropzonePlugin)
  1666. ```
  1667. ## @threepipe/plugin-tweakpane-editor
  1668. Tweakpane Editor Plugin for ThreePipe
  1669. [//]: # (todo: image)
  1670. Example: https://threepipe.org/examples/#tweakpane-editor/
  1671. Source Code: [plugins/tweakpane-editor/src/TweakpaneEditorPlugin.ts](plugins/tweakpane-editor/src/TweakpaneEditorPlugin.ts)
  1672. API Reference: [TweakpaneEditorPlugin](https://threepipe.org/plugins/tweakpane-editor/docs/classes/TweakpaneEditorPlugin.html)
  1673. NPM: `npm install @threepipe/plugin-tweakpane-editor`
  1674. CDN: https://threepipe.org/plugins/tweakpane-editor/dist/index.mjs
  1675. TweakpaneEditorPlugin uses TweakpaneUiPlugin to create an editor for editing viewer,
  1676. plugins, model and material configurations in the browser.
  1677. ```typescript
  1678. import {IObject3D, ThreeViewer, TonemapPlugin} from 'threepipe'
  1679. import {TweakpaneEditorPlugin} from '@threepipe/plugin-tweakpane-editor'
  1680. const viewer = new ThreeViewer({...})
  1681. viewer.addPluginSync(new TweakpaneUiPlugin(true))
  1682. const editor = viewer.addPluginSync(new TweakpaneEditorPlugin())
  1683. // Add some plugins to the viewer
  1684. await viewer.addPlugins([
  1685. new ViewerUiConfigPlugin(),
  1686. // new SceneUiConfigPlugin(), // this is already in ViewerUiPlugin
  1687. new DepthBufferPlugin(HalfFloatType, true, true),
  1688. new NormalBufferPlugin(HalfFloatType, false),
  1689. new RenderTargetPreviewPlugin(false),
  1690. ])
  1691. // Load the plugin UI in the editor and tweakpane ui with categories.
  1692. editor.loadPlugins({
  1693. ['Viewer']: [ViewerUiConfigPlugin, SceneUiConfigPlugin, DropzonePlugin, FullScreenPlugin],
  1694. ['GBuffer']: [DepthBufferPlugin, NormalBufferPlugin],
  1695. ['Post-processing']: [TonemapPlugin],
  1696. ['Debug']: [RenderTargetPreviewPlugin],
  1697. })
  1698. ```
  1699. ## @threepipe/plugin-extra-importers
  1700. Exports several plugins to add support for various file types.
  1701. Example: https://threepipe.org/examples/#extra-importer-plugins/
  1702. Source Code: [plugins/extra-importers/src/index.ts](plugins/extra-importers/src/index.ts)
  1703. API Reference: [@threepipe/plugin-extra-importers](https://threepipe.org/plugins/extra-importers/docs)
  1704. NPM: `npm install @threepipe/plugin-extra-importers`
  1705. CDN: https://threepipe.org/plugins/extra-importers/dist/index.mjs
  1706. This package exports several plugins to add support for several file types using the following plugins
  1707. - [TDSLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/TDSLoadPlugin.html) - Load 3DS Max (.3ds) files
  1708. - [ThreeMFLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/ThreeMFLoadPlugin.html) - Load 3MF (.3mf) files
  1709. - [ColladaLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/ColladaLoadPlugin.html) - Load Collada (.dae) files
  1710. - [AMFLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/AMFLoadPlugin.html) - Load AMF (.amf) files
  1711. - [BVHLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/BVHLoadPlugin.html) - Load BVH (.bvh) files
  1712. - [VOXLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/VOXLoadPlugin.html) - Load MagicaVoxel (.vox) files
  1713. - [GCodeLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/GCodeLoadPlugin.html) - Load GCode (.gcode) files
  1714. - [MDDLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/MDDLoadPlugin.html) - Load MDD (.mdd) files
  1715. - [PCDLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/PCDLoadPlugin.html) - Load Point cloud data (.pcd) files
  1716. - [TiltLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/TiltLoadPlugin.html) - Load Tilt Brush (.tilt) files
  1717. - [VRMLLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/VRMLLoadPlugin.html) - Load VRML (.wrl) files
  1718. - [MPDLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/MPDLoadPlugin.html) - Load LDraw (.mpd) files
  1719. - [VTKLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/VTKLoadPlugin.html) - Load VTK (.vtk) files
  1720. - [XYZLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/XYZLoadPlugin.html) - Load XYZ (.xyz) files
  1721. To add all the plugins at once use `extraImporters`. This adds support for loading all the above file types.
  1722. ```typescript
  1723. import {ThreeViewer} from 'threepipe'
  1724. import {extraImporters} from '@threepipe/plugin-extra-importers'
  1725. const viewer = new ThreeViewer({...})
  1726. viewer.addPluginsSync(extraImporters)
  1727. // Now load any file as is.
  1728. const model = await viewer.load<IObject3D>('file.3mf')
  1729. // To load the file as a data url, use the correct mimetype
  1730. const model1 = await viewer.load<IObject3D>('data:model/3mf;base64,...')
  1731. ```
  1732. Remove the `<IObject3D>` if using javascript and not typescript.