소스 검색

Add website/wiki

master
Palash Bansal 1 년 전
부모
커밋
5b4d35c334
No account linked to committer's email address
85개의 변경된 파일6754개의 추가작업 그리고 34개의 파일을 삭제
  1. 2
    1
      .github/workflows/deploy-pages.yml
  2. 3
    1
      .gitignore
  3. 928
    29
      package-lock.json
  4. 7
    3
      package.json
  5. 218
    0
      website/.vitepress/config.ts
  6. 20
    0
      website/.vitepress/theme/custom.css
  7. 5
    0
      website/.vitepress/theme/index.js
  8. 139
    0
      website/guide/core-plugins.md
  9. 25
    0
      website/guide/editors.md
  10. 177
    0
      website/guide/exporting-files.md
  11. 191
    0
      website/guide/features.md
  12. 218
    0
      website/guide/getting-started.md
  13. 143
    0
      website/guide/introduction.md
  14. 244
    0
      website/guide/loading-files.md
  15. 68
    0
      website/guide/material-extension.md
  16. 130
    0
      website/guide/plugin-system.md
  17. 100
    0
      website/guide/render-pipeline.md
  18. 134
    0
      website/guide/serialization.md
  19. 31
    0
      website/guide/threepipe-packages.md
  20. 126
    0
      website/guide/ui-config.md
  21. 1014
    0
      website/guide/viewer-api.md
  22. 102
    0
      website/index.md
  23. 50
    0
      website/package/plugin-blend-importer.md
  24. 47
    0
      website/package/plugin-blueprintjs.md
  25. 73
    0
      website/package/plugin-configurator.md
  26. 58
    0
      website/package/plugin-gaussian-splatting.md
  27. 61
    0
      website/package/plugin-geometry-generator.md
  28. 49
    0
      website/package/plugin-gltf-transform.md
  29. 128
    0
      website/package/plugin-network.md
  30. 67
    0
      website/package/plugin-svg-renderer.md
  31. 55
    0
      website/package/plugin-tweakpane-editor.md
  32. 44
    0
      website/package/plugin-tweakpane.md
  33. 58
    0
      website/package/plugins-extra-importers.md
  34. 46
    0
      website/plugin/AssetExporterPlugin.md
  35. 75
    0
      website/plugin/CameraViewPlugin.md
  36. 55
    0
      website/plugin/CanvasSnapshotPlugin.md
  37. 32
    0
      website/plugin/ChromaticAberrationPlugin.md
  38. 45
    0
      website/plugin/ClearcoatTintPlugin.md
  39. 32
    0
      website/plugin/ContactShadowGroundPlugin.md
  40. 45
    0
      website/plugin/CustomBumpMapPlugin.md
  41. 34
    0
      website/plugin/DepthBufferPlugin.md
  42. 41
    0
      website/plugin/DeviceOrientationControlsPlugin.md
  43. 54
    0
      website/plugin/DropzonePlugin.md
  44. 33
    0
      website/plugin/EditorViewWidgetPlugin.md
  45. 23
    0
      website/plugin/FileTransferPlugin.md
  46. 33
    0
      website/plugin/FilmicGrainPlugin.md
  47. 46
    0
      website/plugin/FragmentClippingExtensionPlugin.md
  48. 38
    0
      website/plugin/FrameFadePlugin.md
  49. 37
    0
      website/plugin/FullScreenPlugin.md
  50. 32
    0
      website/plugin/GBufferPlugin.md
  51. 29
    0
      website/plugin/GLTFAnimationPlugin.md
  52. 48
    0
      website/plugin/GLTFKHRMaterialVariantsPlugin.md
  53. 27
    0
      website/plugin/GLTFMeshOptDecodePlugin.md
  54. 33
    0
      website/plugin/GeometryUVPreviewPlugin.md
  55. 45
    0
      website/plugin/HDRiGroundPlugin.md
  56. 51
    0
      website/plugin/InteractionPromptPlugin.md
  57. 27
    0
      website/plugin/KTX2LoadPlugin.md
  58. 27
    0
      website/plugin/KTXLoadPlugin.md
  59. 39
    0
      website/plugin/LoadingScreenPlugin.md
  60. 24
    0
      website/plugin/MeshOptSimplifyModifierPlugin.md
  61. 44
    0
      website/plugin/NoiseBumpMaterialPlugin.md
  62. 36
    0
      website/plugin/NormalBufferPlugin.md
  63. 65
    0
      website/plugin/Object3DGeneratorPlugin.md
  64. 51
    0
      website/plugin/Object3DWidgetsPlugin.md
  65. 25
    0
      website/plugin/PLYLoadPlugin.md
  66. 45
    0
      website/plugin/ParallaxMappingPlugin.md
  67. 79
    0
      website/plugin/PickingPlugin.md
  68. 41
    0
      website/plugin/PointerLockControlsPlugin.md
  69. 75
    0
      website/plugin/PopmotionPlugin.md
  70. 21
    0
      website/plugin/ProgressivePlugin.md
  71. 33
    0
      website/plugin/RenderTargetPreviewPlugin.md
  72. 32
    0
      website/plugin/Rhino3dmLoadPlugin.md
  73. 33
    0
      website/plugin/SSAAPlugin.md
  74. 43
    0
      website/plugin/SSAOPlugin.md
  75. 25
    0
      website/plugin/STLLoadPlugin.md
  76. 34
    0
      website/plugin/SimplifyModifierPlugin.md
  77. 37
    0
      website/plugin/ThreeFirstPersonControlsPlugin.md
  78. 23
    0
      website/plugin/TonemapPlugin.md
  79. 69
    0
      website/plugin/TransformAnimationPlugin.md
  80. 37
    0
      website/plugin/TransformControlsPlugin.md
  81. 26
    0
      website/plugin/USDZLoadPlugin.md
  82. 36
    0
      website/plugin/VignettePlugin.md
  83. 45
    0
      website/plugin/VirtualCamerasPlugin.md
  84. BIN
      website/public/favicon.ico
  85. 33
    0
      website/public/logo.svg

+ 2
- 1
.github/workflows/deploy-pages.yml 파일 보기

@@ -45,7 +45,8 @@ jobs:
- run: npm ci # this will also run `npm run prepare` which will build # todo use --cache .npm
- run: npm run docs
- run: mkdir _site
- run: mv -t _site src docs dist examples README.md LICENSE index.html
- run: mv -t _site src docs dist examples README.md LICENSE
- run: cp -r website/.vitepress/dist/* _site
- run: mkdir -p _site/plugins
- run: find plugins -maxdepth 2 -type d \( -name dist -o -name docs -o -name src \) -exec sh -c "mkdir -p _site/{} && cp -r {} _site/{}/.." \;
- name: Setup Pages

+ 3
- 1
.gitignore 파일 보기

@@ -1,7 +1,6 @@
dist
lib
docs
/index.html
examples/**/*.js
examples/**/*.js.map

@@ -66,3 +65,6 @@ typings/

# next.js build output
.next

website/.vitepress/dist
website/.vitepress/cache

+ 928
- 29
package-lock.json
파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
파일 보기


+ 7
- 3
package.json 파일 보기

