UNPKG

threepipe

Version:

A 3D viewer framework built on top of three.js in TypeScript with a focus on quality rendering, modularity and extensibility.

76 lines (75 loc) 3.61 kB
import { _testFinish, downloadBlob, FloatType, GBufferPlugin, HalfFloatType, LoadingScreenPlugin, RenderTargetPreviewPlugin, ThreeViewer, } from 'threepipe'; import { createSimpleButtons } from '../examples-utils/simple-bottom-buttons.js'; const viewer = new ThreeViewer({ canvas: document.getElementById('mcanvas'), msaa: true, zPrepass: true, plugins: [LoadingScreenPlugin], }); async function init() { const gbufferPlugin = viewer.addPluginSync(new GBufferPlugin(HalfFloatType, true, // isPrimaryGBuffer (used for zprepass etc) true, // enabled by default true, // render the flags buffer (used for eg selective tonemapping) true, // render depth texture FloatType)); // render depth texture as Float type. available - UnsignedShort(16 bits), UnsignedInt(24 bits) or Float(32 bits) await viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr'); const model = await viewer.load('https://threejs.org/examples/models/gltf/kira.glb', { autoCenter: true, autoScale: true, }); let id = 1; model?.traverse((o) => { o.materials?.forEach(m => { if (!m.userData.gBufferData) m.userData.gBufferData = {}; if (!m.userData.gBufferData.materialId) m.userData.gBufferData.materialId = id += 10; }); }); // 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 gbufferTarget = gbufferPlugin.target; if (!gbufferTarget) { throw new Error('gbufferPlugin.target returned undefined'); } // to render depth buffer to screen, uncomment this line: // viewer.renderManager.screenPass.overrideReadBuffer = gbufferTarget const getNormalDepth = () => ({ texture: gbufferPlugin.normalDepthTexture }); const getFlags = () => ({ texture: gbufferPlugin.flagsTexture }); const getDepthTexture = () => ({ texture: gbufferPlugin.depthTexture }); const targetPreview = await viewer.addPlugin(RenderTargetPreviewPlugin); targetPreview.addTarget(getNormalDepth, 'normalDepth'); targetPreview.addTarget(getFlags, 'gBufferFlags'); targetPreview.addTarget(getDepthTexture, 'depthTexture'); const screenPass = viewer.renderManager.screenPass; createSimpleButtons({ ['Toggle Normal+Depth']: () => { const rt = getNormalDepth(); screenPass.overrideReadBuffer = screenPass.overrideReadBuffer?.texture === rt.texture ? null : rt; viewer.setDirty(); }, ['Toggle Gbuffer Flags']: () => { const rt = getFlags(); screenPass.overrideReadBuffer = screenPass.overrideReadBuffer?.texture === rt.texture ? null : rt; viewer.setDirty(); }, ['Toggle Depth Texture']: () => { const rt = getDepthTexture(); screenPass.overrideReadBuffer = screenPass.overrideReadBuffer?.texture === rt.texture ? null : rt; viewer.setDirty(); }, ['Download snapshot']: async (btn) => { 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().finally(_testFinish);