| @@ -4,3 +4,5 @@ public | |||
| config | |||
| libs | |||
| docs | |||
| examples/**/*.js | |||
| examples/**/*.html | |||
| @@ -1,5 +1,7 @@ | |||
| dist | |||
| docs | |||
| examples/**/*.js | |||
| examples/**/*.js.map | |||
| # Logs | |||
| logs | |||
| @@ -0,0 +1,30 @@ | |||
| <!DOCTYPE html> | |||
| <html lang="en"> | |||
| <head> | |||
| <meta charset="UTF-8"> | |||
| <title>Custom Pipeline</title> | |||
| <!-- Import map --> | |||
| <script type="importmap"> | |||
| { | |||
| "imports": { | |||
| "threepipe": "./../../dist/index.mjs" | |||
| } | |||
| } | |||
| </script> | |||
| <style id="example-style"> | |||
| html, body, #canvas-container, #mcanvas { | |||
| width: 100%; | |||
| height: 100%; | |||
| margin: 0; | |||
| overflow: hidden; | |||
| } | |||
| </style> | |||
| <script type="module" src="../js-utils/simple-code-preview.mjs"> </script> | |||
| <script id="example-script" type="module" src="./script.js" data-scripts="./script.ts;./script.js"></script> | |||
| </head> | |||
| <body> | |||
| <div id="canvas-container"> | |||
| <canvas id="mcanvas"></canvas> | |||
| </div> | |||
| </body> | |||
| @@ -0,0 +1,48 @@ | |||
| import {_testFinish, DepthBufferPlugin, downloadBlob, HalfFloatType, ThreeViewer} from 'threepipe' | |||
| import {createSimpleButtons} from '../js-utils/simple-bottom-buttons.js' | |||
| const viewer = new ThreeViewer({ | |||
| canvas: document.getElementById('mcanvas') as HTMLCanvasElement, | |||
| msaa: true, | |||
| rgbm: true, | |||
| zPrepass: false, | |||
| }) | |||
| async function init() { | |||
| viewer.addPluginSync(new DepthBufferPlugin(HalfFloatType, true)) | |||
| await viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr') | |||
| await viewer.load('https://threejs.org/examples/models/gltf/kira.glb', { | |||
| autoCenter: true, | |||
| autoScale: true, | |||
| }) | |||
| viewer.renderManager.autoBuildPipeline = false | |||
| viewer.renderManager.pipeline = ['render', 'screen'] | |||
| createSimpleButtons({ | |||
| ['depth']: () => { | |||
| viewer.renderManager.pipeline = ['depth'] | |||
| }, | |||
| ['render']: () => { | |||
| viewer.renderManager.pipeline = ['render'] | |||
| }, | |||
| ['render, screen']: () => { | |||
| viewer.renderManager.pipeline = ['render', 'screen'] | |||
| }, | |||
| ['depth, render, screen']: () => { | |||
| viewer.renderManager.pipeline = ['depth', 'render', 'screen'] | |||
| }, | |||
| ['Download snapshot']: async(btn: HTMLButtonElement) => { | |||
| btn.disabled = true | |||
| const blob = await viewer.getScreenshotBlob({mimeType: 'image/png'}) | |||
| if (blob) downloadBlob(blob, 'file.png') | |||
| else console.error('Unable to get screenshot') | |||
| btn.disabled = false | |||
| }, | |||
| }) | |||
| } | |||
| init().then(_testFinish) | |||
| @@ -0,0 +1,30 @@ | |||
| <!DOCTYPE html> | |||
| <html lang="en"> | |||
| <head> | |||
| <meta charset="UTF-8"> | |||
| <title>Depth Buffer Plugin</title> | |||
| <!-- Import map --> | |||
| <script type="importmap"> | |||
| { | |||
| "imports": { | |||
| "threepipe": "./../../dist/index.mjs" | |||
| } | |||
| } | |||
| </script> | |||
| <style id="example-style"> | |||
| html, body, #canvas-container, #mcanvas { | |||
| width: 100%; | |||
| height: 100%; | |||
| margin: 0; | |||
| overflow: hidden; | |||
| } | |||
| </style> | |||
| <script type="module" src="../js-utils/simple-code-preview.mjs"> </script> | |||
| <script id="example-script" type="module" src="./script.js" data-scripts="./script.ts;./script.js"></script> | |||
| </head> | |||
| <body> | |||
| <div id="canvas-container"> | |||
| <canvas id="mcanvas"></canvas> | |||
| </div> | |||
| </body> | |||
| @@ -0,0 +1,61 @@ | |||
| import { | |||
| _testFinish, | |||
| DepthBufferPlugin, | |||
| downloadBlob, | |||
| HalfFloatType, | |||
| RenderTargetPreviewPlugin, | |||
| ThreeViewer, | |||
| } from 'threepipe' | |||
| import {createSimpleButtons} from '../js-utils/simple-bottom-buttons.js' | |||
| const viewer = new ThreeViewer({ | |||
| canvas: document.getElementById('mcanvas') as HTMLCanvasElement, | |||
| msaa: true, | |||
| }) | |||
| async function init() { | |||
| const depthPlugin = viewer.addPluginSync(new DepthBufferPlugin(HalfFloatType)) | |||
| await viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr') | |||
| await viewer.load('https://threejs.org/examples/models/gltf/kira.glb', { | |||
| autoCenter: true, | |||
| autoScale: true, | |||
| }) | |||
| // Disable automatic near/far plane calculation based on scene bounding box | |||
| viewer.scene.mainCamera.userData.autoNearFar = false | |||
| viewer.scene.mainCamera.userData.minNearPlane = 1 | |||
| viewer.scene.mainCamera.userData.maxFarPlane = 10 | |||
| viewer.scene.refreshScene() | |||
| const depthTarget = depthPlugin.getTarget() | |||
| if (!depthTarget) { | |||
| throw new Error('depthPlugin.getTarget() returned undefined') | |||
| } | |||
| // to render depth buffer to screen, uncomment this line: | |||
| // viewer.renderManager.screenPass.overrideReadBuffer = depthTarget | |||
| const targetPreview = await viewer.addPlugin(RenderTargetPreviewPlugin) | |||
| targetPreview.addTarget(()=>depthTarget, 'depth') | |||
| createSimpleButtons({ | |||
| ['Toggle depth rendering']: () => { | |||
| viewer.renderManager.screenPass.overrideReadBuffer = | |||
| viewer.renderManager.screenPass.overrideReadBuffer ? null : depthTarget | |||
| viewer.setDirty() | |||
| }, | |||
| ['Download snapshot']: async(btn: HTMLButtonElement) => { | |||
| btn.disabled = true | |||
| const blob = await viewer.getScreenshotBlob({mimeType: 'image/png'}) | |||
| if (blob) downloadBlob(blob, 'file.png') | |||
| else console.error('Unable to get screenshot') | |||
| btn.disabled = false | |||
| }, | |||
| }) | |||
| } | |||
| init().then(_testFinish) | |||
| @@ -0,0 +1,46 @@ | |||
| <!DOCTYPE html> | |||
| <html lang="en"> | |||
| <head> | |||
| <meta charset="UTF-8"> | |||
| <title>DRACO(DRC) Load</title> | |||
| <!-- Import map --> | |||
| <script type="importmap"> | |||
| { | |||
| "imports": { | |||
| "threepipe": "./../../dist/index.mjs" | |||
| } | |||
| } | |||
| </script> | |||
| <style id="example-style"> | |||
| html, body, #canvas-container, #mcanvas { | |||
| width: 100%; | |||
| height: 100%; | |||
| margin: 0; | |||
| overflow: hidden; | |||
| } | |||
| </style> | |||
| <script type="module" src="../js-utils/simple-code-preview.mjs"> </script> | |||
| <script id="example-script" type="module"> | |||
| import {_testFinish, ThreeViewer} from 'threepipe' | |||
| const viewer = new ThreeViewer({canvas: document.getElementById('mcanvas')}) | |||
| async function init() { | |||
| await viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr') | |||
| const result = await viewer.load('https://threejs.org/examples/models/draco/bunny.drc', { | |||
| autoCenter: true, | |||
| autoScale: true, | |||
| }) | |||
| console.log(result) | |||
| } | |||
| init().then(_testFinish) | |||
| </script> | |||
| </head> | |||
| <body> | |||
| <div id="canvas-container"> | |||
| <canvas id="mcanvas"></canvas> | |||
| </div> | |||
| </body> | |||
| @@ -0,0 +1,47 @@ | |||
| <!DOCTYPE html> | |||
| <html lang="en"> | |||
| <head> | |||
| <meta charset="UTF-8"> | |||
| <title>FBX Load</title> | |||
| <!-- Import map --> | |||
| <script type="importmap"> | |||
| { | |||
| "imports": { | |||
| "threepipe": "./../../dist/index.mjs" | |||
| } | |||
| } | |||
| </script> | |||
| <style id="example-style"> | |||
| html, body, #canvas-container, #mcanvas { | |||
| width: 100%; | |||
| height: 100%; | |||
| margin: 0; | |||
| overflow: hidden; | |||
| } | |||
| </style> | |||
| <script type="module" src="../js-utils/simple-code-preview.mjs"> </script> | |||
| <script id="example-script" type="module"> | |||
| import {_testFinish, ThreeViewer, HemisphereLight} from 'threepipe' | |||
| const viewer = new ThreeViewer({canvas: document.getElementById('mcanvas')}) | |||
| async function init() { | |||
| viewer.scene.addObject(new HemisphereLight(0xffffff, 0x444444, 10)) | |||
| const result = await viewer.load('https://threejs.org/examples/models/fbx/Samba Dancing.fbx', { | |||
| autoCenter: true, | |||
| autoScale: true, | |||
| }) | |||
| console.log(result) | |||
| } | |||
| init().then(_testFinish) | |||
| </script> | |||
| </head> | |||
| <body> | |||
| <div id="canvas-container"> | |||
| <canvas id="mcanvas"></canvas> | |||
| </div> | |||
| </body> | |||
| @@ -0,0 +1,30 @@ | |||
| <!DOCTYPE html> | |||
| <html lang="en"> | |||
| <head> | |||
| <meta charset="UTF-8"> | |||
| <title>GLB Export</title> | |||
| <!-- Import map --> | |||
| <script type="importmap"> | |||
| { | |||
| "imports": { | |||
| "threepipe": "./../../dist/index.mjs" | |||
| } | |||
| } | |||
| </script> | |||
| <style id="example-style"> | |||
| html, body, #canvas-container, #mcanvas { | |||
| width: 100%; | |||
| height: 100%; | |||
| margin: 0; | |||
| overflow: hidden; | |||
| } | |||
| </style> | |||
| <script type="module" src="../js-utils/simple-code-preview.mjs"> </script> | |||
| <script id="example-script" type="module" src="./script.js" data-scripts="./script.ts;./script.js"></script> | |||
| </head> | |||
| <body> | |||
| <div id="canvas-container"> | |||
| <canvas id="mcanvas"></canvas> | |||
| </div> | |||
| </body> | |||
| @@ -0,0 +1,64 @@ | |||
| import {_testFinish, downloadBlob, IMaterial, IObject3D, ThreeViewer} from 'threepipe' | |||
| import {createSimpleButtons} from '../js-utils/simple-bottom-buttons.js' | |||
| const viewer = new ThreeViewer({canvas: document.getElementById('mcanvas') as HTMLCanvasElement, msaa: true}) | |||
| async function init() { | |||
| // load obj + mtl | |||
| await viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr') | |||
| const helmet = await viewer.load<IObject3D>('https://threejs.org/examples/models/gltf/DamagedHelmet/glTF/DamagedHelmet.gltf', { | |||
| autoCenter: true, | |||
| autoScale: true, | |||
| }) | |||
| if (!helmet) { | |||
| console.error('Unable to load model') | |||
| return | |||
| } | |||
| const mesh = helmet.getObjectByName('node_damagedHelmet_-6514')! | |||
| // const blob = await viewer.assetManager.exporter.exportObject(helmetObject, {exportExt: 'glb'}) | |||
| // const blob = await viewer.exportScene({viewerConfig: false}) // export scene without viewer config | |||
| // const blob = await viewer.exportScene() // export scene with viewer config and default settings. | |||
| createSimpleButtons({ | |||
| ['Download Helmet Object GLB']: async() => { | |||
| const blob = await viewer.assetManager.exporter.exportObject(mesh, { | |||
| exportExt: 'glb', | |||
| embedUrlImages: true, // embed images in glb even when url is available. | |||
| }) | |||
| if (!blob) { | |||
| alert('Unable to export helmet object') | |||
| return | |||
| } | |||
| downloadBlob(blob, 'helmet.' + blob.ext) | |||
| }, | |||
| ['Download Helmet Material']: async() => { | |||
| const blob = await viewer.assetManager.exporter.exportObject(<IMaterial>mesh.material) | |||
| if (!blob) { | |||
| alert('Unable to export helmet material') | |||
| return | |||
| } | |||
| downloadBlob(blob, 'helmet.' + blob.ext) | |||
| }, | |||
| ['Download Scene GLB (Without Viewer Config)']: async() => { | |||
| const blob = await viewer.exportScene({viewerConfig: false}) | |||
| if (!blob || blob.ext !== 'glb') { | |||
| alert('Unable to export scene') | |||
| return | |||
| } | |||
| downloadBlob(blob, 'scene.glb') | |||
| }, | |||
| ['Download Scene GLB (With Viewer Config)']: async() => { | |||
| const blob = await viewer.exportScene({viewerConfig: true}) | |||
| if (!blob || blob.ext !== 'glb') { | |||
| alert('Unable to export scene') | |||
| return | |||
| } | |||
| downloadBlob(blob, 'scene_with_config.glb') | |||
| }, | |||
| }) | |||
| } | |||
| init().then(_testFinish) | |||
| @@ -0,0 +1,30 @@ | |||
| <!DOCTYPE html> | |||
| <html lang="en"> | |||
| <head> | |||
| <meta charset="UTF-8"> | |||
| <title>GLTF Load</title> | |||
| <!-- Import map --> | |||
| <script type="importmap"> | |||
| { | |||
| "imports": { | |||
| "threepipe": "./../../dist/index.mjs" | |||
| } | |||
| } | |||
| </script> | |||
| <style id="example-style"> | |||
| html, body, #canvas-container, #mcanvas { | |||
| width: 100%; | |||
| height: 100%; | |||
| margin: 0; | |||
| overflow: hidden; | |||
| } | |||
| </style> | |||
| <script type="module" src="../js-utils/simple-code-preview.mjs"> </script> | |||
| <script id="example-script" type="module" src="./script.js" data-scripts="./script.ts;./script.js"></script> | |||
| </head> | |||
| <body> | |||
| <div id="canvas-container"> | |||
| <canvas id="mcanvas"></canvas> | |||
| </div> | |||
| </body> | |||
| @@ -0,0 +1,16 @@ | |||
| import {_testFinish, ThreeViewer} from 'threepipe' | |||
| const viewer = new ThreeViewer({canvas: document.getElementById('mcanvas') as HTMLCanvasElement, msaa: true}) | |||
| async function init() { | |||
| await viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr') | |||
| const result = await viewer.load('https://threejs.org/examples/models/gltf/DamagedHelmet/glTF/DamagedHelmet.gltf', { | |||
| autoCenter: true, | |||
| autoScale: true, | |||
| }) | |||
| console.log(result) | |||
| } | |||
| init().then(_testFinish) | |||
| @@ -0,0 +1,43 @@ | |||
| <!DOCTYPE html> | |||
| <html lang="en"> | |||
| <head> | |||
| <meta charset="UTF-8"> | |||
| <title>HDR Load</title> | |||
| <!-- Import map --> | |||
| <script type="importmap"> | |||
| { | |||
| "imports": { | |||
| "threepipe": "./../../dist/index.mjs" | |||
| } | |||
| } | |||
| </script> | |||
| <style id="example-style"> | |||
| html, body, #canvas-container, #mcanvas { | |||
| width: 100%; | |||
| height: 100%; | |||
| margin: 0; | |||
| overflow: hidden; | |||
| } | |||
| </style> | |||
| <script type="module" src="../js-utils/simple-code-preview.mjs"> </script> | |||
| <script id="example-script" type="module"> | |||
| import {_testFinish, ThreeViewer} from 'threepipe' | |||
| const viewer = new ThreeViewer({canvas: document.getElementById('mcanvas')}) | |||
| async function init() { | |||
| await viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr') | |||
| viewer.scene.background = viewer.scene.environment | |||
| } | |||
| init().then(_testFinish) | |||
| </script> | |||
| </head> | |||
| <body> | |||
| <div id="canvas-container"> | |||
| <canvas id="mcanvas"></canvas> | |||
| </div> | |||
| </body> | |||
| @@ -0,0 +1,18 @@ | |||
| <!DOCTYPE html> | |||
| <html lang="en"> | |||
| <head> | |||
| <meta charset="UTF-8"> | |||
| <title>Basic Lib Import Test</title> | |||
| <!-- Import map --> | |||
| <script type="importmap"> | |||
| { | |||
| "imports": { | |||
| "threepipe": "./../../dist/index.mjs" | |||
| } | |||
| } | |||
| </script> | |||
| <script type="module" src="./script.js"></script> | |||
| </head> | |||
| <body> | |||
| </body> | |||
| @@ -0,0 +1,5 @@ | |||
| import {_testFinish, ThreeViewer} from 'threepipe' | |||
| console.log(ThreeViewer) | |||
| _testFinish() | |||
| @@ -0,0 +1,30 @@ | |||
| <!DOCTYPE html> | |||
| <html lang="en"> | |||
| <head> | |||
| <meta charset="UTF-8"> | |||
| <title>ThreePipe Examples</title> | |||
| </head> | |||
| <body> | |||
| <div> | |||
| <h1>Examples</h1> | |||
| <ul> | |||
| <li><a href="./import-test">Import Test</a></li> | |||
| <li><a href="./sphere-rgbm-test">Sphere RGBM Test </a></li> | |||
| <li><a href="./sphere-half-float-test">Sphere Half Float Test </a></li> | |||
| <li><a href="./sphere-msaa-test">Sphere MSAA Test </a></li> | |||
| <li><a href="./z-prepass">Z-Prepass Test </a></li> | |||
| <li><a href="./fbx-load">FBX Load </a></li> | |||
| <li><a href="./hdr-load">HDR Load </a></li> | |||
| <li><a href="./obj-mtl-load">OBJ MTL Load </a></li> | |||
| <li><a href="./gltf-load">GLTF Load </a></li> | |||
| <li><a href="./drc-load">DRACO(DRC) Load </a></li> | |||
| <li><a href="./obj-to-glb">Convert OBJ to GLB </a></li> | |||
| <li><a href="./depth-buffer-plugin">Depth Buffer Plugin </a></li> | |||
| <li><a href="./custom-pipeline">Custom Pipeline specification </a></li> | |||
| <li><a href="./render-target-preview">Render Target Preview </a></li> | |||
| <li><a href="./glb-export">GLB Export </a></li> | |||
| <li><a href="./glb-export">GLB Export </a></li> | |||
| <li><a href="./pmat-material-export">PMAT Material export </a></li> | |||
| </ul> | |||
| </div> | |||
| </body> | |||
| @@ -0,0 +1,13 @@ | |||
| export function createSimpleButtons(buttons: Record<string, (btn: HTMLButtonElement) => void>) { | |||
| const entries = Object.entries(buttons) | |||
| entries.forEach(([text, onclick], i) => { | |||
| const btn = document.createElement('button') | |||
| btn.innerText = text | |||
| btn.style.position = 'absolute' | |||
| btn.style.bottom = `${3 + (entries.length - i - 1) * 2}rem` | |||
| btn.style.right = '3rem' | |||
| btn.style.zIndex = '10000' | |||
| btn.onclick = async() => onclick(btn) | |||
| document.body.appendChild(btn) | |||
| }) | |||
| } | |||
| @@ -0,0 +1,18 @@ | |||
| import {setupCodePreview} from 'https://cdn.jsdelivr.net/gh/repalash/example-code-previewer/dist/index.js'; | |||
| const exampleScript = document.getElementById('example-script') | |||
| const scripts = exampleScript && exampleScript.dataset.scripts ? exampleScript.dataset.scripts.split(';') : [] | |||
| if(exampleScript.textContent) scripts.push(exampleScript) | |||
| const exampleStyle = document.querySelector('#example-style') | |||
| const css = exampleStyle ? exampleStyle.textContent : '' | |||
| setupCodePreview( | |||
| document.getElementById('canvas-container') || document.querySelector('.code-preview-container'), | |||
| scripts, | |||
| scripts.map(s=>s.textContent ? 'js' : s.split('.').pop()), // title | |||
| scripts.map(s=>(typeof s === 'string' && s.endsWith('.js')) ? s : 'https://github.com/repalash/threepipe/tree/master/examples/'+ window.location.pathname.split('/examples/').pop().replace('index.html', '')+(s.textContent ? 'index.html' : s)), // todo: github link | |||
| (c)=>c.replaceAll(" from 'threepipe'", " from 'https://repalash.com/threepipe/dist/index.mjs'"), // todo: fix link | |||
| { | |||
| title: 'ThreePipe: ' + document.title, | |||
| css, | |||
| }, | |||
| ); | |||
| @@ -0,0 +1,47 @@ | |||
| <!DOCTYPE html> | |||
| <html lang="en"> | |||
| <head> | |||
| <meta charset="UTF-8"> | |||
| <title>OBJ MTL Load</title> | |||
| <!-- Import map --> | |||
| <script type="importmap"> | |||
| { | |||
| "imports": { | |||
| "threepipe": "./../../dist/index.mjs" | |||
| } | |||
| } | |||
| </script> | |||
| <style id="example-style"> | |||
| html, body, #canvas-container, #mcanvas { | |||
| width: 100%; | |||
| height: 100%; | |||
| margin: 0; | |||
| overflow: hidden; | |||
| } | |||
| </style> | |||
| <script type="module" src="../js-utils/simple-code-preview.mjs"> </script> | |||
| <script id="example-script" type="module"> | |||
| import {_testFinish, HemisphereLight, ThreeViewer} from 'threepipe' | |||
| const viewer = new ThreeViewer({canvas: document.getElementById('mcanvas'), msaa: true}) | |||
| async function init() { | |||
| viewer.scene.addObject(new HemisphereLight(0xffffff, 0x444444, 10)) | |||
| const result = await viewer.load('https://threejs.org/examples/models/obj/male02/male02.obj', { | |||
| autoCenter: true, | |||
| autoScale: true, | |||
| }) | |||
| console.log(result) | |||
| } | |||
| init().then(_testFinish) | |||
| </script> | |||
| </head> | |||
| <body> | |||
| <div id="canvas-container"> | |||
| <canvas id="mcanvas"></canvas> | |||
| </div> | |||
| </body> | |||
| @@ -0,0 +1,30 @@ | |||
| <!DOCTYPE html> | |||
| <html lang="en"> | |||
| <head> | |||
| <meta charset="UTF-8"> | |||
| <title>OBJ To GLB</title> | |||
| <!-- Import map --> | |||
| <script type="importmap"> | |||
| { | |||
| "imports": { | |||
| "threepipe": "./../../dist/index.mjs" | |||
| } | |||
| } | |||
| </script> | |||
| <style id="example-style"> | |||
| html, body, #canvas-container, #mcanvas { | |||
| width: 100%; | |||
| height: 100%; | |||
| margin: 0; | |||
| overflow: hidden; | |||
| } | |||
| </style> | |||
| <script type="module" src="../js-utils/simple-code-preview.mjs"> </script> | |||
| <script id="example-script" type="module" src="./script.js" data-scripts="./script.ts;./script.js"></script> | |||
| </head> | |||
| <body> | |||
| <div id="canvas-container"> | |||
| <canvas id="mcanvas"></canvas> | |||
| </div> | |||
| </body> | |||
| @@ -0,0 +1,42 @@ | |||
| import {_testFinish, downloadBlob, ThreeViewer} from 'threepipe' | |||
| const viewer = new ThreeViewer({canvas: document.getElementById('mcanvas') as HTMLCanvasElement, msaa: true}) | |||
| async function init() { | |||
| // load obj + mtl | |||
| await viewer.load('https://threejs.org/examples/models/obj/male02/male02.obj', { | |||
| autoCenter: true, | |||
| autoScale: true, | |||
| }) | |||
| // export to glb | |||
| const blob = await viewer.exportScene() | |||
| if (!blob || blob.ext !== 'glb') { | |||
| console.error('Unable to export scene') | |||
| return | |||
| } | |||
| // clear scene | |||
| viewer.scene.disposeSceneModels() | |||
| // load environment map and glb | |||
| await viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr') | |||
| await viewer.load({ | |||
| path: 'file.glb', | |||
| file: blob, | |||
| }) | |||
| // add download button | |||
| const downloadButton = document.createElement('button') | |||
| downloadButton.innerText = 'Download .glb' | |||
| downloadButton.style.position = 'absolute' | |||
| downloadButton.style.bottom = '3rem' | |||
| downloadButton.style.right = '3rem' | |||
| downloadButton.style.zIndex = '10000' | |||
| downloadButton.onclick = () => downloadBlob(blob, 'file.glb') | |||
| document.body.appendChild(downloadButton) | |||
| } | |||
| init().then(_testFinish) | |||
| @@ -0,0 +1,30 @@ | |||
| <!DOCTYPE html> | |||
| <html lang="en"> | |||
| <head> | |||
| <meta charset="UTF-8"> | |||
| <title>PMAT(Physical) Material export</title> | |||
| <!-- Import map --> | |||
| <script type="importmap"> | |||
| { | |||
| "imports": { | |||
| "threepipe": "./../../dist/index.mjs" | |||
| } | |||
| } | |||
| </script> | |||
| <style id="example-style"> | |||
| html, body, #canvas-container, #mcanvas { | |||
| width: 100%; | |||
| height: 100%; | |||
| margin: 0; | |||
| overflow: hidden; | |||
| } | |||
| </style> | |||
| <script type="module" src="../js-utils/simple-code-preview.mjs"> </script> | |||
| <script id="example-script" type="module" src="./script.js" data-scripts="./script.ts;./script.js"></script> | |||
| </head> | |||
| <body> | |||
| <div id="canvas-container"> | |||
| <canvas id="mcanvas"></canvas> | |||
| </div> | |||
| </body> | |||
| @@ -0,0 +1,53 @@ | |||
| import {_testFinish, downloadBlob, IMaterial, IObject3D, Mesh, SphereGeometry, ThreeViewer} from 'threepipe' | |||
| import {createSimpleButtons} from '../js-utils/simple-bottom-buttons.js' | |||
| const viewer = new ThreeViewer({canvas: document.getElementById('mcanvas') as HTMLCanvasElement, msaa: true}) | |||
| async function init() { | |||
| await viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr') | |||
| const helmet = await viewer.load<IObject3D>('https://threejs.org/examples/models/gltf/DamagedHelmet/glTF/DamagedHelmet.gltf', { | |||
| autoCenter: true, | |||
| autoScale: true, | |||
| }) | |||
| if (!helmet) { | |||
| alert('Unable to load model') | |||
| return | |||
| } | |||
| const mesh = helmet.getObjectByName('node_damagedHelmet_-6514')! | |||
| const material = mesh.materials?.[0] | |||
| helmet.position.setX(-3) | |||
| const sphere = new Mesh(new SphereGeometry(0.5, 32, 32), material) | |||
| sphere.position.setX(2) | |||
| await viewer.addSceneObject(sphere) | |||
| const matBlob = await viewer.assetManager.exporter.exportObject(material) | |||
| if (!matBlob) { | |||
| return | |||
| } | |||
| const material2 = await viewer.assetManager.importer.importSingle<IMaterial>({file: matBlob, path: 'mat.' + matBlob.ext}) | |||
| if (!material2) { | |||
| return | |||
| } | |||
| console.log(material2) | |||
| const sphere2 = new Mesh(new SphereGeometry(0.5, 32, 32), material2) | |||
| sphere2.position.setX(0) | |||
| await viewer.addSceneObject(sphere2) | |||
| createSimpleButtons({ | |||
| ['Download PMAT']: async() => { | |||
| const blob = await viewer.assetManager.exporter.exportObject(material) | |||
| if (!blob) { | |||
| alert('Unable to export material') | |||
| return | |||
| } | |||
| downloadBlob(blob, 'material.' + blob.ext) | |||
| }, | |||
| }) | |||
| } | |||
| init().then(_testFinish) | |||
| @@ -0,0 +1,30 @@ | |||
| <!DOCTYPE html> | |||
| <html lang="en"> | |||
| <head> | |||
| <meta charset="UTF-8"> | |||
| <title>Render Target Preview</title> | |||
| <!-- Import map --> | |||
| <script type="importmap"> | |||
| { | |||
| "imports": { | |||
| "threepipe": "./../../dist/index.mjs" | |||
| } | |||
| } | |||
| </script> | |||
| <style id="example-style"> | |||
| html, body, #canvas-container, #mcanvas { | |||
| width: 100%; | |||
| height: 100%; | |||
| margin: 0; | |||
| overflow: hidden; | |||
| } | |||
| </style> | |||
| <script type="module" src="../js-utils/simple-code-preview.mjs"> </script> | |||
| <script id="example-script" type="module" src="./script.js" data-scripts="./script.ts;./script.js"></script> | |||
| </head> | |||
| <body> | |||
| <div id="canvas-container"> | |||
| <canvas id="mcanvas"></canvas> | |||
| </div> | |||
| </body> | |||
| @@ -0,0 +1,30 @@ | |||
| import {_testFinish, DepthBufferPlugin, HalfFloatType, RenderTargetPreviewPlugin, ThreeViewer} from 'threepipe' | |||
| const viewer = new ThreeViewer({ | |||
| canvas: document.getElementById('mcanvas') as HTMLCanvasElement, | |||
| msaa: true, | |||
| rgbm: true, | |||
| zPrepass: false, | |||
| }) | |||
| async function init() { | |||
| const depth = viewer.addPluginSync(new DepthBufferPlugin(HalfFloatType, true)) | |||
| const targetPreview = viewer.addPluginSync(RenderTargetPreviewPlugin) | |||
| await viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr') | |||
| await viewer.load('https://threejs.org/examples/models/gltf/kira.glb', { | |||
| autoCenter: true, | |||
| autoScale: true, | |||
| }) | |||
| viewer.renderManager.autoBuildPipeline = false | |||
| viewer.renderManager.pipeline = ['depth', 'render', 'screen'] | |||
| targetPreview.addTarget(()=>depth.getTarget(), 'depth', false, true) | |||
| targetPreview.addTarget(()=>viewer.renderManager.composerTarget, 'composer-1', false, false) | |||
| targetPreview.addTarget(()=>viewer.renderManager.composerTarget2, 'composer-2', false, false) | |||
| } | |||
| init().then(_testFinish) | |||
| @@ -0,0 +1,42 @@ | |||
| <!DOCTYPE html> | |||
| <html lang="en"> | |||
| <head> | |||
| <meta charset="UTF-8"> | |||
| <title>Half float render pipeline test</title> | |||
| <!-- Import map --> | |||
| <script type="importmap"> | |||
| { | |||
| "imports": { | |||
| "threepipe": "./../../dist/index.mjs" | |||
| } | |||
| } | |||
| </script> | |||
| <style id="example-style"> | |||
| html, body, #canvas-container, #mcanvas { | |||
| width: 100%; | |||
| height: 100%; | |||
| margin: 0; | |||
| overflow: hidden; | |||
| } | |||
| </style> | |||
| <script type="module" src="../js-utils/simple-code-preview.mjs"> </script> | |||
| <script id="example-script" type="module"> | |||
| import {_testFinish, Mesh, SphereGeometry, UnlitMaterial, ThreeViewer} from 'threepipe' | |||
| const viewer = new ThreeViewer({ | |||
| canvas: document.getElementById('mcanvas'), | |||
| rgbm: true, | |||
| }) | |||
| const sphere = new Mesh(new SphereGeometry(1, 32, 32), new UnlitMaterial({color: '#ff0000'})) | |||
| viewer.scene.addObject(sphere) | |||
| _testFinish() | |||
| </script> | |||
| </head> | |||
| <body> | |||
| <div id="canvas-container"> | |||
| <canvas id="mcanvas"></canvas> | |||
| </div> | |||
| </body> | |||
| @@ -0,0 +1,42 @@ | |||
| <!DOCTYPE html> | |||
| <html lang="en"> | |||
| <head> | |||
| <meta charset="UTF-8"> | |||
| <title>MSAA Test</title> | |||
| <!-- Import map --> | |||
| <script type="importmap"> | |||
| { | |||
| "imports": { | |||
| "threepipe": "./../../dist/index.mjs" | |||
| } | |||
| } | |||
| </script> | |||
| <style id="example-style"> | |||
| html, body, #canvas-container, #mcanvas { | |||
| width: 100%; | |||
| height: 100%; | |||
| margin: 0; | |||
| overflow: hidden; | |||
| } | |||
| </style> | |||
| <script type="module" src="../js-utils/simple-code-preview.mjs"> </script> | |||
| <script id="example-script" type="module"> | |||
| import {_testFinish, Mesh, SphereGeometry, UnlitMaterial, ThreeViewer} from 'threepipe' | |||
| const viewer = new ThreeViewer({ | |||
| canvas: document.getElementById('mcanvas'), | |||
| msaa: true, | |||
| }) | |||
| const sphere = new Mesh(new SphereGeometry(1, 32, 32), new UnlitMaterial({color: '#ff0000'})) | |||
| viewer.scene.addObject(sphere) | |||
| _testFinish() | |||
| </script> | |||
| </head> | |||
| <body> | |||
| <div id="canvas-container"> | |||
| <canvas id="mcanvas"></canvas> | |||
| </div> | |||
| </body> | |||
| @@ -0,0 +1,42 @@ | |||
| <!DOCTYPE html> | |||
| <html lang="en"> | |||
| <head> | |||
| <meta charset="UTF-8"> | |||
| <title>RGBM Render pipeline test</title> | |||
| <!-- Import map --> | |||
| <script type="importmap"> | |||
| { | |||
| "imports": { | |||
| "threepipe": "./../../dist/index.mjs" | |||
| } | |||
| } | |||
| </script> | |||
| <style id="example-style"> | |||
| html, body, #canvas-container, #mcanvas { | |||
| width: 100%; | |||
| height: 100%; | |||
| margin: 0; | |||
| overflow: hidden; | |||
| } | |||
| </style> | |||
| <script type="module" src="../js-utils/simple-code-preview.mjs"> </script> | |||
| <script id="example-script" type="module"> | |||
| import {_testFinish, Mesh, SphereGeometry, UnlitMaterial, ThreeViewer} from 'threepipe' | |||
| const viewer = new ThreeViewer({ | |||
| canvas: document.getElementById('mcanvas'), | |||
| rgbm: true, | |||
| }) | |||
| const sphere = new Mesh(new SphereGeometry(1, 32, 32), new UnlitMaterial({color: '#ff0000'})) | |||
| viewer.scene.addObject(sphere) | |||
| _testFinish() | |||
| </script> | |||
| </head> | |||
| <body> | |||
| <div id="canvas-container"> | |||
| <canvas id="mcanvas"></canvas> | |||
| </div> | |||
| </body> | |||
| @@ -0,0 +1,8 @@ | |||
| { | |||
| "extends": "./tsconfig.json", | |||
| "compilerOptions": { | |||
| "paths": { | |||
| "threepipe": ["../dist/"] | |||
| }, | |||
| }, | |||
| } | |||
| @@ -0,0 +1,40 @@ | |||
| { | |||
| "compilerOptions": { | |||
| "baseUrl": "./", | |||
| "allowJs": false, | |||
| "checkJs": false, | |||
| "allowSyntheticDefaultImports": true, | |||
| "experimentalDecorators": true, | |||
| "isolatedModules": false, | |||
| "module": "es2020", | |||
| "noImplicitAny": true, | |||
| "declaration": false, | |||
| "noImplicitThis": true, | |||
| "noUnusedLocals": true, | |||
| "noUnusedParameters": true, | |||
| "removeComments": false, | |||
| "preserveConstEnums": true, | |||
| "moduleResolution": "node", | |||
| "emitDecoratorMetadata": true, | |||
| "sourceMap": false, | |||
| "paths": { | |||
| "threepipe": ["../src/"] | |||
| }, | |||
| "target": "ES2020", | |||
| "strictNullChecks": true, | |||
| "lib": [ | |||
| "es2020", | |||
| "esnext", | |||
| "dom" | |||
| ] | |||
| }, | |||
| "include": [ | |||
| "./**/*.ts" | |||
| ], | |||
| "exclude": [ | |||
| "node_modules", | |||
| "../dist/**/*", | |||
| "../src/**/*", | |||
| "**/*.spec.ts" | |||
| ] | |||
| } | |||
| @@ -0,0 +1,53 @@ | |||
| <!DOCTYPE html> | |||
| <html lang="en"> | |||
| <head> | |||
| <meta charset="UTF-8"> | |||
| <title>Z-Prepass test</title> | |||
| <!-- Import map --> | |||
| <script type="importmap"> | |||
| { | |||
| "imports": { | |||
| "threepipe": "./../../dist/index.mjs" | |||
| } | |||
| } | |||
| </script> | |||
| <style id="example-style"> | |||
| html, body, #canvas-container, #mcanvas { | |||
| width: 100%; | |||
| height: 100%; | |||
| margin: 0; | |||
| overflow: hidden; | |||
| } | |||
| </style> | |||
| <script type="module" src="../js-utils/simple-code-preview.mjs"> </script> | |||
| <script id="example-script" type="module"> | |||
| import {_testFinish, DepthBufferPlugin, UnsignedByteType, ThreeViewer} from 'threepipe' | |||
| async function init() { | |||
| const viewer = new ThreeViewer({ | |||
| canvas: document.getElementById('mcanvas'), | |||
| msaa: true, | |||
| rgbm: true, | |||
| zPrepass: true, | |||
| }) | |||
| viewer.addPluginSync(new DepthBufferPlugin(UnsignedByteType, true)) | |||
| await viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr') | |||
| await viewer.load('https://threejs.org/examples/models/gltf/kira.glb', { | |||
| autoCenter: true, | |||
| autoScale: true, | |||
| }) | |||
| } | |||
| init().then(_testFinish) | |||
| </script> | |||
| </head> | |||
| <body> | |||
| <div id="canvas-container"> | |||
| <canvas id="mcanvas"></canvas> | |||
| </div> | |||
| </body> | |||