| <!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
|
| }
|
| }
|
|
|
|
|
| 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.toneMapping = THREE.ACESFilmicToneMapping;
|
| renderer.toneMappingExposure = 1;
|
| renderer.outputEncoding = THREE.sRGBEncoding;
|
| document.body.appendChild(renderer.domElement);
|
|
|
|
|
| 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);
|
|
|
|
|
|
|
| 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 = new THREE.MeshStandardMaterial({
|
|
|
| color: 0xaaaaaa,
|
| roughness: settings.roughness,
|
| metalness: settings.metalness,
|
|
|
| map: rgbTexture,
|
|
|
| displacementMap: depthTexture,
|
| displacementScale: settings.displacementScale,
|
| displacementBias: settings.displacementBias,
|
|
|
| side: THREE.DoubleSide
|
|
|
| });
|
|
|
| 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);
|
|
|
| })()
|
|
|
|
|
|
|
|
|
| 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> |