| }) | }) | ||||
| createSimpleButtons({ | createSimpleButtons({ | ||||
| ['Download snapshot (rect png)']: async(btn: HTMLButtonElement) => { | |||||
| ['Download snapshot (jpeg)']: async(btn: HTMLButtonElement) => { | |||||
| btn.disabled = true | |||||
| await snapshotPlugin.downloadSnapshot('snapshot.jpeg', { | |||||
| mimeType: 'image/jpeg', // mime type of the image | |||||
| quality: 0.9, // quality of the image (0-1) only for jpeg and webp | |||||
| displayPixelRatio: 2, // render scale | |||||
| }) | |||||
| btn.disabled = false | |||||
| }, | |||||
| ['Download snapshot (1024x1024 size, png)']: async(btn: HTMLButtonElement) => { | |||||
| btn.disabled = true | |||||
| // save scale | |||||
| const scale = viewer.renderManager.renderScale | |||||
| // set fixed render size | |||||
| viewer.setRenderSize({width: 1024, height: 1024}) | |||||
| // (optional) hide the canvas. (not needed if you have an overlay) | |||||
| await snapshotPlugin.downloadSnapshot('snapshot.png', { | |||||
| mimeType: 'image/png', // mime type of the image | |||||
| }) | |||||
| // revert scale | |||||
| viewer.renderManager.renderScale = scale | |||||
| // revert render size to fill container | |||||
| viewer.setSize() | |||||
| btn.disabled = false | |||||
| }, | |||||
| ['Download snapshot (crop rect, png)']: async(btn: HTMLButtonElement) => { | |||||
| btn.disabled = true | btn.disabled = true | ||||
| await snapshotPlugin.downloadSnapshot('snapshot.png', { | await snapshotPlugin.downloadSnapshot('snapshot.png', { | ||||
| scale: 1, // scale the final image | scale: 1, // scale the final image | ||||
| }) | }) | ||||
| btn.disabled = false | btn.disabled = false | ||||
| }, | }, | ||||
| ['Download snapshot (jpeg)']: async(btn: HTMLButtonElement) => { | |||||
| btn.disabled = true | |||||
| await snapshotPlugin.downloadSnapshot('snapshot.jpeg', { | |||||
| mimeType: 'image/jpeg', // mime type of the image | |||||
| quality: 0.9, // quality of the image (0-1) only for jpeg and webp | |||||
| displayPixelRatio: 2, // render scale | |||||
| }) | |||||
| btn.disabled = false | |||||
| }, | |||||
| ['Download snapshot (webp)']: async(btn: HTMLButtonElement) => { | ['Download snapshot (webp)']: async(btn: HTMLButtonElement) => { | ||||
| btn.disabled = true | btn.disabled = true | ||||
| if (!isWebpExportSupported()) { | if (!isWebpExportSupported()) { |
| <li><a href="./custom-pipeline/">Custom Pipeline specification </a></li> | <li><a href="./custom-pipeline/">Custom Pipeline specification </a></li> | ||||
| <li><a href="./ssaa-plugin/">SSAA Plugin </a></li> | <li><a href="./ssaa-plugin/">SSAA Plugin </a></li> | ||||
| <li><a href="./msaa-ssaa/">MSAA + SSAA </a></li> | <li><a href="./msaa-ssaa/">MSAA + SSAA </a></li> | ||||
| <li><a href="./viewer-render-size/">Viewer Render Size </a></li> | |||||
| <li><a href="./depth-buffer-plugin/">Depth Buffer Plugin </a></li> | <li><a href="./depth-buffer-plugin/">Depth Buffer Plugin </a></li> | ||||
| <li><a href="./normal-buffer-plugin/">Normal Buffer Plugin </a></li> | <li><a href="./normal-buffer-plugin/">Normal Buffer Plugin </a></li> | ||||
| <li><a href="./gbuffer-plugin/">GBuffer Plugin <br/>(NormalDepth+Flags) </a></li> | <li><a href="./gbuffer-plugin/">GBuffer Plugin <br/>(NormalDepth+Flags) </a></li> | ||||
| <li><a href="./sphere-msaa-test/">MSAA Test </a></li> | <li><a href="./sphere-msaa-test/">MSAA Test </a></li> | ||||
| <li><a href="./z-prepass/">Z-Prepass Test </a></li> | <li><a href="./z-prepass/">Z-Prepass Test </a></li> | ||||
| <li><a href="./import-test/">Import Test</a></li> | <li><a href="./import-test/">Import Test</a></li> | ||||
| <li><a href="./js-image-data-test/">JS ImageData Test</a></li> | |||||
| <li><a href="./gltf-transmission-test-msaa-zprepass/">glTF Transmission Test + MSAA + zPrepass</a></li> | <li><a href="./gltf-transmission-test-msaa-zprepass/">glTF Transmission Test + MSAA + zPrepass</a></li> | ||||
| </ul> | </ul> | ||||
| </div> | </div> |
| <!DOCTYPE html> | |||||
| <html lang="en"> | |||||
| <head> | |||||
| <meta charset="UTF-8"> | |||||
| <title>JS ImageData test</title> | |||||
| <meta name="viewport" content="width=device-width, initial-scale=1"> | |||||
| <!-- Import maps polyfill --> | |||||
| <!-- Remove this when import maps will be widely supported --> | |||||
| <script async src="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js"></script> | |||||
| <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="../examples-utils/simple-code-preview.mjs"></script> | |||||
| <script id="example-script" type="module"> | |||||
| import {_testFinish, Mesh, SphereGeometry, ThreeViewer, UnlitMaterial, Texture} from 'threepipe' | |||||
| const viewer = new ThreeViewer({ | |||||
| canvas: document.getElementById('mcanvas'), | |||||
| rgbm: true, | |||||
| }) | |||||
| const sphere = new Mesh(new SphereGeometry(1, 32, 32), new UnlitMaterial({color: '#ffffff'})) | |||||
| const data = new ImageData(new Uint8ClampedArray([0, 255, 255, 255]), 1, 1) | |||||
| sphere.material.map = new Texture(data) | |||||
| // sphere.material.map.needsUpdate = true // not required since three.js v0.157.1006 | |||||
| viewer.scene.addObject(sphere) | |||||
| _testFinish() | |||||
| </script> | |||||
| </head> | |||||
| <body> | |||||
| <div id="canvas-container"> | |||||
| <canvas id="mcanvas"></canvas> | |||||
| </div> | |||||
| </body> |
| <!DOCTYPE html> | |||||
| <html lang="en"> | |||||
| <head> | |||||
| <meta charset="UTF-8"> | |||||
| <title>Viewer Render Size</title> | |||||
| <meta name="viewport" content="width=device-width, initial-scale=1"> | |||||
| <!-- Import maps polyfill --> | |||||
| <!-- Remove this when import maps will be widely supported --> | |||||
| <script async src="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js"></script> | |||||
| <script type="importmap"> | |||||
| { | |||||
| "imports": { | |||||
| "threepipe": "./../../dist/index.mjs", | |||||
| "@threepipe/plugin-tweakpane": "./../../plugins/tweakpane/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="../examples-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> |
| import {_testFinish, IObject3D, LoadingScreenPlugin, ThreeViewer} from 'threepipe' | |||||
| import {TweakpaneUiPlugin} from '@threepipe/plugin-tweakpane' | |||||
| async function init() { | |||||
| const viewer = new ThreeViewer({ | |||||
| canvas: document.getElementById('mcanvas') as HTMLCanvasElement, | |||||
| msaa: true, | |||||
| plugins: [LoadingScreenPlugin], | |||||
| }) | |||||
| const ui = viewer.addPluginSync(new TweakpaneUiPlugin(true)) | |||||
| await viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr', { | |||||
| setBackground: true, | |||||
| }) | |||||
| await viewer.load<IObject3D>('https://threejs.org/examples/models/gltf/DamagedHelmet/glTF/DamagedHelmet.gltf', { | |||||
| autoCenter: true, | |||||
| autoScale: true, | |||||
| }) | |||||
| // setup css alignment of canvas inside container | |||||
| viewer.container.style.position = 'relative' | |||||
| viewer.canvas.style.position = 'absolute' | |||||
| viewer.canvas.style.top = '50%' | |||||
| viewer.canvas.style.left = '50%' | |||||
| viewer.canvas.style.transform = 'translate(-50%, -50%)' | |||||
| const state = { | |||||
| width: 1280, | |||||
| height: 768, | |||||
| mode: 'contain' as 'contain' | 'cover' | 'fill' | 'scale-down' | 'none', | |||||
| dpr: 1, | |||||
| alignX: 0, | |||||
| alignY: 0, | |||||
| } | |||||
| viewer.setRenderSize({width: state.width, height: state.height}, state.mode, state.dpr) | |||||
| ui.appendChild({ | |||||
| type: 'folder', | |||||
| label: 'Render Size', | |||||
| value: state, | |||||
| expanded: true, | |||||
| onChange: ()=>{ | |||||
| viewer.setRenderSize({width: state.width, height: state.height}, state.mode, state.dpr) | |||||
| viewer.canvas.style.transform = `translate(${state.alignX * 100 - 50}%, ${state.alignY * 100 - 50}%)` | |||||
| }, | |||||
| children: [{ | |||||
| type: 'slider', | |||||
| label: 'Width', | |||||
| path: 'width', | |||||
| bounds: [10, 2048], | |||||
| stepSize: 10, | |||||
| }, { | |||||
| type: 'slider', | |||||
| label: 'Height', | |||||
| path: 'height', | |||||
| bounds: [10, 2048], | |||||
| stepSize: 10, | |||||
| }, { | |||||
| type: 'dropdown', | |||||
| label: 'Mode', | |||||
| children: ['contain', 'cover', 'fill', 'scale-down', 'none'].map((v) => ({label: v})), | |||||
| path: 'mode', | |||||
| }, { | |||||
| type: 'slider', | |||||
| label: 'DPR', | |||||
| path: 'dpr', | |||||
| bounds: [0.1, 4], | |||||
| stepSize: 0.1, | |||||
| }, { | |||||
| type: 'slider', | |||||
| label: 'AlignX', | |||||
| path: 'alignX', | |||||
| bounds: [-1, 1], | |||||
| stepSize: 0.01, | |||||
| }, { | |||||
| type: 'slider', | |||||
| label: 'AlignY', | |||||
| path: 'alignY', | |||||
| bounds: [-1, 1], | |||||
| stepSize: 0.01, | |||||
| }], | |||||
| }) | |||||
| } | |||||
| init().finally(_testFinish) |