<!doctype html> <html lang="en"> <head> <meta charset="utf-8" /> <title>depthmap-viewer-three</title> <style> body { font-family: sans-serif; margin: 0; } .dropzone { box-sizing: border-box; display: none; position: fixed; width: 100%; height: 100%; left: 0; top: 0; z-index: 99999; background: rgba(#60a7dc, .8); border: 11px dashed #60a7dc; } </style> <script async src="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js"></script> <script type="importmap"> { "imports": { "three": "https://unpkg.com/three@0.154.0/build/three.module.js", "three/addons/": "https://unpkg.com/three@0.154.0/examples/jsm/" } } </script> <script type="module"> import * as THREE from 'three'; import { OrbitControls } from "three/addons/controls/OrbitControls"; import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; var rgbBase64Img = window.frameElement?.getAttribute('data-rgb') || "public/images/rgb.png" var depthBase64Img = window.frameElement?.getAttribute('data-depth') || "public/images/depth.png" let mesh; let material; let stopAnimation = false; const settings = { metalness: 0.0, roughness: 0.5, ambientIntensity: 0.85, displacementScale: 100, displacementBias: -0.5, }; const meshSettings = { rotation: { x: 0, y: 0, z: 0 } } // init const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000); camera.position.z = 3; const scene = new THREE.Scene(); const ambientLight = new THREE.AmbientLight(0xffffff, 0.5); scene.add(ambientLight); const pointLight = new THREE.PointLight(0xff0000, 0.5); pointLight.position.z = 2500; scene.add(pointLight); const renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setAnimationLoop(animation); // renderer.xr.enabled = true; renderer.toneMapping = THREE.ACESFilmicToneMapping; renderer.toneMappingExposure = 1; renderer.outputEncoding = THREE.sRGBEncoding; document.body.appendChild(renderer.domElement); // animation function animation(time) { if (mesh && !stopAnimation) { mesh.rotation.x = 0.5 * Math.sin(time / 2000); mesh.rotation.y = 0.5 * Math.sin(time / 2000); meshSettings.rotation.x = mesh.rotation.x; meshSettings.rotation.y = mesh.rotation.y; } renderer.render(scene, camera); } function onWindowResize() { const aspect = window.innerWidth / window.innerHeight; camera.aspect = aspect; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); } window.addEventListener('resize', onWindowResize); // orbit controls const controls = new OrbitControls(camera, renderer.domElement); controls.enableZoom = true; controls.enableDamping = true; async function getCanvasTexture(imageSrc) { return new Promise((resolve, reject) => { const image = new Image(); image.src = imageSrc; image.onload = () => { const ctx = document.createElement('canvas').getContext('2d'); ctx.canvas.width = image.width; ctx.canvas.height = image.height; ctx.drawImage(image, 0, 0, image.width, image.height); const texture = new THREE.CanvasTexture(ctx.canvas); resolve(texture); } }) } (async () => { const rgbTexture = await getCanvasTexture(rgbBase64Img); const depthTexture = await getCanvasTexture(depthBase64Img); if (mesh) { mesh.geometry.dispose(); mesh.material.dispose(); scene.remove(mesh); } // material material = new THREE.MeshStandardMaterial({ color: 0xaaaaaa, roughness: settings.roughness, metalness: settings.metalness, map: rgbTexture, displacementMap: depthTexture, displacementScale: settings.displacementScale, displacementBias: settings.displacementBias, side: THREE.DoubleSide }); // generating geometry and add mesh to scene const geometry = new THREE.PlaneGeometry(rgbTexture.image.width, rgbTexture.image.height, 512, 512); mesh = new THREE.Mesh(geometry, material); const scale = 1 / Math.max(rgbTexture.image.width, rgbTexture.image.height); mesh.scale.set(scale, scale, scale); scene.add(mesh); })() // setup gui const gui = new GUI(); gui.close(); const sceneGUI = gui.addFolder('Scene'); sceneGUI.add(settings, 'metalness').min(0).max(1).onChange(function (value) { material.metalness = value; }); sceneGUI.add(settings, 'roughness').min(0).max(1).onChange(function (value) { material.roughness = value; }); sceneGUI.add(settings, 'ambientIntensity').min(0).max(1).onChange(function (value) { ambientLight.intensity = value; }); sceneGUI.add(settings, 'displacementScale').min(0).max(500.0).onChange(function (value) { material.displacementScale = value; }); sceneGUI.add(settings, 'displacementBias').min(-500).max(500).onChange(function (value) { material.displacementBias = value; }); const meshGUI = gui.addFolder('Mesh'); meshGUI.add(meshSettings.rotation, 'x').min(-Math.PI).max(Math.PI).step(0.0001).onChange(function (value) { mesh.rotation.x = value; stopAnimation = true; }).listen() meshGUI.add(meshSettings.rotation, 'y').min(-Math.PI).max(Math.PI).step(0.0001).onChange(function (value) { mesh.rotation.y = value; stopAnimation = true; }).listen() meshGUI.add(meshSettings.rotation, 'z').min(-Math.PI).max(Math.PI).step(0.0001).onChange(function (value) { mesh.rotation.z = value; stopAnimation = true; }).listen() </script> </head> <body> </body> </html>