@@ -22,12 +22,15 @@
"dev-examples": "tsc --project examples/tsconfig.build.json -w",
"serve-docs": "ws -d docs -p 8080",
"serve": "ws -d . -p 9229",
"docs": "npx typedoc && markdown-to-html",
"docs": "npx typedoc && npm run website:build",
"docs-plugins": "node scripts/each-plugin.mjs run docs",
"docs-all": "npm run docs && npm run docs-plugins",
"build-plugins": "node scripts/each-plugin.mjs install",
"prepare": "npm run build && npm run build-plugins && npm run build-examples",
"update-version": "node scripts/update-version.mjs"
"update-version": "node scripts/update-version.mjs",
"website:dev": "vitepress dev website",
"website:build": "vitepress build website",
"website:preview": "vitepress preview website"
},
"clean-package": {
"remove": [
@@ -109,7 +112,8 @@
"typescript": "^5.3.3",
"typescript-plugin-css-modules": "^5.0.1",
"vite": "^5.3.5",
"vite-plugin-dts": "^3.7.0"
"vite-plugin-dts": "^3.7.0",
"vitepress": "^1.3.2"
},
"dependencies": {
"@types/three": "https://github.com/repalash/three-ts-types/releases/download/v0.153.1002/package.tgz",

+ 218
- 0
website/.vitepress/config.ts 파일 보기

@@ -0,0 +1,218 @@
import {defineConfig} from 'vitepress'

// https://vitepress.dev/reference/site-config
export default defineConfig({
title: "ThreePipe",
description: "Effortlessly create 3D web experiences, from quick demos to advanced applications, with Three.js",
themeConfig: {
logo: '/logo.svg',
outline: 'deep',

// https://vitepress.dev/reference/default-theme-config
nav: [
{ text: 'Home', link: '/' },
{ text: 'Examples', link: 'https://threepipe.org/examples' },
{ text: '3D Editor', link: 'https://editor.threepipe.org' },
{ text: 'API Reference', link: 'https://threepipe.org/docs' }
],

sidebar: [
{
text: 'Introduction', collapsed: false,
items: [
{text: 'What is Threepipe?', link: 'guide/introduction'},
{text: 'Getting Started', link: 'guide/getting-started'},
{text: 'Threepipe Editors', link: 'guide/editors'},
{text: 'Features', link: 'guide/features'},
{text: 'Viewer API', link: 'guide/viewer-api'},
{text: 'Core Plugins', link: 'guide/core-plugins'},
{text: '@threepipe Packages', link: 'guide/threepipe-package'},
]
},
{
text: 'Guides', collapsed: false,
items: [
{text: 'Loading Files', link: 'guide/loading-files'},
{text: 'Exporting Files', link: 'guide/exporting-files'},
{text: 'Render Pipeline', link: 'guide/render-pipeline'},
{text: 'Material Extension', link: 'guide/material-extension'},
{text: 'UI Configuration', link: 'guide/ui-config'},
{text: 'Serialization', link: 'guide/serialization'},
{text: 'Plugin System', link: 'guide/plugin-system'},
]
},
{
text: 'Core Plugins', collapsed: false,
items: [
{
text: 'Import', collapsed: true,
items: [
{text: 'Rhino3dmLoadPlugin', link: 'plugin/Rhino3dmLoadPlugin'},
{text: 'PLYLoadPlugin', link: 'plugin/PLYLoadPlugin'},
{text: 'STLLoadPlugin', link: 'plugin/STLLoadPlugin'},
{text: 'KTX2LoadPlugin', link: 'plugin/KTX2LoadPlugin'},
{text: 'KTXLoadPlugin', link: 'plugin/KTXLoadPlugin'},
{text: 'USDZLoadPlugin', link: 'plugin/USDZLoadPlugin'},
{text: 'GLTFMeshOptDecodePlugin', link: 'plugin/GLTFMeshOptDecodePlugin'},
],
},
{
text: 'Post-processing', collapsed: true,
items: [
{text: 'TonemapPlugin', link: 'plugin/TonemapPlugin'},
{text: 'VignettePlugin', link: 'plugin/VignettePlugin'},
{text: 'ChromaticAberrationPlugin', link: 'plugin/ChromaticAberrationPlugin'},
{text: 'FilmicGrainPlugin', link: 'plugin/FilmicGrainPlugin'},
],
},
{
text: 'Rendering Pipeline', collapsed: true,
items: [
{text: 'ProgressivePlugin', link: 'plugin/ProgressivePlugin'},
{text: 'SSAAPlugin', link: 'plugin/SSAAPlugin'},
{text: 'DepthBufferPlugin', link: 'plugin/DepthBufferPlugin'},
{text: 'NormalBufferPlugin', link: 'plugin/NormalBufferPlugin'},
{text: 'GBufferPlugin', link: 'plugin/GBufferPlugin'},
{text: 'SSAOPlugin', link: 'plugin/SSAOPlugin'},
{text: 'FrameFadePlugin', link: 'plugin/FrameFadePlugin'},
],
},
{
text: 'Interaction', collapsed: true,
items: [
{text: 'DropzonePlugin', link: 'plugin/DropzonePlugin'},
{text: 'PickingPlugin', link: 'plugin/PickingPlugin'},
{text: 'LoadingScreenPlugin', link: 'plugin/LoadingScreenPlugin'},
{text: 'FullScreenPlugin', link: 'plugin/FullScreenPlugin'},
{text: 'InteractionPromptPlugin', link: 'plugin/InteractionPromptPlugin'},
{text: 'TransformControlsPlugin', link: 'plugin/TransformControlsPlugin'},
{text: 'EditorViewWidgetPlugin', link: 'plugin/EditorViewWidgetPlugin'},
{text: 'DeviceOrientationControlsPlugin', link: 'plugin/DeviceOrientationControlsPlugin'},
{text: 'PointerLockControlsPlugin', link: 'plugin/PointerLockControlsPlugin'},
{text: 'ThreeFirstPersonControlsPlugin', link: 'plugin/ThreeFirstPersonControlsPlugin'},
],
},
{
text: 'Animation', collapsed: true,
items: [
{text: 'GLTFAnimationPlugin', link: 'plugin/GLTFAnimationPlugin'},
{text: 'PopmotionPlugin', link: 'plugin/PopmotionPlugin'},
{text: 'CameraViewPlugin', link: 'plugin/CameraViewPlugin'},
{text: 'TransformAnimationPlugin', link: 'plugin/TransformAnimationPlugin'},
],
},
{
text: 'Material', collapsed: true,
items: [
{text: 'NoiseBumpMaterialPlugin', link: 'plugin/NoiseBumpMaterialPlugin'},
{text: 'CustomBumpMapPlugin', link: 'plugin/CustomBumpMapPlugin'},
{text: 'ClearcoatTintPlugin', link: 'plugin/ClearcoatTintPlugin'},
{text: 'FragmentClippingExtensionPlugin', link: 'plugin/FragmentClippingExtensionPlugin'},
{text: 'ParallaxMappingPlugin', link: 'plugin/ParallaxMappingPlugin'},
],
},
{
text: 'Export', collapsed: true,
items: [
{text: 'CanvasSnapshotPlugin', link: 'plugin/CanvasSnapshotPlugin'},
{text: 'AssetExporterPlugin', link: 'plugin/AssetExporterPlugin'},
{text: 'FileTransferPlugin', link: 'plugin/FileTransferPlugin'},
],
},
{
text: 'Extras', collapsed: true,
items: [
{text: 'ContactShadowGroundPlugin', link: 'plugin/ContactShadowGroundPlugin'},
{text: 'HDRiGroundPlugin', link: 'plugin/HDRiGroundPlugin'},
{text: 'VirtualCamerasPlugin', link: 'plugin/VirtualCamerasPlugin'},
{text: 'Object3DWidgetsPlugin', link: 'plugin/Object3DWidgetsPlugin'},
{text: 'Object3DGeneratorPlugin', link: 'plugin/Object3DGeneratorPlugin'},
{text: 'GLTFKHRMaterialVariantsPlugin', link: 'plugin/GLTFKHRMaterialVariantsPlugin'},
{text: 'SimplifyModifierPlugin', link: 'plugin/SimplifyModifierPlugin'},
{text: 'MeshOptSimplifyModifierPlugin', link: 'plugin/MeshOptSimplifyModifierPlugin'},
],
},
{
text: 'Configurator', collapsed: true,
items: [
{text: 'MaterialConfiguratorBasePlugin', link: 'plugin/MaterialConfiguratorBasePlugin'},
{text: 'SwitchNodeBasePlugin', link: 'plugin/SwitchNodeBasePlugin'},
],
},
{
text: 'UI', collapsed: true,
items: [
{text: 'RenderTargetPreviewPlugin', link: 'plugin/RenderTargetPreviewPlugin'},
{text: 'GeometryUVPreviewPlugin', link: 'plugin/GeometryUVPreviewPlugin'},
{text: 'SceneUiConfigPlugin', link: 'plugin/SceneUiConfigPlugin'},
{text: 'ViewerUiConfigPlugin', link: 'plugin/ViewerUiConfigPlugin'},
],
},
{
text: 'Base', collapsed: true,
items: [
{text: 'AAssetManagerProcessStatePlugin', link: 'plugin/AAssetManagerProcessStatePlugin'},
{text: 'ACameraControlsPlugin', link: 'plugin/ACameraControlsPlugin'},
{text: 'BaseGroundPlugin', link: 'plugin/BaseGroundPlugin'},
{text: 'BaseImporterPlugin', link: 'plugin/BaseImporterPlugin'},
{text: 'PipelinePassPlugin', link: 'plugin/PipelinePassPlugin'},
{text: 'AScreenPassExtensionPlugin', link: 'plugin/AScreenPassExtensionPlugin'},
],
},
]
},
{
text: 'Packages', collapsed: false,
items: [
{text: 'Tweakpane Plugin', link: 'package/plugin-tweakpane'},
{text: 'Blueprint.js Plugin', link: 'package/plugin-blueprintjs'},
{text: 'Tweakpane Editor Plugin', link: 'package/plugin-tweakpane-editor'},
{text: 'Configurator Plugins', link: 'package/plugin-configurator'},
{text: 'Network Plugin', link: 'package/plugin-network'},
{text: 'Geometry Generator Plugin', link: 'package/plugin-geometry-generator'},
{text: 'glTF Transform Plugin', link: 'package/plugin-gltf-transform'},
{text: 'svg-renderer Plugin', link: 'package/plugin-svg-renderer'},
{text: 'Extra Importers Plugins', link: 'package/plugins-extra-importers'},
{text: 'Gaussian Splatting Plugin', link: 'package/plugin-gaussian-splatting'},
{text: 'Blend Importer Plugin', link: 'package/plugin-blend-importer'},
]
},
],

socialLinks: [
{ icon: 'github', link: 'https://github.com/repalash/threepipe' },
{ icon: 'twitter', link: 'https://twitter.com/repalash' }
],

footer: {
message: 'ThreePipe - Make 3D applications on the web',
copyright: 'Copyright © 2023-present, <a href="https://repalash.com/">repalash</a>. All rights reserved.',
},


// https://vitepress.dev/reference/default-theme-search#minisearch-options
search: {
provider: 'local',
options: {
miniSearch: {
/**
* @type {Pick<import('minisearch').Options, 'extractField' | 'tokenize' | 'processTerm'>}
*/
options: {
/* ... */
},
/**
* @type {import('minisearch').SearchOptions}
* @default
* { fuzzy: 0.2, prefix: true, boost: { title: 4, text: 2, titles: 1 } }
*/
searchOptions: {
/* ... */
}
}
}
},


}
})

+ 20
- 0
website/.vitepress/theme/custom.css 파일 보기

@@ -0,0 +1,20 @@
:root {
--vp-home-hero-name-color: transparent;
--vp-home-hero-name-background: -webkit-linear-gradient(120deg, #ec630a, #ecae86);

--vp-c-orange-1: #ec630a;
--vp-c-orange-2: #e56819;
--vp-c-orange-3: #e16e37;
--vp-c-orange-soft: rgba(236, 99, 10, 0.14);

--vp-c-brand-1: var(--vp-c-orange-1);
--vp-c-brand-2: var(--vp-c-orange-2);
--vp-c-brand-3: var(--vp-c-orange-3);
--vp-c-brand-soft: var(--vp-c-orange-soft);

--vp-c-tip-1: var(--vp-c-green-1);
--vp-c-tip-2: var(--vp-c-green-2);
--vp-c-tip-3: var(--vp-c-green-3);
--vp-c-tip-soft: var(--vp-c-green-soft);

}

+ 5
- 0
website/.vitepress/theme/index.js 파일 보기

@@ -0,0 +1,5 @@
// .vitepress/theme/index.js
import DefaultTheme from 'vitepress/theme'
import './custom.css'

export default DefaultTheme

+ 139
- 0
website/guide/core-plugins.md 파일 보기

@@ -0,0 +1,139 @@
---
prev:
text: 'Viewer API'
link: './viewer-api'

next:
text: '@threepipe Packages'
link: './threepipe-packages'
---

# Core Plugins

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.

Plugins can be added to the viewer at any time and can be removed using the `removePlugin` and `removePluginSync` methods.

There are built-in plugins provided in the core of threepipe, that can be directly added to the viewer to add new features. These plugins are designed to be modular and can be used independently or in combination with other plugins. They also serve as good examples and starting points for creating custom plugins.

All of the plugins are configurable, serializable and expose a UI to control their properties.

Checkout the [model-viewer](https://threepipe.org/examples/#model-viewer) or [tweakpane-editor](https://threepipe.org/examples/#tweakpane-editor) examples which use most of these plugins.

More plugins are available as separate packages, check the [@threepipe Packages](./threepipe-packages) page for more details.

## Rendering Pipeline

Plugins configuring the rendering pipeline and providing resources for other plugins, effects.

- [ProgressivePlugin](../plugin/ProgressivePlugin) - Post-render pass to blend the last frame with the current frame. Used for progressive rendering. It's a dependency for several other plugins.
- [SSAAPlugin](../plugin/SSAAPlugin) - Add Super Sample Anti-Aliasing across frames by applying jitter to the camera.
- [DepthBufferPlugin](../plugin/DepthBufferPlugin) - Pre-rendering of depth buffer. The buffer can be used in materials and post-processing effects.
- [NormalBufferPlugin](../plugin/NormalBufferPlugin) - Pre-rendering of normal buffer. The buffer can be used in materials and post-processing effects.
- [GBufferPlugin](../plugin/GBufferPlugin) - Pre-rendering of depth-normal and flags buffers in a single pass. This is a dependency to several post-processing plugins.
- [SSAOPlugin](../plugin/SSAOPlugin) - Extends the render pipeline to add SSAO(Screen Space Ambient Occlusion) for physical materials in the scene.
- [FrameFadePlugin](../plugin/FrameFadePlugin) - Post-render pass to smoothly fade to a new rendered frame over time. Used by the core and several plugins like configurators.

## Import

Plugins to add importers/loaders for different file formats.

- [Rhino3dmLoadPlugin](../plugin/Rhino3dmLoadPlugin) - Add support for loading .3dm files
- [PLYLoadPlugin](../plugin/PLYLoadPlugin) - Add support for loading .ply files
- [STLLoadPlugin](../plugin/STLLoadPlugin) - Add support for loading .stl files
- [KTX2LoadPlugin](../plugin/KTX2LoadPlugin) - Add support for loading .ktx2 files
- [KTXLoadPlugin](../plugin/KTXLoadPlugin) - Add support for loading .ktx files
- [USDZLoadPlugin](../plugin/USDZLoadPlugin) - Add support for loading .usdz files
- [GLTFMeshOptDecodePlugin](../plugin/GLTFMeshOptDecodePlugin) - Decode gltf files with EXT_meshopt_compression extension.

## Post-processing

Plugins to add basic post-processing effects to the final screen pass.

Check packages for more advanced post-processing effects.

- [TonemapPlugin](../plugin/TonemapPlugin) - Add tonemap to the final screen pass. Added to the viewer by default.
- [VignettePlugin](../plugin/VignettePlugin) - Add Vignette effect by patching the final screen pass
- [ChromaticAberrationPlugin](../plugin/ChromaticAberrationPlugin) - Add Chromatic Aberration effect by patching the final screen pass
- [FilmicGrainPlugin](../plugin/FilmicGrainPlugin) - Add Filmic Grain effect by patching the final screen pass

## Interaction

Plugins to add/configure interaction and user editable elements to the viewer.

- [DropzonePlugin](../plugin/DropzonePlugin) - Drag and drop local files to import and automatically load. Also provides hooks for custom processing.
- [PickingPlugin](../plugin/PickingPlugin) - Adds support for selecting objects in the viewer with user interactions(click and hover) and shows selection widgets.
- [LoadingScreenPlugin](../plugin/LoadingScreenPlugin) - Shows a configurable loading screen overlay over the canvas which can be extended to show a loader during any kind of processing.
- [FullScreenPlugin](../plugin/FullScreenPlugin) - Provides helpers for entering the fullscreen mode in browsers.
- [InteractionPromptPlugin](../plugin/InteractionPromptPlugin) - Adds an animated hand icon over canvas and rotates the camera to prompt the user to interact.
- [TransformControlsPlugin](../plugin/TransformControlsPlugin) - Adds support for moving, rotating and scaling objects in the viewer with interactive widgets
- [EditorViewWidgetPlugin](../plugin/EditorViewWidgetPlugin) - Adds an interactive ViewHelper/AxisHelper that syncs with the main camera.
- [DeviceOrientationControlsPlugin](../plugin/DeviceOrientationControlsPlugin) - Adds a controlsMode to the mainCamera for device orientation controls(gyroscope rotation control).
- [PointerLockControlsPlugin](../plugin/PointerLockControlsPlugin) - Adds a controlsMode to the mainCamera for pointer lock controls.
- [ThreeFirstPersonControlsPlugin](../plugin/ThreeFirstPersonControlsPlugin) - Adds a controlsMode to the mainCamera for first person controls from threejs.

## Animation

Plugins to add support for animations and animation controls.

- [GLTFAnimationPlugin](../plugin/GLTFAnimationPlugin) - Add support for playing and seeking gltf animations
- [PopmotionPlugin](../plugin/PopmotionPlugin) - Integrates with popmotion.io library for animation/tweening
- [CameraViewPlugin](../plugin/CameraViewPlugin) - Add support for saving, loading, animating, looping between camera views
- [TransformAnimationPlugin](../plugin/TransformAnimationPlugin) - Add support for saving, loading, animating, between object transforms

## Material

Plugins to add support for custom materials and material extensions for existing materials.

- [NoiseBumpMaterialPlugin](../plugin/NoiseBumpMaterialPlugin) - Sparkle Bump/Noise Bump material extension for PhysicalMaterial
- [CustomBumpMapPlugin](../plugin/CustomBumpMapPlugin) - Custom Bump Map material extension for PhysicalMaterial
- [ClearcoatTintPlugin](../plugin/ClearcoatTintPlugin) - Clearcoat Tint material extension for PhysicalMaterial
- [FragmentClippingExtensionPlugin](../plugin/FragmentClippingExtensionPlugin) - Fragment/SDF Clipping material extension for PhysicalMaterial
- [ParallaxMappingPlugin](../plugin/ParallaxMappingPlugin) - Relief Parallax Bump Mapping extension for PhysicalMaterial

## Export

Plugins to configure export options and methods for different file formats.

- [CanvasSnapshotPlugin](../plugin/CanvasSnapshotPlugin) - Add support for taking snapshots of the canvas.
- [AssetExporterPlugin](../plugin/AssetExporterPlugin) - Provides helper options, methods and ui config to export the scene, object GLB or Viewer Configuration.
- [FileTransferPlugin](../plugin/FileTransferPlugin) - Provides a way to extend the viewer.export functionality with custom actions.

## Extras

- [ContactShadowGroundPlugin](../plugin/ContactShadowGroundPlugin) - Adds a ground plane at runtime with contact shadows
- [HDRiGroundPlugin](../plugin/HDRiGroundPlugin) - Add support for ground projected hdri/skybox to the webgl background shader.
- [VirtualCamerasPlugin](../plugin/VirtualCamerasPlugin) - Add support for rendering virtual cameras before the main one every frame.
- [Object3DWidgetsPlugin](../plugin/Object3DWidgetsPlugin) - Automatically create light and camera helpers/gizmos when they are added to the scene.
- [Object3DGeneratorPlugin](../plugin/Object3DGeneratorPlugin) - Provides UI and API to create scene objects like lights, cameras, meshes, etc.
- [GLTFKHRMaterialVariantsPlugin](../plugin/GLTFKHRMaterialVariantsPlugin) - Support using for variants from KHR_materials_variants extension in gltf models.
- [SimplifyModifierPlugin](../plugin/SimplifyModifierPlugin) - Boilerplate for plugin to simplify geometries
- [MeshOptSimplifyModifierPlugin](../plugin/MeshOptSimplifyModifierPlugin) - Simplify geometries using meshoptimizer library

## UI

Plugins related UI, plugins creating UI element. Check the [packages](./threepipe-packages) page for UI config rendering plugins.

- [RenderTargetPreviewPlugin](../plugin/RenderTargetPreviewPlugin) - Preview any render target in a UI panel over the canvas
- [GeometryUVPreviewPlugin](../plugin/GeometryUVPreviewPlugin) - Preview UVs of any geometry in a UI panel over the canvas
- [SceneUiConfigPlugin](https://threepipe.org/docs/classes/SceneUiConfigPlugin.html) - A dummy plugin to show only the scene ui config using any UI plugin
- [ViewerUiConfigPlugin](https://threepipe.org/docs/classes/ViewerUiConfigPlugin.html) - A dummy plugin to show only the viewer ui config using any UI plugin

## Base

Base plugins that can be inherited to create new plugins for specific use cases.

- [AAssetManagerProcessStatePlugin](https://threepipe.org/docs/classes/AAssetManagerProcessStatePlugin.html) - Base class to create loading bars, process state related plugins.
- [ACameraControlsPlugin](https://threepipe.org/docs/classes/ACameraControlsPlugin.html) - Base class that adds camera controls to the viewer.
- [BaseGroundPlugin](https://threepipe.org/docs/classes/BaseGroundPlugin.html) - Base class that adds a ground plane to the viewer.
- [BaseImporterPlugin](https://threepipe.org/docs/classes/BaseImporterPlugin.html) - Base class that registers an importer to the viewer.
- [PipelinePassPlugin](https://threepipe.org/docs/classes/PipelinePassPlugin.html) - Base class that registers a pass to the main render pipeline.
- [AScreenPassExtensionPlugin](https://threepipe.org/docs/classes/AScreenPassExtensionPlugin.html) - Create plugins that adds an extension to screen pass in the render manager.

## Configurator

Base plugins for creating configurators. These include the functionality, serialization and state management and UI can be added but any subclass or in the application.

- [MaterialConfiguratorBasePlugin](https://threepipe.org/docs/classes/MaterialConfiguratorBasePlugin.html) - Base class to create material configurator plugins.
- [SwitchNodeBasePlugin](https://threepipe.org/docs/classes/SwitchNodeBasePlugin.html) - Base class to create switch node plugins.


+ 25
- 0
website/guide/editors.md 파일 보기

@@ -0,0 +1,25 @@
---
prev:
text: 'Getting Started'
link: './getting-started'

next:
text: 'Features'
link: './features'
---

# Editors in Threepipe

Threepipe provides a set of editors to create, edit and configure 3D scenes in the browser. These editors are built on top of the core framework(as plugins) and provide a simple and intuitive way to interact with the 3D scene, materials, lights, cameras, and other objects.

The editors render `uiConfig` from the viewer, scene, and plugins along with several custom UI elements to provide a completely dynamic and extendable interface.

A common workflow is drop a 3d model into the editor, enable the required plugins, set proper lighting, background, environment maps, set plugin properties like post-processing settings, materials, animations, camera views etc, and export a compressed glb file with scene settings and plugin data. This glb file can then be loaded into the viewer(with all the plugins) to get the same scene and settings.

## Tweakpane Editor

[Tweakpane Editor](https://threepipe.org/examples/tweakpane-editor/) - A simple editor to simply tweak the scene and plugins. It provides a tab-bar to manage different plugin categories. It is built on top of the [Tweakpane](https://cocopon.github.io/tweakpane/) library with custom themes. This can be quickly added to any apps as a debug UI, to create scenes, presets etc.

## Threepipe Editor

[Threepipe Editor](https://editor.threepipe.org) - A more advanced editor to create, edit and configure 3D scenes in the browser. It provides a more traditional style of editor with a sidebar to manage different objects and properties and toolbars with tools managing various plugins. This is used to create and setup full scenes, configurators and experiences. It is built on top of the [React](https://react.dev) and [Blueprint.js](https://blueprintjs.com/) libraries.

+ 177
- 0
website/guide/exporting-files.md 파일 보기

@@ -0,0 +1,177 @@
---
prev:
text: 'Loading Files'
link: './loading-files'

next:
text: 'Render Pipeline'
link: './render-pipeline'
---

# Exporting files

Threepipe has support for exporting various asset type with AssetManager, as well as support to export viewer and plugin configuration, arbitrary objects etc using the [serialization](#serialization) system.

[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.

AssetManager internally uses [AssetExporter](https://threepipe.org/docs/classes/AssetExporter.html) to export files.
AssetExporter includes some basic exporters for glb, exr, textures,
and materials and a system to register exporters for different file types with plugins or custom exporters.

## Exporting 3D models

Export the root scene as glb
```typescript
const blob = await viewer.exportScene({
viewerConfig: true, // default = true. export all viewer and plugin configuration. if false only the model root object is exported.
})
// download the file
downloadBlob(blob, 'scene.glb')
```

Export a single object from the scene as glb
```typescript
const object = viewer.scene.getObjectByName('objectName');
const glb: Blob = await viewer.export(object, {
exportExt: 'glb', // default = glb for models
embedUrlImages: true, // default = false. embed images in glb even when url is available.
})
// download the file
downloadBlob(glb, 'object.glb')
```

Check the example [glb-export](https://threepipe.org/examples/#glb-export/) to see a demo.

## Exporting Materials

Export a material
```typescript
const material = viewer.assetManager.materialManager.findMaterialsByName('materialName')[0];
// or
// const material = viewer.scene.getObjectByName('objectName').material;
const blob = await viewer.export(material)
// download the file
downloadBlob(blob, 'material.' + blob.ext)
```

Check the example [pmat-material-export](https://threepipe.org/examples/#pmat-material-export/) to see a demo.

## Exporting Canvas Images

Canvas Screenshot/snapshot can be exported as png, jpeg or webp(if supported by the browser)
```typescript
const blob = await viewer.getScreenshotBlob({mimeType: 'image/' + type, quality: 0.85})
// or to get data url:
// const dataUrl = await viewer.getScreenshotDataUrl({mimeType: 'image/' + type, quality: 0.85})
// download the file
downloadBlob(blob, 'screenshot.' + blob.ext)
```

Check the example [image-snapshot-export](https://threepipe.org/examples/#image-snapshot-export/) to see a demo.

See also: [CanvasSnapshotPlugin](../plugin/CanvasSnapshotPlugin).

## Exporting Viewer Config (vjson)

The viewer configuration can be exported to JSON using `viewer.exportConfig` or `viewer.export(viewer)`. This would export a JSON object with all the viewer, scene and all plugin configuration but no 3D data.

::: tip
Plugins can exclude themselves from being included in vjson by setting property `serializeWithViewer` to `false`
:::

We use the extension `.vjson` to easily identify viewer configuration files and use them as presets/starter scenes.

```typescript
// get a blob directly
const blob = viewer.export(viewer);

// get a json object
const json = viewer.exportConfig();

// get a json object that will later be embedded in a binary file (like glb)
const json2 = viewer.exportConfig(true);
```

## Exporting Plugin

Any plugin that supports serialization(most of them), can be exported independently to JSON using `viewer.export` or `viewer.exportPluginConfig`.

::: note
Don't use `plugin.toJSON` directly, use `viewer.export` instead as that will make sure the resources(like textures) are embedded with proper context.
:::

```typescript
const plugin = viewer.addPluginSync(SSAOPlugin)

const blob = viewer.export(plugin);
downloadBlob(blob, plugin.name + '.' + blob.ext); // json
```
The exported JSON config can then be imported by `viewer.load` or `viewer.importPluginConfig`.

## Exporting Textures

Textures can be exported to JSON using `viewer.export` or `AssetExporter`

```typescript
const texture = await viewer.load('https://example.com/file.jpeg')
const blob = await viewer.export(texture)
downloadBlob(blob, texture.name + '.' + blob.ext)
```

Render target textures can be exported with `viewer.renderManager.exportRenderTarget` or `viewer.export`,
read about [Exporting Render Targets](#exporting-render-targets) below.

TODO: add examples for texture export

Textures and Uint8 Data Textures can be exported as a data url or copied to a new canvas
```typescript
// get a base64 data url
const dataUrl = textureToDataUrl(texture, 4096, false, 'image/png') // texture or data texture, max-size, flipY, mimeType
// or copy to a new canvas
const canvas = textureToCanvas(texture, 4096) // texture or data texture, max-size
```

Data Textures of type Half float and Float can be exported with `viewer.export`
```typescript
const dataTex = await viewer.load('https://example.com/file.hdr')
const blob = await viewer.export(dataTexture, {exportExt: 'exr'})
```
Check the example [hdr-to-exr](https://threepipe.org/examples/#hdr-to-exr/) to see a demo of HDR to EXR conversion.

TODO: add support to export unsigned byte textures as png, jpeg, webp

## Exporting Images/Textures

Exporting Textures as Images with image of types ImageBitmap, HTMLImageElement,
HTMLOrSVGImageElement, CanvasImageSource, HTMLCanvasElement,
OffscreenCanvas can be exported to png data urls with [imageBitmapToBase64](https://repalash.com/ts-browser-helpers/functions/imageBitmapToBase64.html) function.

```typescript
const texture = await viewer.load('https://example.com/file.jpeg')

const dataUrl = await imageBitmapToBase64(texture.image, 'image/png', 0.85);
```

TODO: add support for texture export as images in AssetExporter

## Exporting Render Targets

Unsigned byte render targets can be exported as png, jpeg or webp(if supported by the browser)
```typescript
const depthPlugin = viewer.addPluginSync(DepthBufferPlugin, UnsignedByteType)
// wait for the first render
const blob = await viewer.export(depthPlugin.target!, {exportExt: 'png'})
if (blob) downloadBlob(blob, target.texture.name + '.' + blob.ext)
```

Half float and float render targets can be exported as exr
```typescript
const depthPlugin = viewer.addPluginSync(DepthBufferPlugin, HalfFloatType)
// wait for the first render
const blob = await viewer.export(depthPlugin.target!, {exportExt: 'exr'})
if (blob) downloadBlob(blob, target.texture.name + '.' + blob.ext)
```

::: tip
`exportExt` is determined automatically if not specified.
:::

+ 191
- 0
website/guide/features.md 파일 보기

@@ -0,0 +1,191 @@
---
prev:
text: 'Editors in Threepipe'
link: './editors'

next:
text: 'Viewer API'
link: './viewer-api'
---

# Features

Threepipe comes packed with a asset manager, render pipeline, serialization setup, material extensions, UI configurations and bundles many plugins, that can be added with a single line of code to provide a variety of features listed below. In a custom application it’s possible to tree-shake the bundle by picking the plugins that are required.

## File Formats

ThreePipe Asset Manager supports the import of the following file formats out of the box:
* **Models**: gltf, glb, obj+mtl, fbx, drc
* **Materials**: mat, pmat, bmat (json based), registered material template slugs
* **Images**: webp, png, jpeg, jpg, svg, ico, avif, hdr, exr
* **Misc**: json, vjson, zip, txt

Plugins can add additional formats:
* Models
* 3dm - Using [Rhino3dmLoadPlugin](../plugin/Rhino3dmLoadPlugin)
* ply - Using [PLYLoadPlugin](../plugin/PLYLoadPlugin)
* usdz - Using [USDZLoadPlugin](../plugin/USDZLoadPlugin)
* stl - Using [STLLoadPlugin](../plugin/STLLoadPlugin)
* ktx - Using [KTXLoadPlugin](../plugin/KTXLoadPlugin)
* ktx2 - Using [KTX2LoadPlugin](../plugin/KTX2LoadPlugin)

Plugins to support more model formats are available in the package [@threepipe/plugins-extra-importers](#threepipeplugins-extra-importers) including .3ds,
.3mf, .collada, .amf, .bvh, .vox, .gcode, .mdd, .pcd, .tilt, .wrl, .mpd, .vtk, .xyz

### Loading files

All the file formats can be easily loaded using the `viewer.load` method.

```typescript
const objectGlb = await viewer.load<IObject3D>('https://example.com/file.glb')
const texture = await viewer.load<ITexture>('https://example.com/texture.png')
const material = await viewer.load<PhysicalMaterial>('https://example.com/material.pmat')
const json = await viewer.load<any>('https://example.com/file.json')
```

This method internally uses the [AssetManager](https://threepipe.org/docs/classes/AssetManager.html) to load files and returns a promise that resolves to the loaded object.

Check the [Loading Files](./loading-files) guide for more details and how to load different file types.

- [3D models](./loading-files#3d-models)
- [Materials](./loading-files#materials)
- [Images/Textures](./loading-files#imagestextures)
- [zip files](./loading-files#zip-files)
- [txt, json files](./loading-files#txt-json-files)
- [Data URLs](./loading-files#data-urls)
- [Local files, File and Blob](./loading-files#local-files-file-and-blob)
- [Background, Environment maps](./loading-files#background-environment-maps)
- [SVG strings](./loading-files#svg-strings)

### Exporting files

Threepipe has built-in support for exporting some file types like glb, exr, images(textures, render targets), , materials, json(viewer/scene configuration and plugin configurations).

To export files, several helpers are provided - [`viewer.export()`](https://threepipe.org/docs/classes/ThreeViewer.html#export) and [`viewer.exportScene()`](https://threepipe.org/docs/classes/ThreeViewer.html#exportScene).

```typescript
const blob = await viewer.exportScene({viewerConfig: true})
const blob1 = await viewer.export(object, {exportExt: 'glb', embedUrlImages: true})
const blob2 = await viewer.export(material)
const blob3 = await viewer.export(texture)
const blob4 = await viewer.export(dataTexture)
const blob5 = await viewer.export(renderTarget)
```

Check the [Exporting Files](./exporting-files) guide for more details and how to export different file types.

- [Exporting 3D models](./exporting-files#exporting-3d-models)
- [Exporting Materials](./exporting-files#exporting-materials)
- [Exporting Canvas Images](./exporting-files#exporting-canvas-images)
- [Exporting Images/Textures](./exporting-files#exporting-imagestextures)
- [Exporting Render Targets](./exporting-files#exporting-render-targets)

## Plugin System

Threepipe includes a plugin system for adding additional features to the viewer in a modular way.

All plugins follow the same basic structure, independent of the logic, with the API to add and remove plugins being always consistent (and one-liner). This makes it easy to debug, bundle, tree-shake, serialisation/deserialisation and extend functionality to the 3d viewer. It is also recommended to keep individual plugins small and handle one specific functionality.

Plugins can be dependant on other plugins. These dependencies are automatically resolved and added to the viewer at runtime. eg. `SSAOPlugin` depends on `GBufferPlugin` to get the depth and normal data. So, when `SSAOPlugin` is added to the viewer, it automatically adds `GBufferPlugin` before that (if not added already).

The plugins can be added synchronously or asynchronously using `viewer.addPluginSync` and `viewer.addPlugin` methods respectively.

It is recommended to create custom plugins for reusable features, as they provide built-in features for ui configuration, serialization, integration with editors etc and are easy to manage and tree-shake in the code.

Check out the list of plugins in the [Core Plugin](./core-plugins) and [@threepipe Packages](./threepipe-packages) pages.

To create new plugins, 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.

Read more about the [Plugin System](./plugin-system) on it's page.

## Render pipeline

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.

The `RenderManager` includes an [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, but the pass management and sorting is managed by the `RenderManager` itself. It inherits from [RenderTargetManager](https://threepipe.org/docs/classes/RenderTargetManager.html) which provides utilities for creating, tracking and destroying dedicated and temporary render targets.

The main render pipeline supports progressive rendering and is fully configurable. Plugins and applications can add custom passes, effects, and shaders to the pipeline.

By default, the render pipeline includes 2 passes - [RenderPass](https://threejs.org/docs/#api/en/postprocessing/RenderPass) for rendering the scene hierarchy and [ScreenPass](https://threejs.org/docs/#api/en/postprocessing/ShaderPass) for rendering the final output on the canvas.

Plugins like [GBufferPlugin](https://threepipe.org/docs/classes/GBufferPlugin.html), [SSAOPlugin](https://threepipe.org/docs/classes/SSAOPlugin.html), [TonemapPlugin](https://threepipe.org/docs/classes/TonemapPlugin.html), etc interact and extend the render pipeline by adding custom passes to the render pipeline and material extensions to the material manager.

Check the [Render Pipeline](./render-pipeline) guide for more details about render targets and how to add custom passes.

## Material Extension

Threepipe includes a Material extension system along with a material manager.
The material manager is used to register materials and material extensions.

The material extensions can extend any material in the scene, or any plugin/pass with additional uniforms, defines, shader snippets and provides hooks.

The material extensions are automatically applied to all materials in the scene that are compatible,
when the extension is registered or when the material(the object its assigned to) is added to the scene.

Threepipe includes several built-in materials like [PhysicalMaterial](https://threepipe.org/docs/classes/PhysicalMaterial.html), [UnlitMaterial](https://threepipe.org/docs/classes/UnlitMaterial.html), [ExtendedShaderMaterial](https://threepipe.org/docs/classes/ExtendedShaderMaterial.html), [LegacyPhongMaterial](https://threepipe.org/docs/classes/LegacyPhongMaterial.html), that include support for extending the material. Any existing three.js material can be made extendable, check the `ShaderPass2` class for a simple example that adds support for material extension to three.js ShaderPass.

Several Plugins create and register material extensions to add different kinds of rendering features over the standard three.js materials like [ClearcoatTintPlugin](https://threepipe.org/docs/classes/ClearcoatTintPlugin.html), [SSAOPlugin](https://threepipe.org/docs/classes/SSAOPlugin.html), [CustomBumpMapPlugin](https://threepipe.org/docs/classes/CustomBumpMapPlugin.html), [AnisotropyPlugin](https://threepipe.org/docs/classes/AnisotropyPlugin.html), [FragmentClippingExtensionPlugin](https://threepipe.org/docs/classes/FragmentClippingExtensionPlugin.html), etc. They also provide uiConfig that can be used to dynamically generate UI or the material extensions.

Some plugins also expose their material extensions to be used by other passes/plugins to access properties like buffers, synced uniforms, defines etc. Like [GBufferPlugin](https://threepipe.org/docs/classes/GBufferPlugin.html), [DepthBufferPlugin](https://threepipe.org/docs/classes/DepthBufferPlugin.html), [NormalBufferPlugin](https://threepipe.org/docs/classes/NormalBufferPlugin.html), etc.

Read more and check a sample plugin in the [Material Extension](./material-extension) guide.

## UI Configuration

Almost all of the classes and plugins in Threepipe include [uiconfig.js](https://repalash.com/uiconfig.js/) support and can be used to create configuration UIs, 3d configurators and even full-editors.
The UIs are automatically generated based on the configuration object under `.uiConfig` property on all objects. These are of type [UiObjectConfig](https://repalash.com/uiconfig.js/interfaces/UiObjectConfig.html).
In some classes, the ui configs are also generated using typescript decorators.

The `uiConfig` is also added to all three.js objects and materials when they are added to the scene.

The UIs can be generated at runtime using any of the UI plugins like [TweakpaneUIPlugin](#threepipeplugin-tweakpane), [BlueprintJsUiPlugin](#threepipeplugin-blueprintjs)

An example showing how to create a UI for a material

```typescript
const ui = viewer.addPluginSync(TweakpaneUiPlugin)

const object = viewer.scene.getObjectByName('objectName');
const material = object.material as PhysicalMaterial;

ui.appendChild(material.uiConfig)
```

See it in action: https://threepipe.org/examples/#material-uiconfig/

Check more examples showing [Viewer UI](https://threepipe.org/examples/#viewer-uiconfig/), [Scene UI](https://threepipe.org/examples/#scene-uiconfig/), [Object UI](https://threepipe.org/examples/#object-uiconfig/), [Camera UI](https://threepipe.org/examples/#camera-uiconfig/)

::: info
[TweakpaneEditorPlugin](#threepipeplugin-tweakpane-editor) further uses the Tweakpane configuration panel along with various plugins to create an 3d editor.
:::

Custom UI configuration can be created to generate custom UI for the editor or tweaking.
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.

Read more and check a sample in the [UI Configuration](./ui-config) guide.

## Serialization

Easy serialization of all threepipe and most three.js objects are supported out of the box using the Asset Manager.
Fine control over serialization is also supported
using the [ThreeSerialization](https://threepipe.org/docs/classes/ThreeSerialization.html) class

Call `ThreeSerialization.serialize` on any object to serialize it.
and `ThreeSerialization.deserialize` to deserialize the serialized object.

This is done by performing a nested serialization of all the properties of the object.
It's possible to implement custom serializers for custom types and classes and is done for three.js primitives,
objects and plugins in threepipe

```typescript
const vec = new Vector3()
const serialized = ThreeSerialization.serialize(vec)
const deserialized = ThreeSerialization.deserialize(serialized)
// deserialized will be an instance of Vector3
```

::: tip
For any high-level usage, don't use the `ThreeSerialization` class directly. Use the `viewer.export` and `viewer.import` methods or other methods to save and load configurations that's available in the plugins and the viewer.
:::

Read more and check samples in the [Serialization](./serialization) guide.

+ 218
- 0
website/guide/getting-started.md 파일 보기

@@ -0,0 +1,218 @@
---
prev:
text: 'What is Threepipe?'
link: './introduction'

next:
text: 'Editors in Threepipe'
link: './editors'
---

# Getting Started

Getting started with Threepipe is easy. You can use it in your HTML/JS, React, Vue.js, Svelte, or any other web framework. The best way to use it is as an ES module in your project. Simply install the package `threepipe` from npm, or include it in html from any CDN like [esm.sh](https://esm.sh/threepipe) or [jsdelivr](https://cdn.jsdelivr.net/npm/threepipe@latest).

[![NPM Package](https://img.shields.io/npm/v/threepipe.svg)](https://www.npmjs.com/package/threepipe)

## What you need

- A 3D Model (GLTF, GLB, OBJ, FBX, etc). Optionally, the model, scene, and plugins can be configured, compressed and exported using the [Threepipe Editor](https://editor.threepipe.org) or [Tweakpane Editor](https://threepipe.org/examples/tweakpane-editor/). A sample is used in examples below.
- A modern browser that supports [WebGL2](https://caniuse.com/webgl2) and [WebAssembly](https://caniuse.com/webassembly) (for some plugins).
- Node.js (for local development). Node 18+ is recommended.
- An existing project or willingness to start a new one
- Basic knowledge of JavaScript/TypeScript

## Quickstart

### Codepen
You can quickly prototype in JavaScript on Codepen. Here is a starter pen with the basic setup: [Threepipe Starter Codepen](https://codepen.io/repalash/pen/GRbEONZ?editors=0010)

Simply fork the pen and start coding.

Each example on [Threepipe Examples](https://threepipe.org/examples) also has a Codepen Button <input type="image" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/t-1/cp-arrow-right.svg" width="35" height="35" style="margin-bottom: -0.6rem; cursor: unset;"> to open the example directly in Codepen.

### Local Setup

To get started with a new project using Threepipe locally, you need to have Node.js installed on your machine.

A new project can be quickly created using the `npm create` command. Open your terminal and run the following command:
```bash
npm create threepipe@latest
```
and follow the prompts to pick a project name, select a template/framework and pick between JavaScript or TypeScript. Supported templates -
- `vanilla`
- `vanilla-ts`

This will create a ready-to-use project with all the necessary dependencies and configurations.

Now, code from any of the examples on the [Threepipe Examples](https://threepipe.org/examples) page can be copied and pasted into the project to get started.

## Install in existing projects

### HTML/JS

```html
<canvas id="three-canvas" style="width: 800px; height: 600px;"></canvas>
<script type="module">
import {ThreeViewer, DepthBufferPlugin} from 'https://threepipe.org/dist/index.mjs'
// or
// import {ThreeViewer, DepthBufferPlugin} from 'https://cdn.jsdelivr.net/npm/threepipe@latest/dist/index.mjs'
// import {ThreeViewer, DepthBufferPlugin} from 'https://esm.sh/threepipe'
// import {ThreeViewer, DepthBufferPlugin} from 'threepipe' // using npm or importmaps

const viewer = new ThreeViewer({canvas: document.getElementById('three-canvas')})

// Add some plugins
viewer.addPluginSync(new DepthBufferPlugin())
// Load an environment map
const envPromise = viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr')
const modelPromise = viewer.load('https://threejs.org/examples/models/gltf/DamagedHelmet/glTF/DamagedHelmet.gltf', {
autoCenter: true,
autoScale: true,
})

Promise.all([envPromise, modelPromise]).then(([env, model]) => {
console.log('Loaded', model, env, viewer)
})
</script>
```
Check it in action: [html-js-sample](https://threepipe.org/examples/#html-js-sample/)

Check out the details about [ThreeViewer API](#viewer-api) and more [plugins](#threepipe-plugins).

### NPM

#### Installation

```bash
npm install threepipe
```

#### Loading a 3D Model

First, create a canvas element in your HTML page:
```html
<canvas id="three-canvas" style="width: 800px; height: 600px;"></canvas>
```

Then, import the viewer and create a new instance:

```typescript
import {ThreeViewer, IObject3D} from 'threepipe'

// Create a viewer
const viewer = new ThreeViewer({canvas: document.getElementById('three-canvas') as HTMLCanvasElement})

// Load an environment map
await viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr')

// Load a model
const result = await viewer.load<IObject3D>('https://threejs.org/examples/models/gltf/DamagedHelmet/glTF/DamagedHelmet.gltf', {
autoCenter: true,
autoScale: true,
})
```

That's it! You should now see a 3D model on your page.

The 3D model can be opened in the [editor](https://threepipe.org/examples/tweakpane-editor/) to view and edit the scene settings, objects, materials, lights, cameras, post-processing, etc. and exported as a GLB file. All settings are automatically serialized and saved in the GLB file, which can be loaded into the viewer. Any plugins used in the editor can be added to the viewer to add the same functionality. The plugin data is automatically loaded(if the plugin is added) when the model is added to the scene.

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.

Check out the GLTF Load example to see it in action or to check the JS equivalent code: [Example: gltf-load](https://threepipe.org/examples/#gltf-load/)

Check out the [Plugins](#plugin-system) section below to learn how to add additional functionality to the viewer.

### React

A sample [react](https://react.dev) component in tsx to render a model with an environment map.

```tsx
import React from 'react'
function ThreeViewerComponent({src, env}: {src: string, env: string}) {
const canvasRef = React.useRef(null)
React.useEffect(() => {
const viewer = new ThreeViewer({canvas: canvasRef.current})

const envPromise = viewer.setEnvironmentMap(env)
const modelPromise = viewer.load(src)
Promise.all([envPromise, modelPromise]).then(([env, model]) => {
console.log('Loaded', model, env, viewer)
})
return () => {
viewer.dispose()
}
}, [])
return (
<canvas id="three-canvas" style={{width: 800, height: 600}} ref={canvasRef} />
)
}
```

Check it in action: [react-tsx-sample](https://threepipe.org/examples/#react-tsx-sample/)

Other examples in js: [react-js-sample](https://threepipe.org/examples/#react-js-sample/) and jsx: [react-jsx-sample](https://threepipe.org/examples/#react-jsx-sample/)

### Vue.js

A sample [vue.js](https://vuejs.org/) component in js to render a model with an environment map.

```js
const ThreeViewerComponent = {
setup() {
const canvasRef = ref(null);

onMounted(() => {
const viewer = new ThreeViewer({ canvas: canvasRef.value });

const envPromise = viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr');
const modelPromise = viewer.load('https://threejs.org/examples/models/gltf/DamagedHelmet/glTF/DamagedHelmet.gltf');

Promise.all([envPromise, modelPromise]).then(([env, model]) => {
console.log('Loaded', model, env, viewer)
})

onBeforeUnmount(() => {
viewer.dispose();
});
});

return { canvasRef };
},
};
```

Check it in action: [vue-html-sample](https://threepipe.org/examples/#vue-html-sample/)

Another example with Vue SFC(Single file component): [Example: vue-sfc-sample](https://threepipe.org/examples/#vue-sfc-sample/)

### Svelte

A sample [svelte](https://svelte.dev/) component in js to render a model with an environment map.

```html
<script>
import {onDestroy, onMount} from 'svelte';
import {ThreeViewer} from 'threepipe';

let canvasRef;
let viewer;
onMount(() => {
viewer = new ThreeViewer({canvas: canvasRef});

const envPromise = viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr');
const modelPromise = viewer.load('https://threejs.org/examples/models/gltf/DamagedHelmet/glTF/DamagedHelmet.gltf');

Promise.all([envPromise, modelPromise]).then(([env, model]) => {
console.log('Loaded', model, env, viewer)
})
});
onDestroy(() => viewer.dispose())
</script>

<canvas bind:this={canvasRef} id="three-canvas" style="width: 800px; height: 600px"></canvas>
```

Check it in action: [svelte-sample](https://threepipe.org/examples/#svelte-sample/)

+ 143
- 0
website/guide/introduction.md 파일 보기

@@ -0,0 +1,143 @@
---
next:
text: 'Getting Started'
link: './getting-started'
---

# Introduction

A new way to work with three.js, 3D models and rendering on the web.

[![NPM Package](https://img.shields.io/npm/v/threepipe.svg)](https://www.npmjs.com/package/threepipe)

[![License: Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-green.svg)](https://opensource.org/license/apache-2-0/)

[//]: # (todo image)

Threepipe provides a high-level API over three.js to create 3D model viewers, configurators. editors and other interactive 3D applications on websites.

It can be used to quickly get into production-ready WebGL and 3D web graphics without getting into graphics and shaders. The framework is also fully customisable with an extensive API for experienced programmers to add features and make more cool stuff.

<div class="tip custom-block" style="padding-top: 8px">

Just want to try it out? Skip to the [Quickstart](./getting-started).

</div>

Key features include:
- Simple, intuitive API for creating 3D model viewers/configurators/editors on web pages, with many built-in presets for common workflows and use-cases.
- Companion [editor](https://threepipe.org/examples/tweakpane-editor/) to create, edit and configure 3D scenes in the browser.
- Modular architecture that allows you to easily extend the viewer, scene objects, materials, shaders, rendering, post-processing and serialization with custom functionality.
- Plugin system along with a rich library of built-in plugins that allows you to easily add new features to the viewer.
- [uiconfig](https://github.com/repalash/uiconfig.js) compatibility to automatically generate configuration UIs in the browser.
- Modular rendering pipeline with built-in deferred rendering, post-processing, RGBM HDR rendering, etc.
- Material extension framework to modify/inject/build custom shader code into existing materials at runtime from plugins.
- 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.
- Automatic serialization of all viewer and plugin settings in GLB(with custom extensions) and JSON formats.
- Automatic disposal of all three.js resources with built-in reference management.

## Examples

Code samples and demos covering various usecases and test are present in the [examples](https://github.com/repalash/threepipe/tree/master/examples/) folder.

Try them: https://threepipe.org/examples/

View the source code by pressing the code button on the top left of the example page.

To make changes and run the example, click on the Codepen Button <input type="image" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/t-1/cp-arrow-right.svg" width="35" height="35" style="margin-bottom: -0.6rem; cursor: unset;"> on the top right of the source code.

::: tip TUTORIALS

There are some step-by-step tutorials to get you started if you are new to 3D or Threepipe.
- [Create an interactive Device Showcase](https://tympanus.net/codrops/2024/08/07/interactive-3d-device-showcase-with-threepipe/) on codrops.

:::

### Sample

Here is what a sample `threepipe` code looks like -

```typescript
import {
ContactShadowGroundPlugin,
IObject3D,
LoadingScreenPlugin,
ProgressivePlugin,
SSAAPlugin,
ThreeViewer
} from 'threepipe';
import {TweakpaneUiPlugin} from '@threepipe/plugin-tweakpane';

async function init() {

const viewer = new ThreeViewer({
// The canvas element where the scene will be rendered
canvas: document.getElementById('threepipe-canvas') as HTMLCanvasElement,
// Enable/Disable MSAA (Multi-Sample Anti-Aliasing)
msaa: false,
// Set the render scale automatically based on the device pixel ratio
renderScale: "auto",
// Enable/Disable tone mapping
tonemap: true,
// Add some plugins
plugins: [
// Show a loading screen while the model is downloading
LoadingScreenPlugin,
// Enable progressive rendering and SSAA
ProgressivePlugin, SSAAPlugin,
// Add a ground with contact shadows
ContactShadowGroundPlugin
]
});

// Add a plugin with a debug UI for tweaking parameters
const ui = viewer.addPluginSync(new TweakpaneUiPlugin(true));

// Load an environment map
await viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr', {
// The environment map can also be used as the scene background
setBackground: false,
});

// Load a 3D model with auto-center and auto-scale options
const result = await viewer.load<IObject3D>('https://threejs.org/examples/models/gltf/DamagedHelmet/glTF/DamagedHelmet.gltf', {
autoCenter: true,
autoScale: true,
});

// Add some debug UI elements for tweaking parameters
ui.setupPlugins(SSAAPlugin)
ui.appendChild(viewer.scene.uiConfig)
ui.appendChild(viewer.scene.mainCamera.uiConfig)

// Every object, material, etc has a UI config that can be added to the UI to configure it.
const model = result?.getObjectByName('node_damagedHelmet_-6514');
if (model) ui.appendChild(model.uiConfig, {expanded: false});

}

init();
```

The `ThreeViewer` class is used to create a new 3D viewer instance. It includes several components including a `Scene`, `Camera`(with `OrbitControls`), `Renderer`, `RenderManager`, `AssetManager`, and some default plugins(like `TonemapPlugin`). It is set up to provide a quickstart to create a three.js app with all the required components.

Additionally plugins like `LoadingScreenPlugin`, `ProgressivePlugin`, `SSAAPlugin`, and `ContactShadowGroundPlugin` are added to extend the functionality of the viewer.

Check out this sample on CodePen: [threepipe-sample](https://codepen.io/repalash/pen/GRbEONZ?editors=0010)

## License
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).

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.

## Status
The project is in `beta` stage and under active development. Many features and integrations will be added but the core API will not change significantly in future releases.

## API Reference/Docs

Check the list of all functions, classes and types in the [API Reference Docs](https://threepipe.org/docs/).

## Contributing

Contributions to ThreePipe are welcome and encouraged! Feel free to open issues and pull requests on the [GitHub repository](https://github.com/repalash/threepipe).


+ 244
- 0
website/guide/loading-files.md 파일 보기

@@ -0,0 +1,244 @@
---
prev:
text: 'Features'
link: './features'

next:
text: 'Exporting Files'
link: './exporting-files'
---

# Loading files

ThreePipe uses the [AssetManager](https://threepipe.org/docs/classes/AssetManager.html) to load files.
The AssetManager has support for loading files from URLs, local files and data URLs.
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.

[`viewer.load()`](https://threepipe.org/docs/classes/ThreeViewer.html#load) is a simple wrapper for loading files from the AssetManager.
It automatically adds the loaded object to the scene(if possible) and returns a promise that resolves to the loaded object, the materials are also automatically registered to the material manager.

::: details AssetManager
AssetManager internally uses [AssetImporter](https://threepipe.org/docs/classes/AssetImporter.html), which provides an API for managing three.js [LoadingManager](https://threejs.org/docs/#api/en/loaders/LoadingManager) and adding and registering loaders for different file types.

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 to import files from the `AssetImporter`. [`viewer.assetManager.loadImported()`](https://threepipe.org/docs/classes/AssetManager.html#loadImported)
can then be called to load the imported files after any processing.
The `viewer.load()`, `viewer.assetManager.addAsset()`
and `viewer.assetManager.addAssetSingle()` methods perform combination of `import` and `loadImported`.
:::

::: tip Caching
The `AssetManager` automatically caches any loaded files in the browser's `CacheStorage`. This can be controlled by passing a custom storage or `false` to the `assetManager.storage` option in the viewer constructor.
```typescript
const viewer = new ThreeViewer({
assetManager: {
storage: await caches.open('my-cache-storage'), // custom storage
// storage: false // or disable caching
}
})
```
Caching should be disabled if the server sets proper [cache-control](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control) headers, as the browser will automatically cache the files.

Note that using a different query parameter in the URL will bypass the cache and load the file again.
:::


## 3D models

The 3d models are added to `viewer.scene.modelRoot` on `viewer.load` unless some option is specified.

```typescript
const objectGlb = await viewer.load<IObject3D>('https://example.com/file.glb')
const objectFbx = await viewer.load<IObject3D>('https://example.com/file.fbx')
const objectObj = await viewer.load<IObject3D>('https://example.com/file.obj') // .mtl referenced in obj is automatically loaded
// ... load any 3d model file as an object
```
Here, we are casting to [IObject3D](https://threepipe.org/docs/interfaces/IObject3D.html) type
to get the proper type and autocomplete for the object.
`IObject3D` inherits [Object3D](https://threejs.org/docs/#api/en/core/Object3D) from three.js and adds some additional properties.

For JavaScript, the type can be omitted.
```javascript
const objectGlb = await viewer.load('https://example.com/file.glb')
```

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.

::: tip
Loaders for some file types are already added, add more loaders using plugins or by registering custom loaders.
```typescript
viewer.addPluginSync(Rhino3dmLoadPlugin)
```
Check the [model-viewer](https://threepipe.org/examples/#model-viewer/) example for a list of plugins that can be used.
:::

## Materials

The materials downloaded as PMAT/BMAT/JSON etc from threepipe,
webgi or the editor can be loaded
and registered with the [MaterialManager](https://threepipe.org/docs/classes/MaterialManager)
using the `viewer.load` method.

Custom material types can also be registered by plugins(like dmat for diamonds), which can also be loaded automatically using the `viewer.load` method.

```typescript
const pMaterial = await viewer.load<PhysicalMaterial>('https://example.com/file.pmat')
const bMaterial = await viewer.load<UnlitMaterial>('https://example.com/file.bmat')
// ... load any material file as a material
```
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.

To assign the material on any object, set it to `object.material`

```typescript
// find a loaded mesh in the scene
const object = viewer.scene.getObjectByName('objectName');
// assign the material
object.material = pMaterial;
```

To copy the properties without changing the material reference, use `material.copy()` or `material.setValues()` methods.

```typescript
object.material.copy(pMaterial);

// or use material manager to apply to multiple materials.
viewer.assetManager.materialManager.applyMaterial(pMaterial, 'METAL') // apply props to all materials/objects with the name METAL
```

TODO: add examples for material load and copy

## Images/Textures

Images can be loaded using the `viewer.load` method.
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.
More formats like ktx2, ktx, etc. can be added using plugins.

```typescript
const texture = await viewer.load<ITexture>('https://example.com/file.png')
// ... load any image file as a texture
```
Casting to [ITexture](https://threepipe.org/docs/interfaces/ITexture.html) is optional
but recommended to get the proper type and autocomplete for the texture.
It inherits from three.js [Texture](https://threejs.org/docs/#api/en/textures/Texture) and adds some additional properties.

To assign the texture on any material, set it to `material.map`

```typescript
// find a loaded mesh in the scene
const object = viewer.scene.getObjectByName('objectName');
const material = object.material as PhysicalMaterial;
// assign the texture
material.map = texture;
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.
```
Check out the image load example to see it in action or to check the JS equivalent code: https://threepipe.org/examples/#image-load/

## Zip files

.zip files are automatically unzipped and the files are sent to re-load recursively when loaded with `viewer.load`.
Any level of zip hierarchy is flattened.
Loading files like .gltf with references to assets inside the zip file,
any relative references are also automatically resolved.
This is supported for file types like gltf, glb, obj,
etc which support references to external files and has `root` set to `true in [IImporter](https://threepipe.org/docs/interfaces/IImporter.html).

```typescript
const objectGltf = await viewer.load<IObject3D>('https://example.com/model.gltf.zip')
```
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.

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.

```typescript
const textures = await viewer.assetManager.addAsset<ITexture[]>('https://example.com/textures.zip')
const materials = await viewer.assetManager.addAsset<IMaterial[]>('https://example.com/materials.zip')
```

The auto import of zip contents can be disabled to get the files and blobs in the zip
```typescript
const zip = await viewer.load<any>('https://example.com/file.zip', {autoImportZipContents: false})
```

TODO - add example for loading zip files.

## txt, json files

Text and JSON files can be loaded using the `viewer.load` method and return strings and objects respectively.

```typescript
const text = await viewer.load<string>('https://example.com/file.txt')
const json = await viewer.load<any>('https://example.com/file.json')
```

## Data URLs

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.

```typescript
const dataUrl = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA' // ... some data url
const texture = await viewer.load<ITexture>(dataUrl)
```

## Local files, File and Blob

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.

```typescript
const file: File|Blob = fileObject // create a new file, blob or get from input element
const text = await viewer.load<IObject>({
// a path/name is required to determine the proper importer by extension. `file.name` can also be used if available
path: 'file.glb',
file
})
```
The same can be done for any file type.

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.

## Background, Environment maps

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.

```typescript
await viewer.setEnvironmentMap('https://example.com/file.hdr')
await viewer.setBackgroundMap('https://example.com/file.png')
```

The same texture can be set to both by setting `setBackground` or `setEnvironment` to true in the options:
```typescript
await viewer.setEnvironmentMap('https://example.com/file.hdr', {setBackground: true})
```

Check the HDR Load example to see it in action: https://threepipe.org/examples/#hdr-load/

## SVG strings
SVG strings can be converted to data urls using the [svgUrl](https://repalash.com/ts-browser-helpers/functions/svgUrl.html) string template function

```typescript
const svgDataUrl = svgUrl`<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"> ... </svg>`;
const texture = await viewer.load<ITexture>(dataUrl)
```

## Custom file types

Custom file importers/loaders can be registered to the `AssetImporter` using the `addImporter` method.

```typescript
class CustomLoader extends FileLoader implements ILoader{
constructor(manager?: LoadingManager) {
super(manager);
}
load(url: string, onLoad: (data: any) => void, onProgress?: (event: ProgressEvent) => void, onError?: (event: ErrorEvent) => void): Mesh {
this.setResponseType('json')
return super.load(url, (json: any)=>{
const mat = new PhysicalMaterial(json)
onLoad?.(mat)
}, onProgress, onError)
}
}

viewer.assetManager.importer.addImporter(new Importer(CustomLoader, ['ext'], ['mime/type'], false))

// load the file
const mat = await viewer.load<PhysicalMaterial>('https://example.com/file.ext')
```

+ 68
- 0
website/guide/material-extension.md 파일 보기

@@ -0,0 +1,68 @@
---
prev:
text: 'Render Pipeline'
link: './render-pipeline'

next:
text: 'UI Configuration'
link: './ui-config'
---

# Material Extension

Threepipe includes a Material extension system along with a material manager.
The material manager is used to register materials and material extensions.

The material extensions can extend any material in the scene, or any plugin/pass with additional uniforms, defines, shader snippets and provides hooks.

The material extensions are automatically applied to all materials in the scene that are compatible,
when the extension is registered or when the material(the object its assigned to) is added to the scene.

Threepipe includes several built-in materials like [PhysicalMaterial](https://threepipe.org/docs/classes/PhysicalMaterial.html), [UnlitMaterial](https://threepipe.org/docs/classes/UnlitMaterial.html), [ExtendedShaderMaterial](https://threepipe.org/docs/classes/ExtendedShaderMaterial.html), [LegacyPhongMaterial](https://threepipe.org/docs/classes/LegacyPhongMaterial.html), that include support for extending the material. Any existing three.js material can be made extendable, check the `ShaderPass2` class for a simple example that adds support for material extension to three.js ShaderPass.

Several Plugins create and register material extensions to add different kinds of rendering features over the standard three.js materials like [ClearcoatTintPlugin](https://threepipe.org/docs/classes/ClearcoatTintPlugin.html), [SSAOPlugin](https://threepipe.org/docs/classes/SSAOPlugin.html), [CustomBumpMapPlugin](https://threepipe.org/docs/classes/CustomBumpMapPlugin.html), [AnisotropyPlugin](https://threepipe.org/docs/classes/AnisotropyPlugin.html), [FragmentClippingExtensionPlugin](https://threepipe.org/docs/classes/FragmentClippingExtensionPlugin.html), etc. They also provide uiConfig that can be used to dynamically generate UI or the material extensions.

Some plugins also expose their material extensions to be used by other passes/plugins to access properties like buffers, synced uniforms, defines etc. Like [GBufferPlugin](https://threepipe.org/docs/classes/GBufferPlugin.html), [DepthBufferPlugin](https://threepipe.org/docs/classes/DepthBufferPlugin.html), [NormalBufferPlugin](https://threepipe.org/docs/classes/NormalBufferPlugin.html), etc.

The material extensions must follow the [MaterialExtension](https://threepipe.org/docs/interfaces/MaterialExtension.html) interface.
Many plugins create their own material extensions either for the scene materials or shader passes(like the screen pass). Some plugins like `DepthBufferPlugin` also provides helper material extensions for other custom plugins to fetch value in the depth buffer.

A sample material extension
```typescript
const extension: MaterialExtension = {
shaderExtender: (shader)=> {
// change the shader properties like shader.fragmentShader, etc
// similar to onBeforeCompile
},
parsFragmentSnippet: ` // add some code before the main function in the fragment shader
uniform sampler2D tTexture;
uniform float opacity;
`,
extraUniforms: {
tTexture: ()=>({value: getTexture()}),
opacity: {value: 1}
// add additional uniforms, these can be IUniform or functions that return IUniform
},
extraDefines: {
['DEPTH_PACKING']: BasicDepthPacking,
['SOME_DEFINE']: ()=>"1",
// add additional defines, these can be values or functions that return values
},
priority: 100, // priority when using multiple extensions on the same material
isCompatible: (material) => material.isMeshBasicMaterial, // check if the material is compatible with this extension,
computeCacheKey: (material) => material.uuid, // a custom cache key for the material extension. Shader is recompiled when this is changed
onObjectRender: (object: Object3D, material: IMaterial) => {
// called when some object is rendererd which has a material with this extension.
},
// uiConfig
// check more properties and hooks in the MaterialExtension interface
}

// The extension can be registered to all the materials using the MaterialManager
viewer.assetManager.materialManager.registerMaterialExtension(extension)

// or register it on a single material (like the Screen Pass)
viewer.renderManager.screenPass.material.registerMaterialExtensions([extension])
```

[//]: # (todo add example)

+ 130
- 0
website/guide/plugin-system.md 파일 보기

@@ -0,0 +1,130 @@
---
prev:
text: 'Serialization'
link: './serialization'

#next:
# text: 'UI Configuration'
# link: './ui-config'
---

# Plugin System

Plugins are the building blocks of features in a 3D Viewer. Each plugin handles its own individual feature along with serialisation and lifecycle management. Threepipe uses a plugin system to add new options, rendering styles, post processing passes, and more functionality. The plugin architecture is designed similar to other js frameworks like vue or webpack (but for 3d rendering).

::: tip
Check the pages on [Core Plugins](./core-plugins) and [@threepipe Packages](./threepipe-packages) for a list of available plugins.
:::

All plugins follow the same basic structure, independent of the logic, with the API to add and remove plugins being always consistent (and one-liner). This makes it easy to debug, bundle, tree-shake, serialisation/deserialisation and extend functionality to the 3d viewer. It is also recommended to keep individual plugins small and handle one specific functionality.

Plugins can be dependant on other plugins. These dependencies are automatically resolved and added to the viewer at runtime. eg. `SSAOPlugin` depends on `GBufferPlugin` to get the depth and normal data. So, when `SSAOPlugin` is added to the viewer, it automatically adds `GBufferPlugin` before that (if not added already).

::: note
Plugin dependencies are different from pass/filter dependencies, which specifies how passes should be arranged in the render pipeline (effect composer).
:::

Threepipe ships with a library of internal and external plugins to achieve photorealistic rendering, generating user interfaces, handling events, loading and exporting assets, building 3d models etc.

The plugins can be added synchronously or asynchronously using `viewer.addPluginSync` and `viewer.addPlugin` methods respectively.

It is recommended to create custom plugins for reusable features, as they provide built-in features for ui configuration, serialization, integration with editors etc and are easy to manage and tree-shake in the code.

Check out the list of plugins in the [Core Plugin](./core-plugins) and [@threepipe Packages](./threepipe-packages) pages.

To create new plugins, 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.
The only difference is that in async the `onAdded` and `onRemove` functions are async.

Here is a sample plugin
```typescript
@uiFolder("Sample Plugin") // This creates a folder in the Ui. (Supported by TweakpaneUiPlugin)
export class SamplePlugin extends AViewerPluginSync<"sample-1" | "sample-2"> {
// These are the list of events that this plugin can dispatch.
static readonly PluginType = "SamplePlugin"; // This is required for serialization and handling plugins. Also used in viewer.getPluginByType()

@uiToggle() // This creates a checkbox in the Ui. (Supported by TweakpaneUiPlugin)
@serialize() // Adds this property to the list of serializable. This is also used when serializing to glb in AssetExporter.
enabled = true;

// A plugin can have custom properties.

@uiSlider("Some Number", [0, 100], 1) // Adds a slider to the Ui, with custom bounds and step size (Supported by TweakpaneUiPlugin)
@serialize("someNumber")
@onChange(SamplePlugin.prototype._updateParams) // this function will be called whenevr this value changes.
val1 = 0;

// A plugin can have custom properties.
@uiInput("Some Text") // Adds a slider to the Ui, with custom bounds and step size (Supported by TweakpaneUiPlugin)
@onChange(SamplePlugin.prototype._updateParams) // this function will be called whenevr this value changes.
@serialize()
val2 = "Hello";

@uiButton("Print Counters") // Adds a button to the Ui. (Supported by TweakpaneUiPlugin)
public printValues = () => {
console.log(this.val1, this.val2);
this.dispatchEvent({ type: "sample-1", detail: { sample: this.val1 } }); // This will dispatch an event.
}

constructor() {
super();
this._updateParams = this._updateParams.bind(this);
}

private _updateParams() {
console.log("Parameters updated.");
this.dispatchEvent({ type: "sample-2" }); // This will dispatch an event.
}

onAdded(v: ThreeViewer): void {
super.onAdded(v);

// Do some initialization here.
this.val1 = 0;
this.val2 = "Hello";

v.addEventListener("preRender", this._preRender);
v.addEventListener("postRender", this._postRender);
v.addEventListener("preFrame", this._preFrame);
v.addEventListener("postFrame", this._postFrame);

this._viewer!.scene.addEventListener("addSceneObject", this._objectAdded); // this._viewer can also be used while this plugin is attached.
}

onRemove(v: ThreeViewer): void {
// remove dispose objects

v.removeEventListener("preRender", this._preRender);
v.removeEventListener("postRender", this._postRender);
v.removeEventListener("preFrame", this._preFrame);
v.removeEventListener("postFrame", this._postFrame);

this._viewer!.scene.removeEventListener("addSceneObject", this._objectAdded); // this._viewer can also be used while this plugin is attached.

super.onRemove(v);
}

private _objectAdded = (ev: IEvent<any>) => {
console.log("A new object, texture or material is added to the scene.", ev.object);
};
private _preFrame = (ev: IEvent<any>) => {
// 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()
};
private _preRender = (ev: IEvent<any>) => {
// This is called before each frame is rendered, only when the viewer is dirty.
};
// postFrame and postRender work the same way as preFrame and preRender.
}
```

Notes:
* 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`
* 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.
* Event listeners and other hooks can be added and removed in `onAdded` and `onRemove` functions for the viewer and other plugins.
* To the viewer render the next frame, `viewer.setDirty()` can be called, or set `this.dirty = true` in preFrame and reset in postFrame to stop the rendering. (Note that rendering may continue if some other plugin sets the viewer dirty like `ProgressivePlugin` or any of the animation plugins). Check `isConverged` in `ProgressivePlugin` to check if its the final frame.
* All Plugins which inherit from AViewerPlugin support serialisation. Create property `serializeWithViewer = false` to disable serialisation with the viewer in config and glb or `toJSON: any = undefined` to disable serialisation entirely
* `plugin.toJSON()` and `plugin.fromJSON()` or `ThreeSerialization` can be used to serialize and deserialize plugins. `viewer.exportPluginConfig` and `viewer.importPluginConfig` also exist for this.
* @serialize('label') decorator can be used to mark any public/private variable as serializable. label (optional) corresponds to the key in JSON.
* @serialize supports instances of ITexture, IMaterial, all primitive types, simple JS objects, three.js math classes(Vector2, Vector3, Matrix3...), and some more.
* uiDecorators can be used to mark properties and functions that will be shown in the Ui. The Ui shows up automatically when TweakpaneUiPlugin/BlueprintJsUiPlugin is added to the viewer. Plugins have special features in the UI for download preset and saving state.

Check various plugins in the source code for more examples.

+ 100
- 0
website/guide/render-pipeline.md 파일 보기

@@ -0,0 +1,100 @@
---
prev:
text: 'Exporting Files'
link: './exporting-files'

next:
text: 'Material Extension'
link: './material-extension'
---

# Render pipeline

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.

The `RenderManager` includes an [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, but the pass management and sorting is managed by the `RenderManager` itself.

The `RenderManager` inherits from [RenderTargetManager](https://threepipe.org/docs/classes/RenderTargetManager.html)
which provides utilities for creating, tracking and destroying dedicated and temporary render targets.

The main render pipeline supports progressive rendering and is fully configurable. Plugins and applications can add custom passes, effects, and shaders to the pipeline.

Plugins like [GBufferPlugin](https://threepipe.org/docs/classes/GBufferPlugin.html), [SSAOPlugin](https://threepipe.org/docs/classes/SSAOPlugin.html), [TonemapPlugin](https://threepipe.org/docs/classes/TonemapPlugin.html), etc interact and extend the render pipeline by adding custom passes to the render pipeline and material extensions to the material manager.

## Render Targets

Render targets can be created
using the `viewer.renderManager.createTarget` and `viewer.renderManager.createTargetCustom` methods.
These can then be disposed using the `viewer.renderManager.disposeTarget` method when not needed anymore.

Or to create temp targets for one time/temporary use `viewer.renderManager.getTempTarget` and `viewer.renderManager.releaseTempTarget` methods can be used. All created render targets are tracked in the `RenderManager`, and are resized and disposed automatically when needed along with the viewer.

```typescript
const newTarget = viewer.renderManager.createTarget({sizeMultiplier: 1})
// or
const newTarget2 = viewer.renderManager.createTarget({size: {
width: 1024,
height: 1024,
},
type: HalfFloatType
})
// or clone an existing target
const newTarget3 = viewer.renderManager.composerTarget.clone()
// for multi-sample render target
const newTarget4 = viewer.renderManager.createTarget({sizeMultiplier: 1, samples: 4})

// or create a custom target
const newTarget5 = viewer.renderManager.createTargetCustom(
{width: 1024, height: 1024},
{type: HalfFloatType},
WebGLCubeRenderTarget
)

// dispose targets
viewer.renderManager.disposeTarget(newTarget)
viewer.renderManager.disposeTarget(newTarget2)
viewer.renderManager.disposeTarget(newTarget3)
viewer.renderManager.disposeTarget(newTarget4)
viewer.renderManager.disposeTarget(newTarget5)

// get a temporary target
const tempTarget = viewer.renderManager.getTempTarget({sizeMultiplier: 1})
// release the temporary target
viewer.renderManager.releaseTempTarget(tempTarget)
```

::: tip
Render targets created with a `sizeMultiplier` are automatically resized when the canvas is resized.
:::

## Passes

By default, the render pipeline([`ViewerRenderManager`](https://threepipe.org/docs/classes/ViewerRenderManager.html) includes 2 passes -
[RenderPass](https://threepipe.org/docs/classes/ExtendedRenderPass.html) for rendering the scene hierarchy and [ScreenPass](https://threepipe.org/docs/classes/ShaderPass)
for rendering the final output on the canvas.

More passes can be added and removed from the pipeline
using the [registerPass](https://threepipe.org/docs/classes/RenderManager.html#registerPass) and [unregisterPass](https://threepipe.org/docs/classes/RenderManager.html#unregisterPass) methods.

The pipeline passes need to follow the interface of [IPipelinePass](https://threepipe.org/docs/interfaces/IPipelinePass.html) and [IPipelinePassPlugin](https://threepipe.org/docs/interfaces/IPipelinePassPlugin.html).
Which adds some important parameters over the three.js Pass,
like pass id and support for defining where the pass should be added in the pipeline and it's dependants.

```typescript
const pass = new GBufferRenderPass('customPass', viewer.renderManager.createTarget({sizeMultiplier: 1}))
pass.before = ['render'] // Add the pass before the render pass
pass.after = [] // Add the pass after these passes (none in this case)
pass.required = ['render'] // render pass is required to be in the pipeline for this. throws an error if not found
viewer.renderManager.registerPass(pass)
```

::: info
See [PipelinePassPlugin](https://threepipe.org/docs/classes/PipelinePassPlugin.html) for an abstract plugin
that provides the boilerplate to create a plugin that registers a custom pass in the pipeline.
Check [NormalBufferPlugin](https://threepipe.org/docs/classes/NormalBufferPlugin.html) for an example of that.
:::

::: tip
All effects in post-processing or material extension need not be a separate pass in the pipeline.
Most effects can be achieved with either extending the scene object material shaders or the Screen Pass material shader using [Material extension](./material-extension) system
:::

+ 134
- 0
website/guide/serialization.md 파일 보기

@@ -0,0 +1,134 @@
---
prev:
text: 'UI Configuration'
link: './ui-config'

next:
text: 'Plugin System'
link: './plugin-system'
---

# Serialization

Easy serialization of all threepipe and most three.js objects are supported out of the box using the Asset Manager. Fine control over serialization is also supported using the [ThreeSerialization](https://threepipe.org/docs/classes/ThreeSerialization.html) class

Call `ThreeSerialization.serialize` on any object to serialize it.
and `ThreeSerialization.deserialize` to deserialize the serialized object.

This is done by performing a nested serialization of all the properties of the object.
It's possible to implement custom serializers for custom types and classes and is done for three.js primitives,
objects and plugins in threepipe.

## Serializable Objects

To make a custom data class that is serializable,
mark it using `@serializable` decorator and any properties using `@serialize` decorator.
```typescript
@serializable('DataClass')
class DataClass{
@serialize() prop1 = 1
@serialize() prop2 = 'string'
@serialize() prop3 = new Vector3()
@serialize() prop4 = new PhysicalMaterial()
@serialize() prop4 = {
prop1: 1,
prop2: 'string',
prop3: new Vector3(),
prop4: new PhysicalMaterial(),
}
}

const data = new DataClass()
const serialized = ThreeSerialization.serialize(data)
const deserialized = ThreeSerialization.deserialize(serialized)
```

The classes without a `@serializable` decorator are serialized as plain objects.
These can still include `@serialize` decorator to mark the properties are serializable
but these classes cannot be deserialized into a new instance of the class.
The ThreeViewer and plugins are an example of these.
When deserialized they need an object to deserialize into.
This ensures there is always just one instance.
With this, the serialization system works like `toJSON` and `fromJSON` methods in three.js.

Check the [plugin system](#plugin-system) below for more details on how to mark properties as serializable for plugins.

```typescript
class CustomClass{
@serialize() prop1 = 1
@serialize() prop2 = 'string'
@serialize() prop3 = new Vector3()
@serialize() prop4 = new PhysicalMaterial()
}
const obj = new DataClass()
const serialized = ThreeSerialization.serialize(data)
// now to deserialize we need to pass in the object to deserialize into
ThreeSerialization.deserialize(serialized, obj)
```

## toJSON and fromJSON

You can also implement the toJSON and fromJSON functions ot the class to customize the serialization and deserialization process.

```typescript
class MyClass{
// ...

toJSON(meta?: SerializationMetaType): ISerializedConfig {
const data: any = ThreeSerialization.Serialize(this, meta, true) // last param set to true to indicate not to call toJSON.
data.type = 'MyType'
data.assetType = 'config'
this.dispatchEvent({type: 'serialize', data}) // optional
return data
}

fromJSON(data: ISerializedConfig, meta?: SerializationMetaType): this|null|Promise<this|null> {
if (data.type !== 'MyType') return null
ThreeSerialization.Deserialize(data, this, meta, true) // last param set to true to indicate not to call fromJSON.
this.dispatchEvent({type: 'deserialize', data, meta}) // optional
return this
}
}
```

When calling `ThreeSerialization.Serialize` on an object of `MyClass`, it will call `toJSON` on the object and serialize the properties of the object. Similarly, when calling `ThreeSerialization.Deserialize` on an object of `MyClass`, it will call `fromJSON` on the object and deserialize the properties of the object.

### Extending classes

When extending classes that have `toJSON` and `fromJSON` methods(like three.js objects), you can call the super methods and then serialize the properties of the class.

```typescript
class MyMaterial extends ThreeMaterial{
// ...
/**
* Serializes this material to JSON.
* @param meta - metadata for serialization
* @param _internal - Calls only super.toJSON, does internal three.js serialization and @serialize tags. Set it to true only if you know what you are doing. This is used in Serialization->serializer->material
*/
toJSON(meta?: SerializationMetaType, _internal = false): any {
if (_internal) return {
...super.toJSON(meta),
...ThreeSerialization.Serialize(this, meta, true), // this will serialize the properties of this class(like defined with @serialize and @serialize attribute)
}
return ThreeSerialization.Serialize(this, meta, false) // this will call toJSON again, but with baseOnly=true, that's why we set isThis to false.
}

/**
* Deserializes the material from JSON.
* Note: some properties that are not serialized in Material.toJSON when they are default values (like side, alphaTest, blending, maps), they wont be reverted back if not present in JSON
* If _internal = true, Textures should be loaded and in meta.textures before calling this method.
* @param data
* @param meta
* @param _internal
*/
fromJSON(data: any, meta?: SerializationMetaType, _internal = false): this | null {
if (_internal) {
ThreeSerialization.Deserialize(data, this, meta, true)
return this.setValues(data) // todo remove this and add @serialize decorator to properties
}
this.dispatchEvent({type: 'beforeDeserialize', data, meta, bubbleToObject: true, bubbleToParent: true})
return this
}
}
```

+ 31
- 0
website/guide/threepipe-packages.md 파일 보기

@@ -0,0 +1,31 @@
---
prev:
text: 'Core Plugins'
link: './core-plugins'

#next:
# text: '@threepipe Packages'
# link: './threepipe-packages'
---

# @threepipe Packages

Additional packages and plugins are available with threepipe, and can be found in the [plugins](https://github.com/repalash/threepipe/tree/master/plugins) directory or in some external repository.

These add support for integrating with other libraries, adding new features, and other functionality with different licenses.

Checkout the [model-viewer](https://threepipe.org/examples/#model-viewer) or [tweakpane-editor](https://threepipe.org/examples/#tweakpane-editor) examples which use most of these plugins.

## List of all the packages

- [@threepipe/plugin-tweakpane](../package/plugin-tweakpane) Tweakpane UI Plugin. Renders a [tweakpane](https://tweakpane.github.io/docs/) UI attached to the viewer for any ui config object.
- [@threepipe/plugin-blueprintjs](../package/plugin-blueprintjs) BlueprintJs UI Plugin. Renders a [blueprintjs](https://blueprintjs.com/) ([React](https://react.dev/)) UI attached to the viewer for any ui config object.
- [@threepipe/plugin-tweakpane-editor](../package/plugin-tweakpane-editor) - Tweakpane Editor Plugin. Uses the tweakpane ui plugin to create a [full editor](https://threepipe.org/examples/tweakpane-editor).
- [@threepipe/plugin-configurator](../package/plugin-configurator) - Provides `MaterialConfiguratorPlugin` and `SwitchNodePlugin` to allow users to select variations
- [@threepipe/plugin-geometry-generator](../package/plugin-geometry-generator) - Generate parametric geometry types that can be re-generated from UI/API.
- [@threepipe/plugin-gltf-transform](../package/plugin-gltf-transform) - Plugin to transform gltf models like adding draco compression while exporting gltf files.
- [@threepipe/plugins-extra-importers](../package/plugins-extra-importers) - Plugin for loading more file types supported by various types of loaders in three.js.
- [@threepipe/plugin-network](../package/plugin-network) - Network/Cloud related plugin implementations for Threepipe - `AWSClientPlugin` and `TransfrSharePlugin`.
- [@threepipe/plugin-blend-importer](../package/plugin-blend-importer) - Blender to add support for loading .blend file (WIP)
- [@threepipe/plugin-gaussian-splatting](../package/plugin-gaussian-splatting) - Gaussian Splatting plugin for loading and rendering splat files (WIP)
- [@threepipe/plugin-svg-renderer](../package/plugin-svg-renderer) - Add support for exporting 3d scene as SVG (WIP) using [three-svg-renderer](https://www.npmjs.com/package/three-svg-renderer).

+ 126
- 0
website/guide/ui-config.md 파일 보기

@@ -0,0 +1,126 @@
---
prev:
text: 'Material Extension'
link: './material-extension'

next:
text: 'Serialization'
link: './serialization'
---

# UI Configuration

Almost all of the classes and plugins in Threepipe include [uiconfig.js](https://repalash.com/uiconfig.js/) support and can be used to create configuration UIs, 3d configurators and even full-editors.
The UIs are automatically generated based on the configuration object under `.uiConfig` property on all objects. These are of type [UiObjectConfig](https://repalash.com/uiconfig.js/interfaces/UiObjectConfig.html).
In some classes, the ui configs are also generated using typescript decorators.

The `uiConfig` is also added to all three.js objects and materials when they are added to the scene.

The UIs can be generated at runtime using any of the UI plugins like [TweakpaneUIPlugin](#threepipeplugin-tweakpane), [BlueprintJsUiPlugin](#threepipeplugin-blueprintjs)

An example showing how to create a UI for a material

```typescript
const ui = viewer.addPluginSync(TweakpaneUiPlugin)

const object = viewer.scene.getObjectByName('objectName');
const material = object.material as PhysicalMaterial;

ui.appendChild(material.uiConfig)
```

See it in action: https://threepipe.org/examples/#material-uiconfig/

Check more examples showing [Viewer UI](https://threepipe.org/examples/#viewer-uiconfig/), [Scene UI](https://threepipe.org/examples/#scene-uiconfig/), [Object UI](https://threepipe.org/examples/#object-uiconfig/), [Camera UI](https://threepipe.org/examples/#camera-uiconfig/)

::: info
[TweakpaneEditorPlugin](#threepipeplugin-tweakpane-editor) further uses the Tweakpane configuration panel along with various plugins to create an 3d editor.
:::

Custom UI configuration can be created to generate custom UI for the editor or tweaking.
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.

Here is a sample of extending the orbit controls class with decorators to automatically generate UI.
```typescript
@uiPanelContainer('Orbit Controls')
export class OrbitControlsWithUi extends OrbitControls implements IUiConfigContainer {
// for autocomplete
uiConfig?: UiObjectConfig<void, 'panel'>

@uiToggle() enabled = true

@uiToggle() dollyZoom = false
@uiToggle() enableDamping = true
@uiInput() dampingFactor = 0.08

@uiToggle() autoRotate = false
@uiInput() autoRotateSpeed = 2.0

@uiToggle() enableZoom = true
@uiInput() zoomSpeed = 0.15
@uiInput() maxZoomSpeed = 0.20

@uiToggle() enableRotate = true
@uiInput() rotateSpeed = 2.0

@uiToggle() enablePan = true
@uiInput() panSpeed = 1.0

@uiInput() autoPushTarget = false
@uiInput() autoPullTarget = false
@uiInput() minDistance = 0.35
@uiInput() maxDistance = 1000

@uiInput() minZoom = 0.01
@uiInput() maxZoom = 1000

@uiInput() minPolarAngle = 0
@uiInput() maxPolarAngle = Math.PI

@uiInput() minAzimuthAngle = -10000 // should be -Infinity but this breaks the UI
@uiInput() maxAzimuthAngle = 10000

}
```

Check out the full source code:
[./src/three/controls/OrbitControls3.ts](https://github.com/repalash/threepipe/blob/master/src/three/controls/OrbitControls3.ts) for proper implementation

See it in action: https://threepipe.org/examples/#camera-uiconfig/ Open the Camera UI and click on the Orbit Controls panel.

There are many available decorators like `uiToggle`, `uiSlider`, `uiInput`, `uiNumber`, `uiColor`, `uiImage`.
Check the complete list in the [uiconfig.js documentation](https://repalash.com/uiconfig.js/).

The UI configuration can also be created using json objects in both typescript and javascript
```javascript
const viewer = new ThreeViewer({...})

const ui = viewer.addPluginSync(TweakpaneUiPlugin)

const state = {
position: new Vector3(),
scale: 1,
}

ui.appendChild({
type: 'folder',
label: 'Custom UI',
children: [
{
type: 'vec3',
label: 'Position',
property: [state, 'position']
},
{
type: 'slider',
label: ()=>'Scale', // everything can be a function as well.
property: [state, 'scale'],
bounds: [1, 2],
stepSize: 0.1,
}
]
})
```

[//]: # (TODO: create example/codepen for this)


+ 1014
- 0
website/guide/viewer-api.md
파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
파일 보기


+ 102
- 0
website/index.md 파일 보기

@@ -0,0 +1,102 @@
---
# https://vitepress.dev/reference/default-theme-home-page
layout: home

hero:
name: "ThreePipe"
text: "3D on the Web\nMade Easy"
tagline: "Effortlessly create 3D web experiences, from quick demos to advanced applications, with Three.js"
image:
src: /logo.svg
alt: Threepipe
actions:
- theme: brand
text: About Threepipe
link: ./guide/introduction
- theme: alt
text: Examples
link: https://threepipe.org/examples
target: _blank
- theme: alt
text: Get Started
link: ./guide/getting-started
- theme: brand
text: 3D glTF Editor
link: https://editor.threepipe.org

features:
- title: Start quickly
details: Simple, intuitive API for creating 3D model viewers, configurators and editors on websites, with many built-in presets for common workflows and use-cases.
link: ./guide/getting-started
linkText: Get Started
- title: 3D and glTF Editor
details: Create, edit and configure 3D scenes in the browser. Provides a complete no-code flow to configure 3d models, configurators, animations etc
link: ./guide/editors
linkText: Learn More
- title: Modular Architecture
details: Modular architecture that allows you to easily extend the viewer, scene objects, materials, shaders, rendering, post-processing and serialization with custom functionality.
linkText: All Features
link: ./guide/features
- title: Free and Open Source
details: Threepipe is completely free and open source under the Apache license 2.0. You can use it for personal or commercial projects without any restrictions, with attribution.
link: https://github.com/repalash/threepipe/blob/master/LICENSE
rel: external
target: _blank
linkText: Apache License 2.0
- title: Plugin system
details: Plugin system along with a rich library of built-in plugins that allows you to add new features to the viewer, like post-processing, custom materials, etc.
linkText: Read More
link: ./guide/plugin-system
- title: Rendering Pipeline
details: Built-in post processing and modular rendering pipeline with included deferred rendering, post-processing, RGBM HDR rendering, etc
linkText: Read More
link: ./guide/render-pipeline
- title: Material Extension
details: A custom material extension framework to modify/inject/build custom shader code into existing materials at runtime from multiple plugins.
linkText: Read More
link: ./guide/material-extension
- title: Asset Management
details: Extendable asset import, export pipeline with support for gltf, glb, obj+mtl, fbx, mat(pmat/bmat), json, zip, png, jpeg, svg, webp, ktx2, ply, 3dm and many more.
linkText: File Formats
link: ./guide/features#file-formats
- title: Framework Agnostic
details: Can be used with any framework or library like React, Angular, Vue, Svelte, etc. or directly with vanilla JS/TS.
linkText: Get Started
link: ./guide/getting-started
- title: TypeScript, Autocomplete
details: Written in TypeScript with full type definitions and autocomplete support in modern IDEs.
link: https://github.com/repalash/threepipe
linkText: Read the source
- title: Serialization
details: Automatic serialization of all viewer and plugin settings in GLB(with custom extensions) and JSON formats.
linkText: Read More
link: ./guide/serialization
- title: Helpers and Optimizations
details: Three.js optimization and helpers for managing objects, states, maintaining references, disposing objects, etc.
linkText: Browse Features
link: ./guide/features
- title: UI Configuration
details: UiConfig compatibility to automatically generate configuration UIs for viewer, plugins and three.js object dynamically in the browser.
link: https://repalash.com/uiconfig.js/
rel: external
target: _blank
linkText: Read More
- title: 3D Model Viewer
details: Offline 3D model viewer app to quickly preview 3d models locally on MacOS/Windows with support for viewing and converting 25 file formats to glTF.
link: https://3dviewer.xyz/
linkText: Download App
target: _blank
- title: Advanced Rendering
details: Supports advanced rendering plugins like SSAO, WebGi plugins(SSR, Bloom, GI), path tracing, etc for industry specific apps.
link: https://webgi.xyz/
rel: external
target: _blank
linkText: Checkout WebGi
- title: Jewelery and Fashion
details: Compatibility with iJewel3D plugins for high-quality rendering and virtual try-on of jewelery, gemstones, diamonds, precious metals, fabric etc.
link: https://ijewel3d.com/
rel: external
target: _blank
linkText: Checkout iJewel3D

---

+ 50
- 0
website/package/plugin-blend-importer.md 파일 보기

@@ -0,0 +1,50 @@
---
prev:
text: '@threepipe/plugin-network'
link: './plugin-network'

next:
text: '@threepipe/plugin-gaussian-splatting'
link: './plugin-gaussian-splatting'

---

# @threepipe/plugin-blend-importer

Exports [BlendImporterPlugin](https://threepipe.org/plugins/blend-importer/docs/classes/BlendLoadPlugin.html) which adds support for loading .blend files.

It uses [js.blend](https://github.com/acweathersby/js.blend) for parsing blend file structure.

::: warning Note
This is still a WIP.
:::

Currently working: `Mesh`, `BufferGeometry` and basic `PointLight`.
To be added: `PhysicalMaterial`, `UnlitMaterial` (similar to blender-gltf-io plugin)

[Example](https://threepipe.org/examples/#blend-load/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/plugins/blend-importer/src/index.ts) &mdash;
[API Reference](https://threepipe.org/plugins/blend-importer/docs)

[![NPM Package](https://img.shields.io/npm/v/@threepipe/plugin-blend-importer.svg)](https://www.npmjs.com/package/@threepipe/plugin-blend-importer)

```bash
npm install @threepipe/plugin-blend-importer
```

```typescript
import {ThreeViewer} from 'threepipe'
import {BlendLoadPlugin} from '@threepipe/plugin-blend-importer'

const viewer = new ThreeViewer({...})
viewer.addPluginSync(BlendLoadPlugin)

// Now load any .blend file.
const model = await viewer.load<IObject3D>('path/to/file.blend')

// To load the file as a data url, use the correct mimetype
const model1 = await viewer.load<IObject3D>('data:application/x-blender;base64,...')

```

[//]: # ( TODO: The plugin should parse and references to other assets and find them relative to the .blend file or the current location.)

+ 47
- 0
website/package/plugin-blueprintjs.md 파일 보기

@@ -0,0 +1,47 @@
---
prev:
text: '@threepipe/plugin-tweakpane'
link: './plugin-tweakpane'

next:
text: '@threepipe/plugin-tweakpane-editor'
link: './plugin-tweakpane-editor'

---

# @threepipe/plugin-blueprintjs
[Blueprint.js](https://blueprintjs.com/) UI plugin for ThreePipe

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#blueprintjs-ui-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/plugins/blueprintjs/src/BlueprintJsUiPlugin.ts) &mdash;
[API Reference](https://threepipe.org/plugins/blueprintjs/docs/classes/BlueprintJsUiPlugin.html)


[![NPM Package](https://img.shields.io/npm/v/@threepipe/plugin-blueprintjs.svg)](https://www.npmjs.com/package/@threepipe/plugin-blueprintjs)

```bash
npm install @threepipe/plugin-blueprintjs
```

BlueprintJsUiPlugin adds support for using [uiconfig-blueprint](https://github.com/repalash/uiconfig-blueprint)
to create a configuration UI in applications using the [BlueprintJs](https://blueprintjs.com/) library.

The plugin takes the [uiconfig](https://github.com/repalash/uiconfig.js)
that's defined in the viewer and all the objects to automatically render a UI in the browser.

```typescript
import {IObject3D, ThreeViewer, TonemapPlugin} from 'threepipe'
import {BlueprintJsUiPlugin} from '@threepipe/plugin-blueprintjs'

const viewer = new ThreeViewer({...})

// Add the plugin
const plugin = viewer.addPluginSync(new BlueprintJsUiPlugin(true)) // true to show expanded the UI by default

// Add the UI for the viewer
plugin.appendChild(viewer.uiConfig)
// Add UI for some plugins
plugin.setupPlugins(TonemapPlugin, DropzonePlugin)
```

+ 73
- 0
website/package/plugin-configurator.md 파일 보기

@@ -0,0 +1,73 @@
---
prev:
text: '@threepipe/plugin-tweakpane-editor'
link: './plugin-tweakpane-editor'

next:
text: '@threepipe/plugin-geometry-generator'
link: './plugin-geometry-generator'

---

# @threepipe/plugin-configurator

Configurator Plugin implementations with basic UI for Threepipe.

Includes Material Configurator and Switch Node Configurator Plugins.

[![NPM Package](https://img.shields.io/npm/v/@threepipe/plugin-configurator.svg)](https://www.npmjs.com/package/@threepipe/plugin-configurator)

```bash
npm install @threepipe/plugin-configurator
```

## MaterialConfiguratorPlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#material-configurator-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/plugins/configurator/src/MaterialConfiguratorPlugin.ts) &mdash;
[API Reference](https://threepipe.org/plugins/configurator/docs/classes/MaterialConfiguratorPlugin.html)

MaterialConfiguratorPlugin adds a UI to configure and switch between different material variations.

The variations of materials are mapped to material names or uuids in the scene.
These variations can be applied to the materials in the scene. (This copies the properties to the same material instances instead of assigning new materials)
The plugin interfaces with the picking plugin and also provides uiConfig to show and edit the variations.
This functionality is inherited from [MaterialConfiguratorBasePlugin](https://threepipe.org/docs/classes/MaterialConfiguratorBasePlugin.html).

Additionally, this plugin adds a simple Grid UI in the DOM over the viewer canvas to show various material variations and allow the user to apply them.
The UI can also be used in the editor to edit the variations and apply them.

To use, simply add the plugin in the viewer and configure using the created UI and UI Config. Note that `PickingPlugin` is required to be added before this to allow configurator.

To create a custom configurator UI, use the `MaterialConfiguratorBasePlugin` directly and call the function `applyVariation`, `getPreview` and `addVariation` to apply and add variations respectively.

[//]: # (TODO Add Example for custom UI)

### SwitchNodePlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#switch-node-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/plugins/configurator/src/SwitchNodePlugin.ts) &mdash;
[API Reference](https://threepipe.org/plugins/configurator/docs/classes/SwitchNodePlugin.html)

SwitchNodePlugin adds a UI to configure and switch between different different object variations within a switch node object.

This plugin allows you to configure object variations with object names in a file and apply them in the scene.
Each SwitchNode is a parent object with multiple direct children. Only one child is visible at a time.
This works by toggling the `visible` property of the children of a parent object.
The plugin interfaces with the picking plugin and also provides uiConfig to show and edit the variations.
It also provides a function to create snapshot previews of individual variations. This creates a limited render of the object with the selected child visible.
To get a proper render, its better to render it offline and set the image as a preview.
This functionality is inherited from [SwitchNodeBasePlugin](https://threepipe.org/docs/classes/SwitchNodeBasePlugin.html).

Additionally, this plugin adds a simple Grid UI in the DOM over the viewer canvas to show various material variations and allow the user to apply them.
The UI can also be used in the editor to edit the variations and apply them.

To use, simply add the plugin in the viewer and configure using the created UI and UI Config. Note that `PickingPlugin` is required to be added before this to allow configurator.

To create a custom configurator UI, use the `SwitchNodeBasePlugin` directly and call the function `selectNode`, `getPreview` and `addNode` to apply and add variations respectively.

[//]: # (TODO Add Example for custom UI)

+ 58
- 0
website/package/plugin-gaussian-splatting.md 파일 보기

@@ -0,0 +1,58 @@
---
prev:
text: '@threepipe/plugin-blend-importer'
link: './plugin-blend-importer'

next:
text: '@threepipe/plugin-svg-renderer'
link: './plugin-svg-renderer'

---

# @threepipe/plugin-gaussian-splatting

Exports [GaussianSplattingPlugin](https://threepipe.org/plugins/gaussian-splatting/docs/classes/GaussianSplattingPlugin.html) which adds support for loading .blend files.

It uses [`three-gaussian-splat`](https://github.com/repalash/threepipe/blob/master/plugins/gaussian-splatting/src/three-gaussian-splat), a rewrite of [@zappar/three-guassian-splat](https://github.com/zappar-xr/three-gaussian-splat) (and [gsplat.js](https://github.com/huggingface/gsplat.js) and [antimatter15/splat](https://github.com/antimatter15/splat)) for loading splat files and rendering gaussian splats.

[Example](https://threepipe.org/examples/#splat-load/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/plugins/gaussian-splatting/src/index.ts) &mdash;
[API Reference](https://threepipe.org/plugins/gaussian-splatting/docs)

[![NPM Package](https://img.shields.io/npm/v/@threepipe/plugin-gaussian-splatting.svg)](https://www.npmjs.com/package/@threepipe/plugin-gaussian-splatting)

```bash
npm install @threepipe/plugin-gaussian-splatting
```

::: warning Note
This is still a WIP.
:::

Currently working:
* Importing .splat files (just array buffer of gaussian splat attributes)
* ThreeGaussianSplatPlugin (Same as GaussianSplattingPlugin), add importer and update events to the viewer
* GaussianSplatMaterialExtension for adding gaussian splat functionality to any material like Unlit, Physical
* GaussianSplatMesh a subclass of Mesh2 for holding the gaussian splat geometry and a material with gaussian splat extension. also handles basic raycast in the splat geometry. (assuming simple points)
* GaussianSplatGeometry holds the geometry data and and the sort worker. Computes correct bounding box and sphere.
* SplatLoader for loading splat files and creating the geometry and material.
* GaussianSplatMaterialUnlit, GaussianSplatMaterialRaw
* GaussianSplatMaterialPhysical, working but normals are hardcoded to 0,1,0

TBD:
* Exporting/embedding splat files into glb
* Rendering to depth/gbuffer
* Estimate normals/read from file
* Lighting in GaussianSplatMaterialPhysical

```typescript
import {ThreeViewer} from 'threepipe'
import {GaussianSplattingPlugin} from '@threepipe/plugin-gaussian-splatting'

const viewer = new ThreeViewer({...})
viewer.addPluginSync(GaussianSplattingPlugin)

// Now load any .splat file.
const model = await viewer.load<GaussianSplatMesh>('path/to/file.splat')

```

+ 61
- 0
website/package/plugin-geometry-generator.md 파일 보기

@@ -0,0 +1,61 @@
---
prev:
text: '@threepipe/plugin-configurator'
link: './plugin-configurator'

next:
text: '@threepipe/plugin-gltf-transform'
link: './plugin-gltf-transform'

---

# @threepipe/plugin-geometry-generator

Exports [GeometryGeneratorPlugin](https://threepipe.org/plugins/geometry-generator/docs/classes/BlendLoadPlugin.html) with several Geometry generators to create parametric and updatable geometries like plane, circle, sphere, box, torus, cylinder, cone etc.

[Example](https://threepipe.org/examples/#geometry-generator-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/plugins/geometry-generator/src/index.ts) &mdash;
[API Reference](https://threepipe.org/plugins/geometry-generator/docs)

[![NPM Package](https://img.shields.io/npm/v/@threepipe/plugin-geometry-generator.svg)](https://www.npmjs.com/package/@threepipe/plugin-geometry-generator)

```bash
npm install @threepipe/plugin-geometry-generator
```

The generated geometries/meshes include the parameters in the userData and can be re-generated by changing the parameters from the UI or the plugin API.

Includes the following generator which inherit from [AGeometryGenerator](https://threepipe.org/plugins/geometry-generator/docs/classes/AGeometryGenerator.html):
- **plane**: [PlaneGeometryGenerator](https://threepipe.org/plugins/geometry-generator/docs/classes/PlaneGeometryGenerator),
- **sphere**: [SphereGeometryGenerator](https://threepipe.org/plugins/geometry-generator/docs/classes/SphereGeometryGenerator),
- **box**: [BoxGeometryGenerator](https://threepipe.org/plugins/geometry-generator/docs/classes/BoxGeometryGenerator),
- **circle**: [CircleGeometryGenerator](https://threepipe.org/plugins/geometry-generator/docs/classes/CircleGeometryGenerator),
- **torus**: [TorusGeometryGenerator](https://threepipe.org/plugins/geometry-generator/docs/classes/TorusGeometryGenerator),
- **cylinder**: [CylinderGeometryGenerator](https://threepipe.org/plugins/geometry-generator/docs/classes/CylinderGeometryGenerator),


Sample Usage:

```typescript
import {ThreeViewer, UnlitMaterial} from 'threepipe'
import {GeometryGeneratorPlugin} from '@threepipe/plugin-geometry-generator'

const viewer = new ThreeViewer({...})
const generator = viewer.addPluginSync(GeometryGeneratorPlugin)

const sphere = generator.generateObject('sphere', {radius: 3})
viewer.scene.addObject(sphere)

// to update the geometry
generator.updateGeometry(sphere.geometry, {radius: 4, widthSegments: 100})

// to add a custom generator
generator.generators.custom = new CustomGenerator('custom') // Extend from AGeometryGenerator or implement GeometryGenerator interface
// refresh the ui so the new generator is available to select.
generator.uiConfig.uiRefresh?.()

// change the material type for all objects
generator.defaultMaterialClass = UnlitMaterial // by default its PhysicalMaterial
viewer.scene.addObject(generator.generateObject('box', {width: 2, height: 2, depth: 2}))

```

+ 49
- 0
website/package/plugin-gltf-transform.md 파일 보기

@@ -0,0 +1,49 @@
---
prev:
text: '@threepipe/plugin-geometry-generator'
link: './plugin-geometry-generator'

next:
text: '@threepipe/plugins-extra-importers'
link: './plugins-extra-importers'

---

# @threepipe/plugin-gltf-transform

Exports [GLTFDracoExportPlugin](https://threepipe.org/plugins/gltf-transform/docs/classes/GLTFDracoExportPlugin.html) that extends the default gltf exporter to compress the file after export.

[Example](https://threepipe.org/examples/#glb-draco-export/) &mdash;
[Source Code](plugins/gltf-transform/src/index.ts) &mdash;
[API Reference](https://threepipe.org/plugins/gltf-transform/docs)

[![NPM Package](https://img.shields.io/npm/v/@threepipe/plugin-gltf-transform.svg)](https://www.npmjs.com/package/@threepipe/plugin-gltf-transform)

```bash
npm install @threepipe/plugin-gltf-transform
```

To use, simply add the plugin to the viewer and export using the `viewer.export` or `viewer.exportScene` functions. This also adds UI options to `AssetExporterPlugin` which are used when exporting using the plugin or using `viewer.exportScene`

The plugin overloads the default gltf exporter in the asset manager with `GLTFDracoExporter`. Using the [gltf-transform](https://gltf-transform.donmccurdy.com/) library, it compresses the exported gltf file using the [khr_draco_mesh_compression](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_draco_mesh_compression/README.md) extension.

Note - Only `glb` export supported right now.

Sample Usage:

```typescript
import {ThreeViewer, downloadBlob} from 'threepipe'
import {GLTFDracoExportPlugin} from '@threepipe/plugin-gltf-transform'

const viewer = new ThreeViewer({...})
viewer.addPluginSync(GLTFDracoExportPlugin)

await viewer.load('file.glb')

const blob = await viewer.exportScene({
compress: true, // this must be specified, by default it's false.
viewerConfig: true, // to export with viewer, scene and plugin settings
})
// download the file
downloadBlob(blob, 'scene.glb')
```

+ 128
- 0
website/package/plugin-network.md 파일 보기

@@ -0,0 +1,128 @@
---
prev:
text: '@threepipe/plugins-extra-importers'
link: './plugins-extra-importers'

next:
text: '@threepipe/plugin-blend-importer'
link: './plugin-blend-importer'

---

# @threepipe/plugin-network

Network/Cloud related plugin implementations for Threepipe.

Includes `AWSClientPlugin` and `TransfrSharePlugin`.

[![NPM Package](https://img.shields.io/npm/v/@threepipe/plugin-network.svg)](https://www.npmjs.com/package/@threepipe/plugin-network)

```bash
npm install @threepipe/plugin-network
```

## TransfrSharePlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#transfr-share-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/plugins/network/src/TransfrSharePlugin.ts) &mdash;
[API Reference](https://threepipe.org/plugins/network/docs/classes/TransfrSharePlugin.html)

TransfrSharePlugin provides functionality to export and upload the scene or an object as glb and provide link to share/preview/edit the files.

It uses the options from the `AssetExporterPlugin` to export the scene or object, and can be configured using it's ui.

Uses the free service [transfr.one](https://transfr.one/) by default which deletes the files after a certain time, but the url can be changed to a custom backend or a self-hosted version of transfr.

::: tip Note
Since the uploaded files are publicly accessible by anyone by default, it is recommended to encrypt the file using the exporter options or use a secure backend.
:::

```typescript
import {ThreeViewer} from 'threepipe'
import {TransfrSharePlugin} from '@threepipe/plugin-network'

const viewer = new ThreeViewer({...})

// Add the plugin
const sharePlugin = viewer.addPluginSync(new TransfrSharePlugin())

// when sharing, this query param is set to the model link
sharePlugin.queryParam = 'm' // this is the default
// used when clicking/calling Share page link
sharePlugin.pageUrl = window.location.href // this is the default

// used when clicking/calling Share viewer link
sharePlugin.baseUrls.viewer = 'https://threepipe.org/examples/model-viewer/index.html'
// used when clicking/calling Share editor link
sharePlugin.baseUrls.editor = 'https://threepipe.org/examples/tweakpane-editor/index.html'

// set to a custom server
// sharePlugin.serverUrl = 'https://example.com/'

// upload and get the link of the 3d model
const link = await sharePlugin.getLink()
// or upload and get the share link with a base page. And also copy to clipboard and shows a alert prompt(using viewer.dialog)
const link2 = await sharePlugin.shareLink('https://example.com/custom_viewer')
// or get the editor link directly
const link3 = await sharePlugin.shareEditorLink()

// to encrypt
const assetExporterPlugin = viewer.getPlugin(AssetExporterPlugin) // this is a dependency, so automatically added
assetExporterPlugin.encrypt = true
// assetExporterPlugin.encryptKey = 'password' // user will be prompted for password when exporting if this is commented

await sharePlugin.shareViewerLink()
```

### AWSClientPlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#aws-client-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/plugins/network/src/AWSClientPlugin.ts) &mdash;
[API Reference](https://threepipe.org/plugins/network/docs/classes/AWSClientPlugin.html)

Provides `fetch` function that performs a fetch request with AWS v4 signing.
This is useful for connecting to AWS services like S3 directly from the client.
It also interfaces with the `FileTransferPlugin` to directly upload file when exported with the viewer or the plugin.

::: danger Note
Make sure to use keys with limited privileges and correct CORS settings.
All the keys will be stored in plain text if `serializeSettings` is set to true
:::

```typescript
import {ThreeViewer} from 'threepipe'
import {AWSClientPlugin} from '@threepipe/plugin-network'

const viewer = new ThreeViewer({...})

const awsPlugin = viewer.addPluginSync(new AWSClientPlugin())
// set parameters and export. This can all be done from the UI also.
awsPlugin.accessKeyId = '00000000000000000000'
awsPlugin.accessKeySecret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
awsPlugin.endpointURL = 'https://s3.amazonaws.com/bucket/'
awsPlugin.pathPrefix = 'some/path/'
// or load a json file with the parameters
// the json file can be creating by entering the data in the UI and clicking the download preset json option.
await viewer.load('file.json')

// this will export the scene as glb
const blob = await viewer.exportScene()

// for a plugin config
// blob = await viewer.export(viewer.getPlugin(GroundPlugin))
// for a material
// blob = await viewer.export(object.material)
// for an object/mesh
// blob = await viewer.export(object, {exportExt: 'glb'})

// upload to s3. needs the parameters to be correct
await viewer.exportBlob(blob, 'filename.glb')
```

::: tip Note
CORS should be enabled for the S3 bucket on the domain where the viewer is hosted. This requirement can be bypassed during development by setting `AWSClientPlugin.USE_PROXY = true`. A free proxy is already set by default and can be changed by setting `AWSClientPlugin.PROXY_URL`.
:::

+ 67
- 0
website/package/plugin-svg-renderer.md 파일 보기

@@ -0,0 +1,67 @@
---
prev:
text: '@threepipe/plugin-gaussian-splatting'
link: './plugin-gaussian-splatting'

next: false
---

# @threepipe/plugin-svg-renderer

Exports [ThreeSVGRendererPlugin](https://threepipe.org/plugins/svg-renderer/docs/classes/ThreeSVGRendererPlugin.html) and [BasicSVGRendererPlugin](https://threepipe.org/plugins/svg-renderer/docs/classes/BasicSVGRendererPlugin.html) which provide support for rendering the 3d scene as [SVG(Scalable Vector Graphics)](https://developer.mozilla.org/en-US/docs/Web/SVG). The generated SVG is compatible with browser rendering and other software like figma, illustrator etc.

[Example](https://threepipe.org/examples/#three-svg-renderer/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/plugins/svg-renderer/src/index.ts) &mdash;
[API Reference](https://threepipe.org/plugins/svg-renderer/docs) &mdash;
[GPLV3 License](https://github.com/repalash/threepipe/blob/master/plugins/svg-renderer/LICENSE)

[![NPM Package](https://img.shields.io/npm/v/@threepipe/plugin-network.svg)](https://www.npmjs.com/package/@threepipe/plugin-svg-renderer)

```bash
npm install @threepipe/plugin-svg-renderer
```

::: warning Note
This is still a WIP. API might change a bit
:::

`ThreeSVGRendererPlugin` uses [`three-svg-renderer`](https://github.com/repalash/threepipe/blob/master/plugins/svg-renderer/src/three-svg-renderer), which is a modified version of [three-svg-renderer](https://www.npmjs.com/package/three-svg-renderer) (GPLV3 Licenced).
The plugin renderers meshes in the viewer scene to svg objects by computing polygons and contours of the geometry in view space. Check [LokiResearch/three-svg-renderer](https://github.com/LokiResearch/three-svg-renderer?tab=readme-ov-file#references) for more details.
In the modified version that is used here, support for some types of geometries is added and a rendered image in screen-space is used to create raster fill images for paths along with some other small changes. Check out the [Example](https://threepipe.org/examples/#three-svg-renderer/) for demo. See also [svg-geometry-playground example](https://threepipe.org/examples/#svg-geometry-playground/) for usage with other plugins `PickingPlugin`, `TransformControlsPlugin` and `GeometryGeneratorPlugin`.

Note that this does not support all the features of three.js and may not work with all types of materials and geometries. Check the examples for a list of sample models that do and don't work.

`BasicSVGRendererPlugin` is a sample plugin using [SVGRenderer](https://threejs.org/docs/index.html?q=svg#examples/en/renderers/SVGRenderer) from three.js addons. This renders all triangles in the scene to separate svg paths. Check the three.js docs for more details. Check out the [Example](https://threepipe.org/examples/#basic-svg-renderer/) for demo.

```typescript
import {ThreeViewer} from 'threepipe'
import {ThreeSVGRendererPlugin} from '@threepipe/plugin-svg-renderer'

const viewer = new ThreeViewer({
...,
rgbm: false, // this is required
})
const svgRender = viewer.addPluginSync(ThreeSVGRendererPlugin)
svgRender.autoRender = true // automatically render when camera or any object changes.
svgRender.autoMakeSvgObjects = true // automatically create SVG objects for all meshes in the scene.
// svgRender.makeSVGObject(object) // manually create SVG object for an object. (if autoMakeSvgObjects is false)

// Now load or generate any 3d model. Make sure its not very big. And the meshes are optimized.
const model = await viewer.load<IOBject3D>('path/to/file.glb')

// clear the background of the viewer
viewer.scene.backgroundColor = null
viewer.scene.background = null
// disable damping to get better experience.
viewer.scene.mainCamera.controls!.enableDamping = false

// hide the canvas to see the underlying svg node.
// note: do not set the display to none or remove the canvas as OrbitControls and other plugins might still be tracking the canvas.
viewer.canvas.style.opacity = '0'

// 3d pipeline can also be disabled like this if `drawImageFills` is `false` to get better performance. Do this only after loading the model.
// await viewer.doOnce('postFrame') // wait for the first frame to be rendered (for autoScale etc)
// viewer.renderManager.autoBuildPipeline = false
// viewer.renderManager.pipeline = [] // this will disable main viewer rendering
```

+ 55
- 0
website/package/plugin-tweakpane-editor.md 파일 보기

@@ -0,0 +1,55 @@
---
prev:
text: '@threepipe/plugin-blueprintjs'
link: './plugin-blueprintjs'

next:
text: '@threepipe/plugin-configurator'
link: './plugin-configurator'

---

# @threepipe/plugin-tweakpane-editor

Tweakpane Editor Plugin for ThreePipe

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#tweakpane-editor/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/plugins/tweakpane-editor/src/TweakpaneEditorPlugin.ts) &mdash;
[API Reference](https://threepipe.org/plugins/tweakpane-editor/docs/classes/TweakpaneEditorPlugin.html)

[![NPM Package](https://img.shields.io/npm/v/@threepipe/plugin-tweakpane-editor.svg)](https://www.npmjs.com/package/@threepipe/plugin-tweakpane-editor)

```bash
npm install @threepipe/plugin-tweakpane-editor
```

`TweakpaneEditorPlugin` uses `TweakpaneUiPlugin` and other custom ui to create an editor for editing viewer, plugins, model and material configurations in the browser.

```typescript
import {IObject3D, ThreeViewer, TonemapPlugin} from 'threepipe'
import {TweakpaneEditorPlugin} from '@threepipe/plugin-tweakpane-editor'

const viewer = new ThreeViewer({...})

viewer.addPluginSync(new TweakpaneUiPlugin(true))
const editor = viewer.addPluginSync(new TweakpaneEditorPlugin())

// Add some plugins to the viewer
await viewer.addPlugins([
new ViewerUiConfigPlugin(),
// new SceneUiConfigPlugin(), // this is already in ViewerUiPlugin
new DepthBufferPlugin(HalfFloatType, true, true),
new NormalBufferPlugin(HalfFloatType, false),
new RenderTargetPreviewPlugin(false),
])

// Load the plugin UI in the editor and tweakpane ui with categories.
editor.loadPlugins({
['Viewer']: [ViewerUiConfigPlugin, SceneUiConfigPlugin, DropzonePlugin, FullScreenPlugin],
['GBuffer']: [DepthBufferPlugin, NormalBufferPlugin],
['Post-processing']: [TonemapPlugin],
['Debug']: [RenderTargetPreviewPlugin],
})
```

+ 44
- 0
website/package/plugin-tweakpane.md 파일 보기

@@ -0,0 +1,44 @@
---
prev: false
next:
text: '@threepipe/plugin-blueprintjs'
link: './plugin-blueprintjs'

---

# @threepipe/plugin-tweakpane

[Tweakpane](https://tweakpane.github.io/docs/) UI plugin for ThreePipe

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#tweakpane-ui-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/plugins/tweakpane/src/TweakpaneUiPlugin.ts) &mdash;
[API Reference](https://threepipe.org/plugins/tweakpane/docs/classes/TweakpaneUiPlugin.html)

[![NPM Package](https://img.shields.io/npm/v/@threepipe/plugin-tweakpane.svg)](https://www.npmjs.com/package/@threepipe/plugin-tweakpane)

```bash
npm install @threepipe/plugin-tweakpane
```

TweakpaneUiPlugin adds support for using [uiconfig-tweakpane](https://github.com/repalash/uiconfig-tweakpane)
to create a configuration UI in applications using the [Tweakpane](https://tweakpane.github.io/docs/) library.

The plugin takes the [uiconfig](https://github.com/repalash/uiconfig.js)
that's defined in the viewer and all the objects to automatically render a UI in the browser.

```typescript
import {IObject3D, ThreeViewer, TonemapPlugin} from 'threepipe'
import {TweakpaneUiPlugin} from '@threepipe/plugin-tweakpane'

const viewer = new ThreeViewer({...})

// Add the plugin
const plugin = viewer.addPluginSync(new TweakpaneUiPlugin(true)) // true to show expanded the UI by default

// Add the UI for the viewer
plugin.appendChild(viewer.uiConfig)
// Add UI for some plugins
plugin.setupPlugins(TonemapPlugin, DropzonePlugin)
```

+ 58
- 0
website/package/plugins-extra-importers.md 파일 보기

@@ -0,0 +1,58 @@
---
prev:
text: '@threepipe/plugin-gltf-transform'
link: './plugin-gltf-transform'

next:
text: '@threepipe/plugin-network'
link: './plugin-network'

---

# @threepipe/plugins-extra-importers

Exports several plugins to add support for various file types.

[Example](https://threepipe.org/examples/#extra-importer-plugins/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/plugins/extra-importers/src/index.ts) &mdash;
[API Reference](https://threepipe.org/plugins/extra-importers/docs)

[![NPM Package](https://img.shields.io/npm/v/@threepipe/plugins-extra-importers.svg)](https://www.npmjs.com/package/@threepipe/plugins-extra-importers)

```bash
npm install @threepipe/plugins-extra-importers
```

This package exports several plugins to add support for several file types using the following plugins

- [TDSLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/TDSLoadPlugin.html) - Load 3DS Max (.3ds) files
- [ThreeMFLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/ThreeMFLoadPlugin.html) - Load 3MF (.3mf) files
- [ColladaLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/ColladaLoadPlugin.html) - Load Collada (.dae) files
- [AMFLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/AMFLoadPlugin.html) - Load AMF (.amf) files
- [BVHLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/BVHLoadPlugin.html) - Load BVH (.bvh) files
- [VOXLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/VOXLoadPlugin.html) - Load MagicaVoxel (.vox) files
- [GCodeLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/GCodeLoadPlugin.html) - Load GCode (.gcode) files
- [MDDLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/MDDLoadPlugin.html) - Load MDD (.mdd) files
- [PCDLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/PCDLoadPlugin.html) - Load Point cloud data (.pcd) files
- [TiltLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/TiltLoadPlugin.html) - Load Tilt Brush (.tilt) files
- [VRMLLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/VRMLLoadPlugin.html) - Load VRML (.wrl) files
- [MPDLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/MPDLoadPlugin.html) - Load LDraw (.mpd) files
- [VTKLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/VTKLoadPlugin.html) - Load VTK (.vtk) files
- [XYZLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/XYZLoadPlugin.html) - Load XYZ (.xyz) files

To add all the plugins at once use `extraImporters`. This adds support for loading all the above file types.
```typescript
import {ThreeViewer} from 'threepipe'
import {extraImporters} from '@threepipe/plugins-extra-importers'

const viewer = new ThreeViewer({...})
viewer.addPluginsSync(extraImporters)

// Now load any file as is.
const model = await viewer.load<IObject3D>('file.3mf')

// To load the file as a data url, use the correct mimetype
const model1 = await viewer.load<IObject3D>('data:model/3mf;base64,...')
```

Remove the `<IObject3D>` if using javascript and not typescript.

+ 46
- 0
website/plugin/AssetExporterPlugin.md 파일 보기

@@ -0,0 +1,46 @@
---
prev:
text: 'FullScreenPlugin'
link: './FullScreenPlugin'

next:
text: 'FileTransferPlugin'
link: './FileTransferPlugin'

---

# AssetExporterPlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#asset-exporter-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/export/AssetExporterPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/AssetExporterPlugin.html)

Asset Exporter Plugin provides options and methods to export the scene, object GLB or Viewer Config.
All the functionality is available in the viewer(and `AssetExporter`) directly, this plugin only provides a ui-config and maintains state of the options which is saved as plugin configuration along with glb/vjson file

```typescript
import {ThreeViewer, AssetExporterPlugin} from 'threepipe'

const viewer = new ThreeViewer({...})

const assetExporter = viewer.addPluginSync(new AssetExporterPlugin())
// check the existing options
console.log(assetExporter.exportOptions)
// enable/disable viewer config/json embedding in glb
assetExporter.viewerConfig = true
// set encryption
assetExporter.encrypt = true
assetExporter.encryptKey = 'superstrongpassword' // comment this to get prompted for a key during export.

// export scene as blob
const blob = assetExporter.exportScene()
// or export and download directly
assetExporter.downloadSceneGlb()

// export a specific object
const object = viewer.scene.getObjectByName('objectName')
const blob2 = assetExporter.exportObject(object, true) // true to also download
```
Note: when downloading the model through the plugin, it uses viewer.export, which downloads the files by default, but uploads it to remote destinations when overloaded using `FileTransferPlugin`.

+ 75
- 0
website/plugin/CameraViewPlugin.md 파일 보기

@@ -0,0 +1,75 @@
---
prev:
text: 'PopmotionPlugin'
link: './PopmotionPlugin'

next:
text: 'TransformAnimationPlugin'
link: './TransformAnimationPlugin'

---

# CameraViewPlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#camera-view-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/animation/CameraViewPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/CameraViewPlugin.html)

CameraViewPlugin adds support to save and load camera views, which can then be animated to.
It uses PopmotionPlugin internally to animate any camera to a saved view or to loop through all the saved views.

It also provides a UI to manage the views.

```typescript
import {CameraViewPlugin, ThreeViewer, CameraView, Vector3, Quaternion, EasingFunctions, timeout} from 'threepipe'

const viewer = new ThreeViewer({...})

const cameraViewPlugin = viewer.addPluginSync(new CameraViewPlugin())

const intialView = cameraViewPlugin.getView()
// or = viewer.scene.mainCamera.getView()

// create a new view
const view = new CameraView(
'My View', // name
new Vector3(0, 0, 10), // position
new Vector3(0, 0, 0), // target
new Quaternion(0, 0, 0, 1), // quaternion rotation
1 // zoom
)

// or clone a view
const view2 = intialView.clone()
view2.position.add(new Vector3(0, 5, 0)) // move up 5 units

// animate the main camera to a view
await cameraViewPlugin.animateToView(
view,
2000, // in ms, = 2sec
EasingFunctions.easeInOut,
).catch(()=>console.log('Animation stopped'))

// stop any/all animations
cameraViewPlugin.stopAllAnimations()

// add views to the plugin
cameraViewPlugin.addView(view)
cameraViewPlugin.addView(view2)
cameraViewPlugin.addView(intialView)
cameraViewPlugin.addCurrentView() // adds the current view of the main camera

// loop through all the views once
cameraViewPlugin.animDuration = 2000 // default duration
cameraViewPlugin.animEase = EasingFunctions.easeInOutSine // default easing
await cameraViewPlugin.animateAllViews()

// loop through all the views forever
cameraViewPlugin.viewLooping = true
await timeout(10000) // wait for some time
// stop looping
cameraViewPlugin.viewLooping = false

```

+ 55
- 0
website/plugin/CanvasSnapshotPlugin.md 파일 보기

@@ -0,0 +1,55 @@
---
prev:
text: 'SSAOPlugin'
link: './SSAOPlugin'

next:
text: 'PickingPlugin'
link: './PickingPlugin'

---

# CanvasSnapshotPlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#canvas-snapshot-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/export/CanvasSnapshotPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/CanvasSnapshotPlugin.html)

Canvas Snapshot Plugin adds support for taking snapshots of the canvas and exporting them as images and data urls. It includes options to take snapshot of a region, mime type, quality render scale and scaling the output image. Check out the interface [CanvasSnapshotOptions](https://threepipe.org/docs/interfaces/CanvasSnapshotOptions.html) for more details.

```typescript
import {ThreeViewer, CanvasSnapshotPlugin} from 'threepipe'

const viewer = new ThreeViewer({...})

const snapshotPlugin = viewer.addPluginSync(new CanvasSnapshotPlugin())

// download a snapshot.
await snapshotPlugin.downloadSnapshot('image.webp', { // all parameters are optional
scale: 1, // scale the final image
timeout: 0, // wait before taking the snapshot, in ms
quality: 0.9, // quality of the image (0-1) only for jpeg and webp
displayPixelRatio: 2, // render scale
mimeType: 'image/webp', // mime type of the image
waitForProgressive: true, // wait for progressive rendering to finish (ProgressivePlugin). true by default
rect: { // region to take snapshot. eg. crop center of the canvas
height: viewer.canvas.clientHeight / 2,
width: viewer.canvas.clientWidth / 2,
x: viewer.canvas.clientWidth / 4,
y: viewer.canvas.clientHeight / 4,
},
})

// get data url (string)
const dataUrl = await snapshotPlugin.getDataUrl({ // all parameters are optional
displayPixelRatio: 2, // render scale
mimeType: 'image/webp', // mime type of the image
})

// get File
const file = await snapshotPlugin.getFile('file.jpeg', { // all parameters are optional
mimeType: 'image/jpeg', // mime type of the image
})
```

+ 32
- 0
website/plugin/ChromaticAberrationPlugin.md 파일 보기

@@ -0,0 +1,32 @@
---
prev:
text: 'VignettePlugin'
link: './VignettePlugin'

next:
text: 'FilmicGrainPlugin'
link: './FilmicGrainPlugin'

---

# ChromaticAberrationPlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#chromatic-aberration-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/postprocessing/ChromaticAberrationPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/ChromaticAberrationPlugin.html)

ChromaticAberrationPlugin adds a post-processing material extension to the ScreenPass in render manager
that applies a chromatic-aberration effect to the final render. The parameter `intensity` can be changed to customize the effect.

```typescript
import {ThreeViewer, ChromaticAberrationPlugin} from 'threepipe'

const viewer = new ThreeViewer({...})

const chromaticAberrationPlugin = viewer.addPluginSync(ChromaticAberrationPlugin)

// Change the chromaticAberration color
chromaticAberrationPlugin.intensity = 0.5
```

+ 45
- 0
website/plugin/ClearcoatTintPlugin.md 파일 보기

@@ -0,0 +1,45 @@
---
prev:
text: 'CustomBumpMapPlugin'
link: './CustomBumpMapPlugin'

next:
text: 'FragmentClippingExtensionPlugin'
link: './FragmentClippingExtensionPlugin'

---

# ClearcoatTintPlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#clearcoat-tint-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/material/ClearcoatTintPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/ClearcoatTintPlugin.html)

ClearcoatTintPlugin adds a material extension to PhysicalMaterial which adds tint and thickness to the built-in clearcoat properties.
It also adds a UI to the material to edit the settings.
It uses `WEBGI_materials_clearcoat_tint` glTF extension to save the settings in glTF/glb files.

```typescript
import {ThreeViewer, ClearcoatTintPlugin} from 'threepipe'

const viewer = new ThreeViewer({...})

const clearcoatTint = viewer.addPluginSync(ClearcoatTintPlugin)

material.clearcoat = 1
// add initial properties
ClearcoatTintPlugin.AddClearcoatTint(material, {
tintColor: '#ff0000',
thickness: 1,
})

// Change properties with code or use the UI
material.userData._clearcoatTint!.tintColor = '#ff0000'
material.setDirty()

// Disable
material.userData._clearcoatTint.enableTint = false
material.setDirty()
```

+ 32
- 0
website/plugin/ContactShadowGroundPlugin.md 파일 보기

@@ -0,0 +1,32 @@
---
prev:
text: 'TransformControlsPlugin'
link: './TransformControlsPlugin'

next:
text: 'GLTFAnimationPlugin'
link: './GLTFAnimationPlugin'

---

# ContactShadowGroundPlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#contact-shadow-ground-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/extras/ContactShadowGroundPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/ContactShadowGroundPlugin.html)

Contact Shadow Ground Plugin adds a ground plane with three.js contact shadows to the viewer scene.

The plane is added to the scene root at runtime and not saved with scene export. Instead the plugin settings are saved with the scene.

It inherits from the base class [BaseGroundPlugin](https://threepipe.org/docs/classes/BaseGroundPlugin.html) which provides generic ground plane functionality. Check the source code for more details. With the property `autoAdjustTransform`, the ground plane is automatically adjusted based on the bounding box of the scene.

```typescript
import {ThreeViewer, ContactShadowGroundPlugin} from 'threepipe'

const viewer = new ThreeViewer({...})

viewer.addPluginSync(new ContactShadowGroundPlugin())
```

+ 45
- 0
website/plugin/CustomBumpMapPlugin.md 파일 보기

@@ -0,0 +1,45 @@
---
prev:
text: 'NoiseBumpMaterialPlugin'
link: './NoiseBumpMaterialPlugin'

next:
text: 'ClearcoatTintPlugin'
link: './ClearcoatTintPlugin'

---

# CustomBumpMapPlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#custom-bump-map-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/material/CustomBumpMapPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/CustomBumpMapPlugin.html)

CustomBumpMapPlugin adds a material extension to PhysicalMaterial to support custom bump maps.
A Custom bump map is similar to the built-in bump map, but allows using an extra bump map and scale to give a combined effect.
This plugin also has support for bicubic filtering of the custom bump map and is enabled by default.
It also adds a UI to the material to edit the settings.
It uses `WEBGI_materials_custom_bump_map` glTF extension to save the settings in glTF/glb files.

```typescript
import {ThreeViewer, CustomBumpMapPlugin} from 'threepipe'

const viewer = new ThreeViewer({...})

const customBump = viewer.addPluginSync(CustomBumpMapPlugin)

// Add noise bump to a material
customBump.enableCustomBump(material, bumpMap, 0.2)

// Change properties with code or use the UI
material.userData._customBumpMat = texture
material.setDirty()

// Disable
material.userData._hasCustomBump = false
// or
material.userData._customBumpMat = null
material.setDirty()
```

+ 34
- 0
website/plugin/DepthBufferPlugin.md 파일 보기

@@ -0,0 +1,34 @@
---
prev:
text: 'SSAAPlugin'
link: './SSAAPlugin'

next:
text: 'NormalBufferPlugin'
link: './NormalBufferPlugin'

---

# DepthBufferPlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#depth-buffer-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/pipeline/DepthBufferPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/DepthBufferPlugin.html)

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.

```typescript
import {ThreeViewer, DepthBufferPlugin} from 'threepipe'

const viewer = new ThreeViewer({...})

const depthPlugin = viewer.addPluginSync(new DepthBufferPlugin(HalfFloatType))

const depthTarget = depthPlugin.target;

// Use the depth target by accesing `depthTarget.texture`.
```

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.

+ 41
- 0
website/plugin/DeviceOrientationControlsPlugin.md 파일 보기

@@ -0,0 +1,41 @@
---
prev:
text: 'Object3DGeneratorPlugin'
link: './Object3DGeneratorPlugin'

next:
text: 'PointerLockControlsPlugin'
link: './PointerLockControlsPlugin'

---

# DeviceOrientationControlsPlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#device-orientation-controls-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/interaction/DeviceOrientationControlsPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/DeviceOrientationControlsPlugin.html)

DeviceOrientationControlsPlugin enables controlling the main camera rotation in the scene with device orientation. This only works on devices which have a gyroscope(but can also be emulated in devtools in chrome).
After the plugin is added, it adds support for setting `deviceOrientation` as the key in `scene.mainCamera.controlMode`.

When the controls is started (for the first time), the current camera rotation is and the device orientation is saved and used as reference. To reset the saved device orientation, call `resetView` in the controls.

Sample Usage
```typescript
import {ThreeViewer, DeviceOrientationControlsPlugin, Mesh2} from 'threepipe'

const viewer = new ThreeViewer({...})

viewer.addPluginSync(DeviceOrientationControlsPlugin)

// after some user action
viewer.scene.mainCamera.controlsMode = 'deviceOrientation'

// to reset the saved device orientation
viewer.scene.mainCamera.controls.resetView()

// switch back to default orbit controls
viewer.scene.mainCamera.controlsMode = 'orbit'
```

+ 54
- 0
website/plugin/DropzonePlugin.md 파일 보기

@@ -0,0 +1,54 @@
---
prev:
text: 'TonemapPlugin'
link: './TonemapPlugin'

next:
text: 'ProgressivePlugin'
link: './ProgressivePlugin'

---

# DropzonePlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#dropzone-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/interaction/DropzonePlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/DropzonePlugin.html)

DropzonePlugin adds support for drag and drop of local files to automatically import, process and load them into the viewer.

DropzonePlugin can be added by default in ThreeViewer
by setting the `dropzone` property to `true` or an object of `DropzonePluginOptions` in the options.

```typescript
import {DropzonePlugin, ThreeViewer} from 'threepipe'
const viewer = new ThreeViewer({
canvas: document.getElementById('mcanvas') as HTMLCanvasElement,
dropzone: true, // just set to true to enable drag drop functionatility in the viewer
})
```

To set custom options,
pass an object of [DropzonePluginOptions](https://threepipe.org/docs/interfaces/DropzonePluginOptions.html) type to the `dropzone` property.
```typescript
import {DropzonePlugin, ThreeViewer} from 'threepipe'
const viewer = new ThreeViewer({
canvas: document.getElementById('mcanvas') as HTMLCanvasElement,
dropzone: { // this can also be set to true and configured by getting a reference to the DropzonePlugin
allowedExtensions: ['gltf', 'glb', 'hdr', 'png', 'jpg', 'json', 'fbx', 'obj', 'bin', 'exr'], // only allow these file types. If undefined, all files are allowed.
addOptions: {
disposeSceneObjects: true, // auto dispose of old scene objects
autoSetEnvironment: true, // when hdr is dropped
autoSetBackground: true, // when any image is dropped
autoCenter: true, // auto center the object
autoScale: true, // auto scale according to radius
autoScaleRadius: 2,
license: 'Imported from dropzone', // Any license to set on imported objects
importConfig: true, // import config from file
},
// check more options in the DropzonePluginOptions interface
},
})
```

+ 33
- 0
website/plugin/EditorViewWidgetPlugin.md 파일 보기

@@ -0,0 +1,33 @@
---
prev:
text: 'VirtualCamerasPlugin'
link: './VirtualCamerasPlugin'

next:
text: 'Object3DWidgetsPlugin'
link: './Object3DWidgetsPlugin'

---

# EditorViewWidgetPlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#editor-view-widget-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/interaction/EditorViewWidgetPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/EditorViewWidgetPlugin.html)

EditorViewWidgetPlugin adds a ViewHelper in the parent of the viewer canvas to show the current camera view and allow the user to change the camera view to one of the primary world axes.

Simply add the plugin to the viewer to see the widget.

```typescript
import {ThreeViewer, EditorViewWidgetPlugin} from 'threepipe'

const viewer = new ThreeViewer({...})

const plugin = viewer.addPluginSync(new EditorViewWidgetPlugin())

// to hide the widget
plugin.enabled = false
```

+ 23
- 0
website/plugin/FileTransferPlugin.md 파일 보기

@@ -0,0 +1,23 @@
---
prev:
text: 'AssetExporterPlugin'
link: './AssetExporterPlugin'

next:
text: 'LoadingScreenPlugin'
link: './LoadingScreenPlugin'

---

# FileTransferPlugin

[//]: # (todo: image)

[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/export/FileTransferPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/FileTransferPlugin.html)

Provides a way to extend the viewer.export functionality with custom actions. It also maintains a process state for plugins like `LoadingScreenPlugin`.

This plugin is added automatically, there is no need to use it manually, unless writing a plugin to extend the export functionality.

Used in eg `AWSClientPlugin` to upload files directly to S3.

+ 33
- 0
website/plugin/FilmicGrainPlugin.md 파일 보기

@@ -0,0 +1,33 @@
---
prev:
text: 'ChromaticAberrationPlugin'
link: './ChromaticAberrationPlugin'

next:
text: 'NoiseBumpMaterialPlugin'
link: './NoiseBumpMaterialPlugin'

---

# FilmicGrainPlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#filmic-grain-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/postprocessing/FilmicGrainPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/FilmicGrainPlugin.html)

FilmicGrainPlugin adds a post-processing material extension to the ScreenPass in render manager
that applies a filmic-grain effect to the final render. The parameters `power` and `color` can be changed to customize the effect.

```typescript
import {ThreeViewer, FilmicGrainPlugin} from 'threepipe'

const viewer = new ThreeViewer({...})

const filmicGrainPlugin = viewer.addPluginSync(FilmicGrainPlugin)

// Change the filmicGrain color
filmicGrainPlugin.intensity = 10
filmicGrainPlugin.multiply = false
```

+ 46
- 0
website/plugin/FragmentClippingExtensionPlugin.md 파일 보기

@@ -0,0 +1,46 @@
---
prev:
text: 'ClearcoatTintPlugin'
link: './ClearcoatTintPlugin'

next:
text: 'ParallaxMappingPlugin'
link: './ParallaxMappingPlugin'

---

# FragmentClippingExtensionPlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#fragment-clipping-extension-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/material/FragmentClippingExtensionPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/FragmentClippingExtensionPlugin.html)

FragmentClippingExtensionPlugin adds a material extension to PhysicalMaterial to add support for fragment clipping.
Fragment clipping allows to clip fragments of the material in screen space or world space based on a circle, rectangle, plane, sphere, etc.
It uses fixed SDFs with params defined by the user for clipping.
It also adds a UI to the material to edit the settings.
It uses `WEBGI_materials_fragment_clipping_extension` glTF extension to save the settings in glTF/glb files.

```typescript
import {ThreeViewer, FragmentClippingExtensionPlugin} from 'threepipe'

const viewer = new ThreeViewer({...})

const fragmentClipping = viewer.addPluginSync(FragmentClippingExtensionPlugin)

// add initial properties
FragmentClippingExtensionPlugin.AddFragmentClipping(material, {
clipPosition: new Vector4(0.5, 0.5, 0, 0),
clipParams: new Vector4(0.1, 0.05, 0, 1),
})

// Change properties with code or use the UI
material.userData._fragmentClipping!.clipPosition.set(0, 0, 0, 0)
material.setDirty()

// Disable
material.userData._clearcoatTint.clipEnabled = false
material.setDirty()
```

+ 38
- 0
website/plugin/FrameFadePlugin.md 파일 보기

@@ -0,0 +1,38 @@
---
prev:
text: 'GeometryUVPreviewPlugin'
link: './GeometryUVPreviewPlugin'

next:
text: 'VignettePlugin'
link: './VignettePlugin'

---

# FrameFadePlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#frame-fade-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/pipeline/FrameFadePlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/FrameFadePlugin.html)

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.

```typescript
import {ThreeViewer, FrameFadePlugin} from 'threepipe'

const viewer = new ThreeViewer({...})

const fadePlugin = viewer.addPluginSync(new FrameFadePlugin())

// Make some changes in the scene (any visual change that needs to be faded)

// Start transition and wait for it to finish
await fadePlugin.startTransition(400) // duration in ms

```

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.

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.

+ 37
- 0
website/plugin/FullScreenPlugin.md 파일 보기

@@ -0,0 +1,37 @@
---
prev:
text: 'PickingPlugin'
link: './PickingPlugin'

next:
text: 'AssetExporterPlugin'
link: './AssetExporterPlugin'

---

# FullScreenPlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#fullscreen-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/interaction/FullScreenPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/FullScreenPlugin.html)

A simple plugin that provides functions to enter, exit and toggle full screen mode and check if the viewer is in full screen mode. Either the canvas or the whole container can be set to full screen.

```typescript
import {ThreeViewer, FullScreenPlugin} from 'threepipe'

const viewer = new ThreeViewer({...})

const fullscreen = viewer.addPluginSync(new FullScreenPlugin())

// enter full screen
await fullscreen.enter(viewer.container) // viewer.canvas is used if no element is passed
// exit full screen
await fullscreen.exit()
// toggle
await fullscreen.toggle(viewer.container)
// check if full screen
console.log(fullScreenPlugin.isFullScreen())
```

+ 32
- 0
website/plugin/GBufferPlugin.md 파일 보기

@@ -0,0 +1,32 @@
---
prev:
text: 'NormalBufferPlugin'
link: './NormalBufferPlugin'

next:
text: 'SSAOPlugin'
link: './SSAOPlugin'

---

# GBufferPlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#gbuffer-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/pipeline/GBufferPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/GBufferPlugin.html)

GBuffer Plugin adds a pre-render pass to the render manager and renders depth+normals to a target and some customizable flags to another. The multiple render target and textures can be accessed by other plugins throughout the rendering pipeline to create effects like SSAO, SSR, etc.

```typescript
import {ThreeViewer, GBufferPlugin} from 'threepipe'

const viewer = new ThreeViewer({...})

const gBufferPlugin = viewer.addPluginSync(new GBufferPlugin())

const gBuffer = gBufferPlugin.target;
const normalDepth = gBufferPlugin.normalDepthTexture;
const gBufferFlags = gBufferPlugin.flagsTexture;
```

+ 29
- 0
website/plugin/GLTFAnimationPlugin.md 파일 보기

@@ -0,0 +1,29 @@
---
prev:
text: 'ContactShadowGroundPlugin'
link: './ContactShadowGroundPlugin'

next:
text: 'PopmotionPlugin'
link: './PopmotionPlugin'

---

# GLTFAnimationPlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#gltf-animation-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/animation/GLTFAnimationPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/GLTFAnimationPlugin.html)

Manages playback of GLTF animations.

The GLTF animations can be created in any 3d software that supports GLTF export like Blender.
If animations from multiple files are loaded, they will be merged in a single root object and played together.

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.

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.

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

+ 48
- 0
website/plugin/GLTFKHRMaterialVariantsPlugin.md 파일 보기

@@ -0,0 +1,48 @@
---
prev:
text: 'ThreeFirstPersonControlsPlugin'
link: './ThreeFirstPersonControlsPlugin'

next:
text: 'Rhino3dmLoadPlugin'
link: './Rhino3dmLoadPlugin'

---

# GLTFKHRMaterialVariantsPlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#gltf-khr-material-variants-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/extras/GLTFKHRMaterialVariantsPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/GLTFKHRMaterialVariantsPlugin.html)

GLTFKHRMaterialVariantsPlugin adds support for importing and exporting glTF models with the `KHR_materials_variants` extension to load the model with different material variants/combinations. It also provides API and UI to change the current material variant.

The plugin automatically adds support for the extension when added to the viewer.

The materials are stored in `object.userData._variantMaterials` and are automatically loaded and saved when using the `GLTFLoader`.

Sample Usage
```typescript
import {ThreeViewer, GLTFKHRMaterialVariantsPlugin, Mesh2} from 'threepipe'

const viewer = new ThreeViewer({...})

const variantsPlugin = viewer.addPluginSync(GLTFKHRMaterialVariantsPlugin)

// load some model
await viewer.load(model_url)

// list of all variants in the model (names and objects)
console.log(variantsPlugin.variants)

// change the selected variant
variantsPlugin.selectedVariant = 'beach'
```

## Links

- https://www.khronos.org/blog/blender-gltf-i-o-support-for-gltf-pbr-material-extensions
- https://www.khronos.org/blog/streamlining-3d-commerce-with-material-variant-support-in-gltf-assets
- https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_variants/README.md

+ 27
- 0
website/plugin/GLTFMeshOptDecodePlugin.md 파일 보기

@@ -0,0 +1,27 @@
---
prev:
text: 'KTXLoadPlugin'
link: './KTXLoadPlugin'

next:
text: 'SimplifyModifierPlugin'
link: './SimplifyModifierPlugin'

---

# GLTFMeshOptDecodePlugin

[Example](https://threepipe.org/examples/#gltf-meshopt-compression/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/import/GLTFMeshOptDecodePlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/GLTFMeshOptDecodePlugin.html)

Loads the MeshOpt Decoder module from [meshoptimizer](https://github.com/zeux/meshoptimizer) library at runtime from a customisable cdn url.
The loaded module is set in `window.MeshoptDecoder` and then used by `GLTFLoader2` to decode files using [EXT_meshopt_compression](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Vendor/EXT_meshopt_compression/README.md) extension

```typescript
import {GLTFMeshOptDecodePlugin} from 'threepipe'
const plugin = viewer.addPluginSync(new GLTFMeshOptDecodePlugin())
// await plugin.initialize() // optional, this happens when loading a gltf file with extension anyway

const texture = await viewer.load('file.glb')
```

+ 33
- 0
website/plugin/GeometryUVPreviewPlugin.md 파일 보기

@@ -0,0 +1,33 @@
---
prev:
text: 'RenderTargetPreviewPlugin'
link: './RenderTargetPreviewPlugin'

next:
text: 'FrameFadePlugin'
link: './FrameFadePlugin'

---

# GeometryUVPreviewPlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#geometry-uv-preview/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/ui/GeometryUVPreviewPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/GeometryUVPreviewPlugin.html)

GeometryUVPreviewPlugin is a useful development and debugging plugin
that adds a panel to the viewer to show the UVs of a geometry.

```typescript
import {ThreeViewer, GeometryUVPreviewPlugin, SphereGeometry} from 'threepipe'

const viewer = new ThreeViewer({...})

const previewPlugin = viewer.addPluginSync(new GeometryUVPreviewPlugin())

const geometry = new SphereGeometry(1, 32, 32)
// Show the normal buffer in a panel
previewPlugin.addGeometry(geometry, 'sphere')
```

+ 45
- 0
website/plugin/HDRiGroundPlugin.md 파일 보기

@@ -0,0 +1,45 @@
---
prev:
text: 'ParallaxMappingPlugin'
link: './ParallaxMappingPlugin'

next:
text: 'VirtualCamerasPlugin'
link: './VirtualCamerasPlugin'

---

# HDRiGroundPlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#hdri-ground-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/extras/HDRiGroundPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/HDRiGroundPlugin.html)

HDRiGroundPlugin patches the background shader in the renderer to add support for ground projected environment map/skybox. Works simply by setting the background same as the environemnt and enabling the plugin.

The world radius, tripod height, and origin position(center offset) can be set in the plugin.

The plugin is disabled by default when added. Set `.enabled` to enable it or pass `true` in the constructor.
If the background is not the same as the environment when enabled, the user will be prompted for this, unless `promptOnBackgroundMismatch` is set to `false` in the plugin.

```typescript
import {ThreeViewer, HDRiGrounPlugin} from 'threepipe'

const viewer = new ThreeViewer({...})

const hdriGround = viewer.addPluginSync(new HDRiGrounPlugin())

// Load an hdr environment map
await viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr')
// set background to environment
viewer.scene.background = 'environment'
// or
// viewer.scene.background = viewer.scene.environemnt

// enable the plugin
hdriGround.enabled = true
```

Check the [example](https://threepipe.org/examples/#hdri-ground-plugin/) for a demo.

+ 51
- 0
website/plugin/InteractionPromptPlugin.md 파일 보기

@@ -0,0 +1,51 @@
---
prev:
text: 'LoadingScreenPlugin'
link: './LoadingScreenPlugin'

next:
text: 'TransformControlsPlugin'
link: './TransformControlsPlugin'

---

# InteractionPromptPlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#interaction-prompt-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/interaction/InteractionPromptPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/InteractionPromptPlugin.html)

Interaction Prompt Plugin adds a hand pointer icon over the canvas that moves to prompt the user to interact with the 3d scene. To use, simply add the plugin to the viewer.

The default pointer icon from [google/model-viewer](https://github.com/google/model-viewer) and can be configured with the `pointerIcon` property.

The pointer is automatically shown when some object is in the scene and the camera is not moving.

The animation starts after a delay and stops on user interaction. It then restarts after a delay after the user stops interacting

The plugin provides several options and functions to configure the automatic behaviour or trigger the animation manually.

```typescript
import {ThreeViewer, InteractionPromptPlugin} from 'threepipe'

const viewer = new ThreeViewer({...})

const interactionPrompt = viewer.addPluginSync(new InteractionPromptPlugin())

// change duration
interactionPrompt.animationDuration = 3000
// change animation distance in pixels
interactionPrompt.animationDistance = 100

// disable auto start when the camera stops
interactionPrompt.autoStart = false
interactionPrompt.autoStop = false
// manually start and stop
interactionPrompt.startAnimation()
// ...
interactionPrompt.stopAnimation()
```

Note - The pointer is automatically shown/hidden when animation is started/stopped.

+ 27
- 0
website/plugin/KTX2LoadPlugin.md 파일 보기

@@ -0,0 +1,27 @@
---
prev:
text: 'STLLoadPlugin'
link: './STLLoadPlugin'

next:
text: 'KTXLoadPlugin'
link: './KTXLoadPlugin'

---

# KTX2LoadPlugin

[Example](https://threepipe.org/examples/#ktx2-load/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/import/KTX2LoadPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/KTX2LoadPlugin.html)

Adds support for loading .ktx2 ([Khronos Texture](https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/) files with asset manager and embedded in glTF files.

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.

```typescript
import {KTX2LoadPlugin} from 'threepipe'
viewer.addPluginSync(new KTX2LoadPlugin())

const texture = await viewer.load('file.ktx2')
```

+ 27
- 0
website/plugin/KTXLoadPlugin.md 파일 보기

@@ -0,0 +1,27 @@
---
prev:
text: 'KTX2LoadPlugin'
link: './KTX2LoadPlugin'

next:
text: 'GLTFMeshOptDecodePlugin'
link: './GLTFMeshOptDecodePlugin'

---

# KTXLoadPlugin

[Example](https://threepipe.org/examples/#ktx-load/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/import/KTXLoadPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/KTXLoadPlugin.html)

Adds support for loading .ktx ([Khronos Texture](https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/) files.

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.

```typescript
import {KTXLoadPlugin} from 'threepipe'
viewer.addPluginSync(new KTXLoadPlugin())

const texture = await viewer.load('file.ktx')
```

+ 39
- 0
website/plugin/LoadingScreenPlugin.md 파일 보기

@@ -0,0 +1,39 @@
---
prev:
text: 'FileTransferPlugin'
link: './FileTransferPlugin'

next:
text: 'InteractionPromptPlugin'
link: './InteractionPromptPlugin'

---

# LoadingScreenPlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#loading-screen-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/interaction/LoadingScreenPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/LoadingScreenPlugin.html)

Loading Screen Plugin adds configurable overlay with a logo, loading text, spinner and the list of loading items. It also provides options to minimize and maximize the loading popup when there is no objects in the scene.

The overlay is automatically added to the viewer container and shown when any files are loading. Behaviour can be configured to change how its shown and hidden, and can even be triggered programmatically.

```typescript
import {ThreeViewer, LoadingScreenPlugin} from 'threepipe'

const viewer = new ThreeViewer({...})

const loadingScreen = viewer.addPluginSync(new LoadingScreenPlugin())
loadingScreen.loadingTextHeader = 'Loading Helmet 3D Model'
loadingScreen.errorTextHeader = 'Error Loading Helmet 3D Model'
loadingScreen.showFileNames = true
loadingScreen.showProcessStates = true
loadingScreen.showProgress = true
loadingScreen.backgroundOpacity = 0.4 // 0-1
loadingScreen.backgroundBlur = 28 // px
```

See also the base class [AAssetManagerProcessStatePlugin](https://threepipe.org/docs/classes/AAssetManagerProcessStatePlugin.html) to write a custom loading plugin.

+ 24
- 0
website/plugin/MeshOptSimplifyModifierPlugin.md 파일 보기

@@ -0,0 +1,24 @@
---
prev:
text: 'SimplifyModifierPlugin'
link: './SimplifyModifierPlugin'

next: false
---

# MeshOptSimplifyModifierPlugin

[Example](https://threepipe.org/examples/#meshopt-simplify-modifier-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/extras/MeshOptSimplifyModifierPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/MeshOptSimplifyModifierPlugin.html)

Simplify modifier using [meshoptimizer](https://github.com/zeux/meshoptimizer) library. It Loads the library at runtime from a customisable CDN URL.

Note: It does not guarantee that the geometry will be simplified to the exact target count.

```typescript
const simplifyModifier = viewer.addPluginSync(new MeshOptSimplifyModifierPlugin())

const root = await viewer.load('file.glb')
simplifyModifier.simplifyAll(root, {factor: 0.75})
```

+ 44
- 0
website/plugin/NoiseBumpMaterialPlugin.md 파일 보기

@@ -0,0 +1,44 @@
---
prev:
text: 'FilmicGrainPlugin'
link: './FilmicGrainPlugin'

next:
text: 'CustomBumpMapPlugin'
link: './CustomBumpMapPlugin'

---

# NoiseBumpMaterialPlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#noise-bump-material-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/material/NoiseBumpMaterialPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/NoiseBumpMaterialPlugin.html)

NoiseBumpMaterialPlugin adds a material extension to PhysicalMaterial to add support for sparkle bump / noise bump by creating procedural bump map from noise to simulate sparkle flakes.
It uses voronoise function from blender along with several additions to generate the noise for the generation.
It also adds a UI to the material to edit the settings.
It uses `WEBGI_materials_noise_bump` glTF extension to save the settings in glTF/glb files.

```typescript
import {ThreeViewer, NoiseBumpMaterialPlugin} from 'threepipe'

const viewer = new ThreeViewer({...})

const noiseBump = viewer.addPluginSync(NoiseBumpMaterialPlugin)

// Add noise bump to a material
NoiseBumpMaterialPlugin.AddNoiseBumpMaterial(material, {
flakeScale: 300,
})

// Change properties with code or use the UI
material.userData._noiseBumpMat!.bumpNoiseParams = [1, 1]
material.setDirty()

// Disable
material.userData._noiseBumpMat!.hasBump = false
material.setDirty()
```

+ 36
- 0
website/plugin/NormalBufferPlugin.md 파일 보기

@@ -0,0 +1,36 @@
---
prev:
text: 'DepthBufferPlugin'
link: './DepthBufferPlugin'

next:
text: 'GBufferPlugin'
link: './GBufferPlugin'

---

# NormalBufferPlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#normal-buffer-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/pipeline/NormalBufferPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/NormalBufferPlugin.html)

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.

::: info NOTE
Use [`GBufferPlugin`](#GBufferPlugin) if using both `DepthBufferPlugin` and `NormalBufferPlugin` to render both depth and normal buffers in a single pass.
:::

```typescript
import {ThreeViewer, NormalBufferPlugin} from 'threepipe'

const viewer = new ThreeViewer({...})

const normalPlugin = viewer.addPluginSync(new NormalBufferPlugin())

const normalTarget = normalPlugin.target;

// Use the normal target by accessing `normalTarget.texture`.
```

+ 65
- 0
website/plugin/Object3DGeneratorPlugin.md 파일 보기

@@ -0,0 +1,65 @@
---
prev:
text: 'Object3DWidgetsPlugin'
link: './Object3DWidgetsPlugin'

next:
text: 'DeviceOrientationControlsPlugin'
link: './DeviceOrientationControlsPlugin'

---

# Object3DGeneratorPlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#object3d-generator-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/extras/Object3DGeneratorPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/Object3DGeneratorPlugin.html)

Object3DGeneratorPlugin adds support for creating different types of lights and camera objects in the viewer.
Call the `generate` method with any type to generate a type of object(like lights, cameras, mesh etc).

Support for the following types of generators is included in the plugin:
* camera-perspective - Creates instance of `PerspectiveCamera2`
* light-directional - Creates instance of `DirectionalLight2`
* light-ambient - Creates instance of `AmbientLight2`
* light-point - Creates instance of `PointLight2`
* light-spot - Creates instance of `SpotLight2`
* light-hemisphere - Creates instance of `HemisphereLight2`
* light-rect-area - Creates instance of `RectAreaLight2`

Additional types of generators can be added dynamically or by other plugins by adding a custom generator function to the `Object3DGeneratorPlugin.generators` object. This is done by [GeometryGeneratorPlugin](#threepipeplugin-geometry-generator) to add various type of primitive objects like plane, sphere, etc
A custom generator can take in any kind object as parameters and should return an `IObject3D`.

Sample Usage
```typescript
import {ThreeViewer, Object3DWidgetsPlugin, Object3DGeneratorPlugin, Mesh2} from 'threepipe'

const viewer = new ThreeViewer({...})

const generator = viewer.addPluginSync(Object3DGeneratorPlugin)
generator.generate('camera-perspective', {
position: new Vector3(5, 5, 0),
name: 'My Camera'
})
const light = generator.generate('light-spot', {
position: new Vector3(5, 0, 0),
})

// to add support for a custom helper
plugin.generators['custom-object'] = (params)=>{
const object = new Mesh2(new PlaneGeometry(1,1), new PhysicalMaterial())
object.name = params.name ?? 'Custom Mesh'
if(params.position) object.position.copy(params.position)
return object
}
const obj = generator.generate('custom-object', {
position: new Vector3(5, 0, 0),
})

// Add Object3DWidgetsPlugin to see the added lights and cameras.
viewer.addPluginSync(new Object3DWidgetsPlugin())
```

Check the [example](https://threepipe.org/examples/#object3d-generator-plugin/) for the UI.

+ 51
- 0
website/plugin/Object3DWidgetsPlugin.md 파일 보기

@@ -0,0 +1,51 @@
---
prev:
text: 'EditorViewWidgetPlugin'
link: './EditorViewWidgetPlugin'

next:
text: 'Object3DGeneratorPlugin'
link: './Object3DGeneratorPlugin'

---

# Object3DWidgetsPlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#object3d-widgets-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/extras/Object3DWidgetsPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/Object3DWidgetsPlugin.html)

Object3DWidgetsPlugin adds support for light and camera helpers/gizmos in the viewer.
A helper is automatically created when any supported light or camera is added to the scene.
Simply add the plugin to the viewer to see the widget.

Support for additional types of helpers can be added dynamically or by other plugins by pushing a helper constructor to the `Object3DWidgetsPlugin.helpers` array, and calling `Object3DWidgetsPlugin.refresh()`.

The helper class prototype should implement the `IObject3DHelper` interface. Check `DirectionalLightHelper2` for an example.

```typescript
import {ThreeViewer, Object3DWidgetsPlugin, Object3DGeneratorPlugin} from 'threepipe'

const viewer = new ThreeViewer({...})

// Add the plugin to add support
const plugin = viewer.addPluginSync(new Object3DWidgetsPlugin())

// Add some lights or cameras to the scene. (This can be done before adding the plugin as well)
// Using Object3DGeneratorPlugin to create a camera and add it to the scene.
const generator = viewer.getOrAddPluginSync(Object3DGeneratorPlugin)
generator.generate('camera-perspective', {
position: new Vector3(5, 5, 0),
name: 'My Camera'
})

// to hide the widgets
plugin.enabled = false

// to add support for a custom helper
plugin.helpers.push(MyCustomHelper)
plugin.refresh()

```

+ 25
- 0
website/plugin/PLYLoadPlugin.md 파일 보기

@@ -0,0 +1,25 @@
---
prev:
text: 'Rhino3dmLoadPlugin'
link: './Rhino3dmLoadPlugin'

next:
text: 'USDZLoadPlugin'
link: './USDZLoadPlugin'

---

# PLYLoadPlugin

[Example](https://threepipe.org/examples/#ply-load/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/import/PLYLoadPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/PLYLoadPlugin.html)

Adds support for loading .ply ([Polygon file format](https://en.wikipedia.org/wiki/PLY_(file_format))) files.

```typescript
import {PLYLoadPlugin} from 'threepipe'
viewer.addPluginSync(new PLYLoadPlugin())

const mesh = await viewer.load('file.ply')
```

+ 45
- 0
website/plugin/ParallaxMappingPlugin.md 파일 보기

@@ -0,0 +1,45 @@
---
prev:
text: 'FragmentClippingExtensionPlugin'
link: './FragmentClippingExtensionPlugin'

next:
text: 'HDRiGroundPlugin'
link: './HDRiGroundPlugin'

---

# ParallaxMappingPlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#parallax-mapping-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/material/ParallaxMappingPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/ParallaxMappingPlugin.html)

`ParallaxMappingPlugin` adds a material extension to PhysicalMaterial to add support for [parallax relief mapping](https://en.wikipedia.org/wiki/Relief_mapping_(computer_graphics)). The idea is to walk along a ray that has entered the bumpmap's volume, finding the intersection point of the ray with the bumpmap. [Steep parallax mapping](https://en.wikipedia.org/wiki/Parallax_mapping) and [parallax occlusion mapping](https://en.wikipedia.org/wiki/Parallax_occlusion_mapping) are other common names for these techniques.

To use the plugin, add the plugin to the viewer and use the `bumpMap` in `PhysicalMaterial` normally. The max height is determined by the `bumpScale` in the material. This is assumed to be in world scale.

```typescript
import {ThreeViewer, ParallaxMappingPlugin} from 'threepipe'

const viewer = new ThreeViewer({...})

const parallaxMapping = viewer.addPluginSync(ParallaxMappingPlugin)

// load or create an object

// set the bump map
object.material.bumpMap = await viewer.load<ITexture>(bumps[0]) || null
// set the bump scale
object.material.bumpScale = 0.1
// setDirty to notify the viewer to update.
object.material.setDirty()
```

## References and related links:

- WebGL implementation by Rabbid76 - [github.com/Rabbid76/graphics-snippets](https://github.com/Rabbid76/graphics-snippets/blob/master/html/technique/parallax_005_parallax_relief_mapping_derivative_tbn.html)
- Lesson on Parallax Occlusion Mapping in GLSL - [http://sunandblackcat.com/tipFullView.php?topicid=28](https://web.archive.org/web/20190128023901/http://sunandblackcat.com/tipFullView.php?topicid=28)
- Learn OpenGL - https://learnopengl.com/Advanced-Lighting/Parallax-Mapping

+ 79
- 0
website/plugin/PickingPlugin.md 파일 보기

@@ -0,0 +1,79 @@
---
prev:
text: 'CanvasSnapshotPlugin'
link: './CanvasSnapshotPlugin'

next:
text: 'FullScreenPlugin'
link: './FullScreenPlugin'

---

# PickingPlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#picking-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/interaction/PickingPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/PickingPlugin.html)

Picking Plugin adds support for selecting and hovering over objects in the viewer with user interactions and selection widgets.

When the plugin is added to the viewer, it starts listening to the mouse move and click events over the canvas.
When an object is clicked, it is selected,
and if a UI plugin is added, the uiconfig for the selected object is populated in the interface.
The events `selectedObjectChanged`, `hoverObjectChanged`, and `hitObject` can be listened to on the plugin.

Picking plugin internally uses [ObjectPicker](https://threepipe.org/docs/classes/ObjectPicker.html),
check out the documentation or source code for more information.

```typescript
import {ThreeViewer, PickingPlugin} from 'threepipe'

const viewer = new ThreeViewer({...})

const pickingPlugin = viewer.addPluginSync(new PickingPlugin())

// Hovering events are also supported, but since its computationally expensive for large scenes it is disabled by default.
pickingPlugin.hoverEnabled = true

pickingPlugin.addEventListener('hitObject', (e)=>{
// This is fired when the user clicks on the canvas.
// The selected object hasn't been changed yet, and we have the option to change it or disable selection at this point.
// e.intersects.selectedObject contains the object that the user clicked on.
console.log('Hit: ', e.intersects.selectedObject)
// It can be changed here
// e.intersects.selectedObject = e.intersects.selectedObject.parent // select the parent
// e.intersects.selectedObject = null // unselect
// Check other properties on the event like intersects, mouse position, normal etc.
console.log(e)
})

pickingPlugin.addEventListener('selectedObjectChanged', (e)=>{
// This is fired when the selected object is changed.
// e.object contains the new selected object. It can be null if nothing is selected.
console.log('Selected: ', e.object)
})

// Objects can be programmatically selected and unselected

// to select
pickingPlugin.setSelectedObject(object)

// get the selected object
console.log(pickingPlugin.getSelectedObject())
// to unselect
pickingPlugin.setSelectedObject(null)

// Select object with camera animation to the object
pickingPlugin.setSelectedObject(object, true)

pickingPlugin.addEventListener('hoverObjectChanged', (e)=>{
// This is fired when the hovered object is changed.
// e.object contains the new hovered object.
console.log('Hovering: ', e.object)
})

```

+ 41
- 0
website/plugin/PointerLockControlsPlugin.md 파일 보기

@@ -0,0 +1,41 @@
---
prev:
text: 'DeviceOrientationControlsPlugin'
link: './DeviceOrientationControlsPlugin'

next:
text: 'ThreeFirstPersonControlsPlugin'
link: './ThreeFirstPersonControlsPlugin'

---

# PointerLockControlsPlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#pointer-lock-controls-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/interaction/PointerLockControlsPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/PointerLockControlsPlugin.html)

PointerLockControlsPlugin adds support for using PointerLockControls from three.js. It works similar to controls in first person shooter, captures the mouse pointer and uses it to look around with the camera.

After the plugin is added, it adds support for setting `pointerLock` as the key in `scene.mainCamera.controlMode`.

Sample Usage
```typescript
import {ThreeViewer, PointerLockControlsPlugin, Mesh2} from 'threepipe'

const viewer = new ThreeViewer({...})

viewer.addPluginSync(PointerLockControlsPlugin)

// after some user action
viewer.scene.mainCamera.controlsMode = 'pointerLock'

// listen to lock/unlock events
viewer.scene.mainCamera.controls?.addEventListener('lock', ()=> console.log('pointer locked'))
viewer.scene.mainCamera.controls?.addEventListener('unlock', ()=> console.log('pointer unlocked'))

// switch back to default orbit controls
viewer.scene.mainCamera.controlsMode = 'orbit'
```

+ 75
- 0
website/plugin/PopmotionPlugin.md 파일 보기

@@ -0,0 +1,75 @@
---
prev:
text: 'GLTFAnimationPlugin'
link: './GLTFAnimationPlugin'

next:
text: 'CameraViewPlugin'
link: './CameraViewPlugin'

---

# PopmotionPlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#popmotion-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/animation/PopmotionPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/PopmotionPlugin.html)

Provides animation/tweening capabilities to the viewer using the [popmotion.io](https://popmotion.io/) library.

Overrides the driver in popmotion to sync with the viewer and provide ways to store and stop animations.

```typescript
import {PopmotionPlugin, ThreeViewer} from 'threepipe'

const viewer = new ThreeViewer({...})

const cube = viewer.scene.getObjectByName('cube');

const popmotion = viewer.addPluginSync(new PopmotionPlugin())

// Move the object cube 1 unit up.
const anim = popmotion.animateTarget(cube, 'position', {
to: cube.position.clone().add(new Vector3(0,1,0)),
duration: 500, // ms
onComplete: () => isMovedUp = true,
onStop: () => throw(new Error('Animation stopped')),
})

// Alternatively, set the property directly in onUpdate.
const anim1 = popmotion.animate({
from: cube.position.y,
to: cube.position.y + 1,
duration: 500, // ms
onUpdate: (v) => {
cube.position.setY(v)
cube.setDirty()
},
onComplete: () => isMovedUp = true,
onStop: () => throw(new Error('Animation stopped')),
onEnd: () => console.log('Animation ended'), // This runs after both onComplete and onStop
})

// await for animation. This promise will reject only if an exception is thrown in onStop or onComplete. onStop rejects if throwOnStop is true
await anim.promise.catch((e)=>{
console.log(e, 'animation stopped before completion')
});

// or stop the animation
// anim.stop()

// Animate the color
await popmotion.animateAsync({ // Also await for the animation.
from: '#' + cube.material.color.getHexString(),
to: '#' + new Color().setHSL(Math.random(), 1, 0.5).getHexString(),
duration: 1000, // 1s
onUpdate: (v) => {
cube.material.color.set(v)
cube.material.setDirty()
},
})
```

Note: The animation is started when the animate or animateAsync function is called.

+ 21
- 0
website/plugin/ProgressivePlugin.md 파일 보기

@@ -0,0 +1,21 @@
---
prev:
text: 'DropzonePlugin'
link: './DropzonePlugin'

next:
text: 'SSAAPlugin'
link: './SSAAPlugin'
---

# ProgressivePlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#progressive-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/pipeline/ProgressivePlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/ProgressivePlugin.html)

Progressive Plugin adds a post-render pass to blend the last frame with the current frame.

This is used as a dependency in other plugins for progressive rendering effect which is useful for progressive shadows, gi, denoising, baking, anti-aliasing, and many other effects. The helper function `convergedPromise` returns a new promise that can be used to wait for the progressive rendering to converge.

+ 33
- 0
website/plugin/RenderTargetPreviewPlugin.md 파일 보기

@@ -0,0 +1,33 @@
---
prev:
text: 'TransformAnimationPlugin'
link: './TransformAnimationPlugin'

next:
text: 'GeometryUVPreviewPlugin'
link: './GeometryUVPreviewPlugin'

---

# RenderTargetPreviewPlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#render-target-preview/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/ui/RenderTargetPreviewPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/RenderTargetPreviewPlugin.html)

RenderTargetPreviewPlugin is a useful development and debugging plugin that renders any registered render-target to the screen in small collapsable panels.

```typescript
import {ThreeViewer, RenderTargetPreviewPlugin, NormalBufferPlugin} from 'threepipe'

const viewer = new ThreeViewer({...})

const normalPlugin = viewer.addPluginSync(new NormalBufferPlugin(HalfFloatType))

const previewPlugin = viewer.addPluginSync(new RenderTargetPreviewPlugin())

// Show the normal buffer in a panel
previewPlugin.addTarget(()=>normalPlugin.target, 'normal', false, false)
```

+ 32
- 0
website/plugin/Rhino3dmLoadPlugin.md 파일 보기

@@ -0,0 +1,32 @@
---
prev:
text: 'GLTFKHRMaterialVariantsPlugin'
link: './GLTFKHRMaterialVariantsPlugin'

next:
text: 'PLYLoadPlugin'
link: './PLYLoadPlugin'

---

# Rhino3dmLoadPlugin

[Example](https://threepipe.org/examples/#rhino3dm-load/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/import/Rhino3dmLoadPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/Rhino3dmLoadPlugin.html)

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.

It also adds some helpful options to process the model after load.

```typescript
import {Rhino3dmLoadPlugin} from 'threepipe'
const rhino3dmPlugin = viewer.addPluginSync(new Rhino3dmLoadPlugin())

rhino3dmPlugin.importMaterials = true // import materials source from 3dm file
rhino3dmPlugin.forceLayerMaterials = true // force material source to be layer in 3dm file.
rhino3dmPlugin.hideLineMesh = true // hide all lines and points in the model.
rhino3dmPlugin.replaceWithInstancedMesh = true // replace meshes with the same parent, geometry and material with a single instance mesh.

const mesh = await viewer.load('file.3dm')
```

+ 33
- 0
website/plugin/SSAAPlugin.md 파일 보기

@@ -0,0 +1,33 @@
---
prev:
text: 'ProgressivePlugin'
link: './ProgressivePlugin'

next:
text: 'DepthBufferPlugin'
link: './DepthBufferPlugin'

---

# SSAAPlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#ssaa-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/pipeline/SSAAPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/SSAAPlugin.html)

SSAA Plugin adds support for [Super Sampling Anti-Aliasing](https://en.wikipedia.org/wiki/Supersampling) to the viewer. Simply add the plugin to the viewer to use it.

It jitters the camera view offset over multiple frames, which are then blended by the [ProgressivePlugin](#progressiveplugin) to create a higher quality image. This is useful for reducing aliasing artifacts in the scene.

By default, the pipeline only renders once per request animation frame. So we don't get any anti-aliasing while moving. For that, either use the TAA(Temporal Anti-aliasing) plugin or for the case of simple scenes - render multiple times per frame which can be done by setting `plugin.rendersPerFrame` or `viewer.rendersPerFrame`. Check out the [example](https://threepipe.org/examples/#ssaa-plugin/) to see the effect on frame rate.

```typescript

const ssaa = viewer.addPluginSync(new SSAAPlugin())

ssaa.enabled = true // toggle jittering(if you want to set custom view offset)

ssaa.rendersPerFrame = 4 // render 4 times per frame (max 32 is useful)
```

+ 43
- 0
website/plugin/SSAOPlugin.md 파일 보기

@@ -0,0 +1,43 @@
---
prev:
text: 'GBufferPlugin'
link: './GBufferPlugin'

next:
text: 'CanvasSnapshotPlugin'
link: './CanvasSnapshotPlugin'

---

# SSAOPlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#ssao-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/pipeline/SSAOPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/SSAOPlugin.html)

SSAO Plugin adds support for [Screen Space Ambient Occlusion](https://en.wikipedia.org/wiki/Screen_space_ambient_occlusion) to the viewer. Simply add the plugin to the viewer to use it.

This is done by adding a pre-render pass to the render manager which renders SSAO to a custom render target. SSAOPlugin depends on [GBufferPlugin](#gbufferplugin), and is automatically added if not already.

This render target is then used by all PhysicalMaterial(s) in the scene during the main RenderPass to get the AO data. SSAO can also be disabled from the UI of the material.

Note: Use with [ProgressivePlugin](#progressiveplugin) and `TemporalAAPlugin` for best results.

```typescript
import {ThreeViewer, SSAOPlugin} from 'threepipe'

const viewer = new ThreeViewer({...})

const ssaoPlugin = viewer.addPluginSync(new SSAOPlugin())

// get the buffer.
console.log(ssaoPlugin.target);

// disable ssao for a material in the scene
material.userData.ssaoDisabled = true
```
> In the target/buffer - The ssao data is in the `r` channel to remain compatible with ORM. `gba` contains the depth in vec3(xyz) format.
> Note that its `ssaoDisabled`, so setting it to `true` will disable the effect.


+ 25
- 0
website/plugin/STLLoadPlugin.md 파일 보기

@@ -0,0 +1,25 @@
---
prev:
text: 'USDZLoadPlugin'
link: './USDZLoadPlugin'

next:
text: 'KTX2LoadPlugin'
link: './KTX2LoadPlugin'

---

# STLLoadPlugin

[Example](https://threepipe.org/examples/#stl-load/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/import/STLLoadPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/STLLoadPlugin.html)

Adds support for loading .stl ([Stereolithography](https://en.wikipedia.org/wiki/STL_(file_format))) files.

```typescript
import {STLLoadPlugin} from 'threepipe'
viewer.addPluginSync(new STLLoadPlugin())

const mesh = await viewer.load('file.stl')
```

+ 34
- 0
website/plugin/SimplifyModifierPlugin.md 파일 보기

@@ -0,0 +1,34 @@
---
prev:
text: 'GLTFMeshOptDecodePlugin'
link: './GLTFMeshOptDecodePlugin'

next:
text: 'MeshOptSimplifyModifierPlugin'
link: './MeshOptSimplifyModifierPlugin'

---

# SimplifyModifierPlugin

[Example](https://threepipe.org/examples/#simplify-modifier-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/extras/SimplifyModifierPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/SimplifyModifierPlugin.html)

Boilerplate for implementing a plugin for simplifying geometries.
This is a base class and cannot be used directly.

A sample to use it:
```typescript
class SimplifyModifierPluginImpl extends SimplifyModifierPlugin {
protected _simplify(geometry: IGeometry, count: number) {
return new SimplifyModifier().modify(geometry, count) as IGeometry
}
}

const plugin = viewer.addPluginSync(new SimplifyModifierPluginImpl())

const root = await viewer.load('file.glb')
plugin.simplifyAll(root, {factor: 0.75})
```
Check the [example](https://threepipe.org/examples/#simplify-modifier-plugin/) for full implementation.

+ 37
- 0
website/plugin/ThreeFirstPersonControlsPlugin.md 파일 보기

@@ -0,0 +1,37 @@
---
prev:
text: 'PointerLockControlsPlugin'
link: './PointerLockControlsPlugin'

next:
text: 'GLTFKHRMaterialVariantsPlugin'
link: './GLTFKHRMaterialVariantsPlugin'

---

# ThreeFirstPersonControlsPlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#three-first-person-controls-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/interaction/ThreeFirstPersonControlsPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/ThreeFirstPersonControlsPlugin.html)

ThreeFirstPersonControlsPlugin adds support for using FirstPersonControls from three.js. It works similar to idle look around in first person games, it does not captures the mouse pointer.

After the plugin is added, it adds support for setting `threeFirstPerson` as the key in `scene.mainCamera.controlMode`.

Sample Usage
```typescript
import {ThreeViewer, ThreeFirstPersonControlsPlugin, Mesh2} from 'threepipe'

const viewer = new ThreeViewer({...})

viewer.addPluginSync(ThreeFirstPersonControlsPlugin)

// after some user action
viewer.scene.mainCamera.controlsMode = 'threeFirstPerson'

// switch back to default orbit controls
viewer.scene.mainCamera.controlsMode = 'orbit'
```

+ 23
- 0
website/plugin/TonemapPlugin.md 파일 보기

@@ -0,0 +1,23 @@
---
prev: false
next:
text: 'DropzonePlugin'
link: './DropzonePlugin'

---

# TonemapPlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#tonemap-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/postprocessing/TonemapPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/TonemapPlugin.html)

TonemapPlugin adds a post-processing material extension to the ScreenPass in render manager
that applies tonemapping to the color. The tonemapping operator can be changed
by setting the `toneMapping` property of the plugin. The default tonemapping operator is `ACESFilmicToneMapping`.

Other Tonemapping properties can be like `exposure`, `contrast` and `saturation`

TonemapPlugin is added by default in ThreeViewer unless `tonemap` is set to `false` in the options.

+ 69
- 0
website/plugin/TransformAnimationPlugin.md 파일 보기

@@ -0,0 +1,69 @@
---
prev:
text: 'CameraViewPlugin'
link: './CameraViewPlugin'

next:
text: 'RenderTargetPreviewPlugin'
link: './RenderTargetPreviewPlugin'

---

# TransformAnimationPlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#transform-animation-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/animation/TransformAnimationPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/TransformAnimationPlugin.html)

TransformAnimationPlugin adds support to save and load transform(position, rotation, scale) states for objects in the scene, which can then be animated to.
It uses PopmotionPlugin internally to animate any object to a saved transform object.

The transformations are saved in the object userData, and can be created and interacted with from the plugin.

It also provides a UI to manage the states, this UI is added to the object's uiConfig and can be accessed using the object UI or PickingPlugin. Check the example for a working demo.

Sample Usage -
```javascript
import {TransformAnimationPlugin, ThreeViewer, Vector3, Quaternion, EasingFunctions, timeout} from 'threepipe'

const viewer = new ThreeViewer({...})

const model = viewer.scene.getObjectByName('model')

const transformAnim = viewer.addPluginSync(new TransformAnimationPlugin())

// Save the current state of the model as a transform
transformAnim.addTransform(model, 'initial')

// Rotate/Move the model and save other transform states
// left
model.rotation.set(0, Math.PI / 2, 0)
model.setDirty?.()
transformAnim.addTransform(model, 'left')

// top
model.rotation.set(Math.PI / 2, 0, 0)
model.setDirty?.()
transformAnim.addTransform(model, 'top')

// up
model.position.set(0, 2, 0)
model.lookAt(viewer.scene.mainCamera.position)
model.setDirty?.()
transformAnim.addTransform(model, 'up')

// animate to a transform(from current position) in 1 sec
const anim = transformAnim.animateTransform(model, 'left', 1000)
// to stop the animation
// anim.stop()
// wait for the animation to finish
await anim.promise

// set a transform without animation
transformAnim.setTransform(model, 'top')

// await directly.
await transformAnim.animateToTransform(model, 'up', 1000)?.promise
```

+ 37
- 0
website/plugin/TransformControlsPlugin.md 파일 보기

@@ -0,0 +1,37 @@
---
prev:
text: 'InteractionPromptPlugin'
link: './InteractionPromptPlugin'

next:
text: 'ContactShadowGroundPlugin'
link: './ContactShadowGroundPlugin'

---

# TransformControlsPlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#transform-controls-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/interaction/TransformControlsPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/TransformControlsPlugin.html)

Transform Controls Plugin adds support for moving, rotating and scaling objects in the viewer with interactive widgets.

Under the hood, TransformControlsPlugin uses [TransformControls2](https://threepipe.org/docs/classes/TransformControls2) to provide the interactive controls, it is a extended version of three.js [TransformControls](https://threejs.org/docs/#examples/en/controls/TransformControls).

When the plugin is added to the viewer, it interfaces with the [PickingPlugin](#pickingplugin) and shows the control gizmos when an object is selected and hides them when the object is unselected.

If the `PickingPlugin` is not added to the viewer before the `TransformControlsPlugin`, it is added automatically with the plugin.

```typescript
import {ThreeViewer, TransformControlsPlugin} from 'threepipe'

const viewer = new ThreeViewer({...})

const transfromControlsPlugin = viewer.addPluginSync(new TransformControlsPlugin())

// Get the underlying transform controls
console.log(transfromControlsPlugin.transformControls)
```

+ 26
- 0
website/plugin/USDZLoadPlugin.md 파일 보기

@@ -0,0 +1,26 @@
---
prev:
text: 'PLYLoadPlugin'
link: './PLYLoadPlugin'

next:
text: 'STLLoadPlugin'
link: './STLLoadPlugin'

---

# USDZLoadPlugin

[Example](https://threepipe.org/examples/#usdz-load/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/import/USDZLoadPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/USDZLoadPlugin.html)

Adds support for loading .usdz and .usda ([Universal Scene Description](https://graphics.pixar.com/usd/docs/index.html)) files.

```typescript
import {USDZLoadPlugin} from 'threepipe'
viewer.addPluginSync(new USDZLoadPlugin())

const mesh = await viewer.load('file.usdz')
const mesh2 = await viewer.load('file.usda')
```

+ 36
- 0
website/plugin/VignettePlugin.md 파일 보기

@@ -0,0 +1,36 @@
---
prev:
text: 'FrameFadePlugin'
link: './FrameFadePlugin'

next:
text: 'ChromaticAberrationPlugin'
link: './ChromaticAberrationPlugin'

---

# VignettePlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#vignette-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/postprocessing/VignettePlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/VignettePlugin.html)

VignettePlugin adds a post-processing material extension to the ScreenPass in render manager
that applies a vignette effect to the final render. The parameters `power` and `color` can be changed to customize the effect.

```typescript
import {ThreeViewer, VignettePlugin} from 'threepipe'

const viewer = new ThreeViewer({...})

const vignettePlugin = viewer.addPluginSync(VignettePlugin)

// Change the vignette color
vignettePlugin.power = 1
vignettePlugin.color = new Color(0.5, 0, 0)

// or
// vignettePlugin.color.set('#ff0000'); vignettePlugin.setDirty() // Call setDirty to tell the plugin that color has changed
```

+ 45
- 0
website/plugin/VirtualCamerasPlugin.md 파일 보기

@@ -0,0 +1,45 @@
---
prev:
text: 'HDRiGroundPlugin'
link: './HDRiGroundPlugin'

next:
text: 'EditorViewWidgetPlugin'
link: './EditorViewWidgetPlugin'

---

# VirtualCamerasPlugin

[//]: # (todo: image)

[Example](https://threepipe.org/examples/#virtual-cameras-plugin/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/rendering/VirtualCamerasPlugin.ts) &mdash;
[API Reference](https://threepipe.org/docs/classes/VirtualCamerasPlugin.html)

VirtualCamerasPlugin adds support for rendering to multiple virtual cameras in the viewer. These cameras are rendered in preRender callback just before the main camera is rendered. The virtual cameras can be added to the plugin and removed from it.

The feed to the virtual camera is rendered to a Render Target texture which can be accessed and re-rendered in the scene or used in other plugins.

```typescript
import {ThreeViewer, VirtualCamerasPlugin} from 'threepipe'

const viewer = new ThreeViewer({...})

const virtualCameras = viewer.addPluginSync(new VirtualCamerasPlugin())

const camera = new PerspectiveCamera2('orbit', viewer.canvas, false, 45, 1)
camera.name = name
camera.position.set(0, 5, 0)
camera.target.set(0, 0.25, 0)
camera.userData.autoLookAtTarget = true // automatically look at the target (in setDirty)
camera.setDirty()
camera.addEventListener('update', ()=>{
viewer.setDirty() // if the camera is not added to the scene it wont update automatically when camera.setDirty is called(like from the UI)
})

const vCam = virtualCameras.addCamera(camera)
console.log(vCam.target) // target is a WebGLRenderTarget/IRenderTarget
```

Check the [virtual camera](https://threepipe.org/examples/#virtual-camera/) example for using the texture in the scene.

BIN
website/public/favicon.ico 파일 보기


+ 33
- 0
website/public/logo.svg 파일 보기

@@ -0,0 +1,33 @@
<svg width="256" height="256" viewBox="0 0 400 400" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M322.581 0H77.4194C34.6618 0 0 34.6618 0 77.4194V322.581C0 365.338 34.6618 400 77.4194 400H322.581C365.338 400 400 365.338 400 322.581V77.4194C400 34.6618 365.338 0 322.581 0Z" fill="#F97316"/>
<path d="M295.594 354.188C327.954 354.188 354.188 327.954 354.188 295.594C354.188 263.233 327.954 237 295.594 237C263.233 237 237 263.233 237 295.594C237 327.954 263.233 354.188 295.594 354.188Z" fill="white" fill-opacity="0.46"/>
<path opacity="0.4" d="M177.916 36.3571L148.357 65.9167C141.532 72.7411 141.532 83.8058 148.357 90.6302L177.357 119.63C184.181 126.455 195.246 126.455 202.07 119.63L231.63 90.0707C238.454 83.2463 238.454 72.1816 231.63 65.3572L202.63 36.3571C195.805 29.5326 184.741 29.5326 177.916 36.3571Z" fill="#FDBA74"/>
<path d="M129.012 255.934L144.586 317.944" stroke="white" stroke-width="7" stroke-miterlimit="10"/>
<path d="M190.529 273.357L129.012 255.934" stroke="white" stroke-width="7" stroke-miterlimit="10"/>
<path d="M144.588 317.938L190.531 273.352" stroke="white" stroke-width="7" stroke-miterlimit="10"/>
<path d="M144.586 317.943L83.0684 300.52" stroke="white" stroke-width="7" stroke-miterlimit="10"/>
<path d="M83.0684 300.52L93.575 342.38C95.8256 351.347 106.944 354.508 113.575 348.066L144.586 317.943" stroke="white" stroke-width="7" stroke-miterlimit="10"/>
<path d="M83.0684 300.52L129.011 255.934" stroke="white" stroke-width="7" stroke-miterlimit="10"/>
<path d="M129.012 255.929L174.996 211.301" stroke="white" stroke-width="7" stroke-miterlimit="10"/>
<path d="M174.998 211.302L220.941 166.715" stroke="white" stroke-width="7" stroke-miterlimit="10"/>
<path d="M159.422 149.297L174.996 211.307" stroke="white" stroke-width="7" stroke-miterlimit="10"/>
<path d="M174.994 211.301L113.436 193.918" stroke="white" stroke-width="7" stroke-miterlimit="10"/>
<path d="M113.436 193.918L129.01 255.928" stroke="white" stroke-width="7" stroke-miterlimit="10"/>
<path d="M129.013 255.932L67.4961 238.508" stroke="white" stroke-width="7" stroke-miterlimit="10"/>
<path d="M67.4961 238.508L83.0706 300.518" stroke="white" stroke-width="7" stroke-miterlimit="10"/>
<path d="M51.9219 176.496L67.4964 238.507" stroke="white" stroke-width="7" stroke-miterlimit="10"/>
<path d="M113.439 193.92L51.9219 176.496" stroke="white" stroke-width="7" stroke-miterlimit="10"/>
<path d="M67.4961 238.505L113.439 193.918" stroke="white" stroke-width="7" stroke-miterlimit="10"/>
<path d="M113.436 193.884L159.419 149.297" stroke="white" stroke-width="7" stroke-miterlimit="10"/>
<path d="M159.422 149.291L97.8633 131.867" stroke="white" stroke-width="7" stroke-miterlimit="10"/>
<path d="M97.8633 131.867L113.438 193.878" stroke="white" stroke-width="7" stroke-miterlimit="10"/>
<path d="M51.9202 176.497L40.9749 132.889C38.9155 124.684 46.5022 117.322 54.6416 119.627L97.863 131.869" stroke="white" stroke-width="7" stroke-miterlimit="10"/>
<path d="M51.9219 176.495L97.8647 131.867" stroke="white" stroke-width="7" stroke-miterlimit="10"/>
<path d="M236.512 228.725L267.526 198.627C274.158 192.19 271.331 180.988 262.439 178.469L220.938 166.715" stroke="white" stroke-width="7" stroke-miterlimit="10"/>
<path d="M220.938 166.715L236.512 228.725" stroke="white" stroke-width="7" stroke-miterlimit="10"/>
<path d="M236.515 228.725L174.998 211.301" stroke="white" stroke-width="7" stroke-miterlimit="10"/>
<path d="M174.998 211.301L190.531 273.352" stroke="white" stroke-width="7" stroke-miterlimit="10"/>
<path d="M190.529 273.354L236.513 228.727" stroke="white" stroke-width="7" stroke-miterlimit="10"/>
<path d="M220.939 166.721L159.422 149.297" stroke="white" stroke-width="7" stroke-miterlimit="10"/>
<path d="M278.747 140.584L354.362 148.325C356.978 148.593 359.316 146.689 359.584 144.073L367.326 68.4585C367.758 64.2377 362.871 61.6016 359.581 64.2804L276.225 132.153C272.935 134.832 274.526 140.152 278.747 140.584Z" fill="white"/>
</svg>

Loading…
취소
저장