寻求Autodesk Forge Reality Capture生成OBJ接入网页3D查看器的简易示例
极简OBJ 3D查看器实现方案
核心特性
- 单HTML文件,纯前端实现,无需后端服务、无需Node.js环境
- 自动读取URL参数中的模型地址,支持直接加载公网OBJ模型
- 支持鼠标/触摸交互:旋转、缩放、平移查看
- 全屏自适应,支持iframe嵌入
完整实现代码
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>3D模型查看器</title> <style> * { margin: 0; padding: 0; } html, body { width: 100%; height: 100%; overflow: hidden; } canvas { display: block; width: 100%; height: 100%; } </style> <!-- 引入Three.js相关依赖 --> <script src="https://cdn.jsdelivr.net/npm/three@0.158.0/build/three.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/three@0.158.0/examples/js/loaders/OBJLoader.js"></script> <script src="https://cdn.jsdelivr.net/npm/three@0.158.0/examples/js/loaders/MTLLoader.js"></script> <script src="https://cdn.jsdelivr.net/npm/three@0.158.0/examples/js/controls/OrbitControls.js"></script> </head> <body> <script> // 读取URL参数 const params = new URLSearchParams(window.location.search); const modelUrl = params.get('url'); if (!modelUrl) { document.body.innerHTML = '<p style="padding: 20px; font-size: 16px;">请指定模型URL参数,格式:?url=你的OBJ模型公网地址</p>'; } // 初始化3D场景 const scene = new THREE.Scene(); scene.background = new THREE.Color(0xf0f0f0); // 初始化相机 const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.set(0, 0, 10); // 初始化渲染器 const renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setPixelRatio(window.devicePixelRatio); document.body.appendChild(renderer.domElement); // 添加光照 const ambientLight = new THREE.AmbientLight(0xffffff, 0.6); scene.add(ambientLight); const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8); directionalLight.position.set(10, 10, 10); scene.add(directionalLight); // 初始化交互控制器 const controls = new THREE.OrbitControls(camera, renderer.domElement); controls.enableDamping = true; controls.dampingFactor = 0.05; // 加载模型 const mtlLoader = new THREE.MTLLoader(); const objLoader = new THREE.OBJLoader(); // 尝试先加载同路径MTL材质 const mtlUrl = modelUrl.replace(/\.obj$/i, '.mtl'); mtlLoader.load(mtlUrl, (materials) => { materials.preload(); objLoader.setMaterials(materials); loadObj(); }, undefined, () => { // 没有MTL文件直接加载OBJ loadObj(); }); function loadObj() { objLoader.load(modelUrl, (obj) => { // 模型居中适配 const box = new THREE.Box3().setFromObject(obj); const center = box.getCenter(new THREE.Vector3()); const size = box.getSize(new THREE.Vector3()); const maxDim = Math.max(size.x, size.y, size.z); const scale = 5 / maxDim; obj.scale.multiplyScalar(scale); obj.position.sub(center.multiplyScalar(scale)); scene.add(obj); // 调整相机位置适配模型大小 camera.position.z = maxDim * scale * 2; controls.target.copy(obj.position); controls.update(); }, undefined, (err) => { document.body.innerHTML = '<p style="padding: 20px; font-size: 16px; color: red;">模型加载失败,请检查URL是否有效、是否配置跨域规则</p>'; console.error(err); }); } // 窗口自适应 window.addEventListener('resize', () => { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); }); // 渲染循环 function animate() { requestAnimationFrame(animate); controls.update(); renderer.render(scene, camera); } animate(); </script> </body> </html>
使用说明
- 部署:将上述代码保存为
viewer.html,上传到任意静态服务器(可直接托管在OSS、Nginx静态目录等,无需后端接口支持) - 直接访问:访问地址拼接参数即可,示例:
https://你的域名/viewer.html?url=http://cloud1.tri-di.com/data/uploaded/xxx/result.obj - iframe嵌入:直接用一行代码嵌入到任意页面中,示例:
<iframe src="https://你的域名/viewer.html?url=http://cloud1.tri-di.com/data/uploaded/xxx/result.obj" width="100%" height="900" frameborder="0" allowfullscreen></iframe>
常见问题解决
- 加载失败提示跨域:在你存储模型文件的服务器配置CORS规则,允许查看器所在域名的GET请求即可,OSS类存储服务可直接在后台配置跨域规则。
- 材质/纹理不显示:确保OBJ配套的MTL文件、纹理图片和OBJ在同一公网路径下,文件名和OBJ内引用的路径一致。
- 需要加载ZIP压缩包:可引入
JSZip库,前端直接读取GET参数传入的ZIP包地址,自动解压后读取内部的OBJ、MTL及纹理文件即可,无需修改现有模型导出流程。
内容的提问来源于stack exchange,提问作者mcgregor94086
相关产品推荐
相关产品推荐

