<!DOCTYPE html> <html lang="en"> <head> <title>three.js webgl - USDZ exporter</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> <link type="text/css" rel="stylesheet" href="main.css"> <style> body { background-color: #eee; } #info { color: #222; } a { color: #00f } #button { position: absolute; bottom: 15px; left: calc(50% - 40px); } </style> </head> <body> <div id="info"> <a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - USDZ exporter<br /> Battle Damaged Sci-fi Helmet by <a href="https://sketchfab.com/theblueturtle_" target="_blank" rel="noopener">theblueturtle_</a> </div> <a id="link" rel="ar" href="" download="asset.usdz"> <img id="button" width="100" src="files/arkit.png"> </a> <!-- Import maps polyfill --> <!-- Remove this when import maps will be widely supported --> <script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script> <script type="importmap"> { "imports": { "three": "../build/three.module.js", "three/addons/": "./jsm/" } } </script> <script type="module"> import * as THREE from 'three'; import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js'; import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; import { USDZExporter } from 'three/addons/exporters/USDZExporter.js'; let camera, scene, renderer; init(); render(); function init() { renderer = new THREE.WebGLRenderer( { antialias: true } ); renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); renderer.toneMapping = THREE.ACESFilmicToneMapping; renderer.outputEncoding = THREE.sRGBEncoding; document.body.appendChild( renderer.domElement ); camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.25, 20 ); camera.position.set( - 2.5, 0.6, 3.0 ); const pmremGenerator = new THREE.PMREMGenerator( renderer ); scene = new THREE.Scene(); scene.background = new THREE.Color( 0xf0f0f0 ); scene.environment = pmremGenerator.fromScene( new RoomEnvironment(), 0.04 ).texture; const loader = new GLTFLoader().setPath( 'models/gltf/DamagedHelmet/glTF/' ); loader.load( 'DamagedHelmet.gltf', async function ( gltf ) { scene.add( gltf.scene ); const shadowMesh = createSpotShadowMesh(); shadowMesh.position.y = - 1.1; shadowMesh.position.z = - 0.25; shadowMesh.scale.setScalar( 2 ); scene.add( shadowMesh ); render(); // USDZ const exporter = new USDZExporter(); const arraybuffer = await exporter.parse( gltf.scene ); const blob = new Blob( [ arraybuffer ], { type: 'application/octet-stream' } ); const link = document.getElementById( 'link' ); link.href = URL.createObjectURL( blob ); } ); const controls = new OrbitControls( camera, renderer.domElement ); controls.addEventListener( 'change', render ); // use if there is no animation loop controls.minDistance = 2; controls.maxDistance = 10; controls.target.set( 0, - 0.15, - 0.2 ); controls.update(); window.addEventListener( 'resize', onWindowResize ); } function createSpotShadowMesh() { const canvas = document.createElement( 'canvas' ); canvas.width = 128; canvas.height = 128; const context = canvas.getContext( '2d' ); const gradient = context.createRadialGradient( canvas.width / 2, canvas.height / 2, 0, canvas.width / 2, canvas.height / 2, canvas.width / 2 ); gradient.addColorStop( 0.1, 'rgba(130,130,130,1)' ); gradient.addColorStop( 1, 'rgba(255,255,255,1)' ); context.fillStyle = gradient; context.fillRect( 0, 0, canvas.width, canvas.height ); const shadowTexture = new THREE.CanvasTexture( canvas ); const geometry = new THREE.PlaneGeometry(); const material = new THREE.MeshBasicMaterial( { map: shadowTexture, blending: THREE.MultiplyBlending, toneMapped: false } ); const mesh = new THREE.Mesh( geometry, material ); mesh.rotation.x = - Math.PI / 2; return mesh; } function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize( window.innerWidth, window.innerHeight ); render(); } // function render() { renderer.render( scene, camera ); } </script> </body> </html>