展示3D模型
参照版本: Web 3.7.0-220224001
简介
这里主要介绍如何在图形界面上展示3D模型,分为以下几个步骤:创建模型、上传模型、展示模型 和 模型交互。
本文创建模型以 Blender 为例,导出文件格式使用 fbx。使用 three.js 作为3D模型展示的引擎。
Blender 官方网站: https://www.blender.org/
Blender 官方中文文档: https://docs.blender.org/manual/zh-hans/3.2/
three.js 官方网站: https://threejs.org/
Blender 免费开源,对电脑的配置要求较低,有官方中文文档,并且与 three.js 兼容性好一些。当然也可以使用其他建模软件,比如:3DMax、Maya、Rhino等,最终导出成 three.js 支持的格式即可。three.js 支持的格式有:fbx、obj、ply、bvh、dae、glTF、json 等,不过目前测试在 3DMax 中使用贴图材质或直接添加颜色、Maya 中使用曲面颜色材质、Rhino 中使用金属材质时,在Web页面上显示模型,会存在一些材质贴图丢失或无使用的问题,实际使用时需要注意一下。
创建模型
创建模型
打开 Blender,点击菜单栏 文件 - 新建 - 常规,会看到界面中默认生成了一个模型,有三部分:一个正方体模型、一个相机 和 一个灯光,本文直接使用这个默认的模型为例。
导出模型
上传模型
备份工程
在设备 维护 - 工程维护 页面上,备份工程,不要设置密码,得到工程文件。
解压工程
以 tar.gz 格式将工程文件解压,得到 project 文件夹。
加入模型文件
project 文件夹下有一个 img 文件夹,将导出的模型文件放在这里。
构建工程文件
将 project 文件夹重新压缩成 tar.gz 格式。
还原工程
将压缩的文件作为工程文件,还原工程,就完成了上传模型。
使用three.js展示模型
下载 three.js
three.js 下载地址: https://github.com/mrdoob/three.js/archive/refs/tags/r147.zip ,下载后得到一个压缩包。
导入 three.js 和插件
在UI界面里 创建一个页面,在页面的 加载事件 中,添加以下插件的代码。插件和插件之间使用 英文分号 和 换行 分开。
添加代码,创建3D场景
创建自定义控件
在页面中添加一个自定义控件。
添加模型容器
在自定义控件的 Code 属性中写入:
<div id="app"></div>
添加展示模型代码
在自定义控件的 加载事件 中加入下面的代码。注意代码中的路径 ../project/img/test.fbx,这个路径就是之前导入工程的模型文件路径,上面我们保存的模型文件名为 test.fbx,所以路径为../project/img/test.fbx,如果是其他名称,需要相的修改一下。
// 创建场景 let scene = new THREE.Scene(); let pcWidth = getAttr(thisId, "width"); let pcHeight = getAttr(thisId, "height"); // 创建相机 let camera = new THREE.PerspectiveCamera(85, pcWidth / pcHeight, 0.01, 10000); // 修改相机的位置 camera.position.set(0, 140, 230); camera.lookAt(scene.position); // 创建渲染器 let renderer = new THREE.WebGLRenderer(); // 设置渲染器的颜色 renderer.setClearColor(new THREE.Color(0x4C7BBb)); // 设置渲染器的大小 renderer.setSize(pcWidth, pcHeight); // 循环渲染回调 anmiate() // 添加环境光,参数一为颜色,参数二为亮度值,范围在0-1之间。默认值为1 let ambient = new THREE.AmbientLight(0xffffff, 0.7); scene.add(ambient); document.getElementById("app").appendChild(renderer.domElement); const controls = new THREE.OrbitControls(camera, renderer.domElement); // 循环渲染 function anmiate() { renderer.render(scene, camera) requestAnimationFrame(anmiate) } const loaderFBX = new THREE.FBXLoader(); loaderFBX.load('../project/img/test.fbx', function (objFBX) { scene.add(objFBX); });
保存页面、运行,就可以看到模型了。
模型交互
添加文字控件,用来查看模型的名称。
在页面上添加一个 文字 控件,ID属性改为 model_name,放置到页面的外部,为了方便观看,也修改了 背景颜色、边框宽度、文字颜色 属性。
添加交互代码
在自定义控件的 加载事件 中继续添加以下代码。
// 添加点击事件 document.getElementById(thisId).addEventListener("pointerdown", onpointerdown) // 创建Raycaster const raycaster = new THREE.Raycaster(); // 创建二维向量 const pointer = new THREE.Vector2(); // 点击事件函数 function onpointerdown(event) { // 计算event.offset坐标值相对于three.js里的坐标值 pointer.x = (event.offsetX - (pcWidth / 2)) / (pcWidth / 2); pointer.y = -((event.offsetY - (pcHeight / 2)) / (pcHeight / 2)); raycaster.setFromCamera(pointer, camera); // 被选中的模型列表 let intersects = raycaster.intersectObjects(scene.children); // 有模型被选中时,显示文字控件,并显示模型名称 if (intersects.length > 0) { setAttr('model_name', { x: event.offsetX + getAttr(thisId, "x"), y: event.offsetY + getAttr(thisId, "y"), visibility: false, text: intersects[0].object.name }); // 没有模型被选中,隐藏文字控件 } else { setAttr('model_name', "visibility", true); } }
保存页面、运行,查看效果
点击立方体,文字 控件会出现在鼠标点击的位置,并显示立方体的名称,点击立方体以外的地方文字会隐藏。
可以看到立方体的名称为 Cube,在 Blender 里可以编辑该名称,如果有多个模型,用不同的名称就可以做出区分。