Skip to content
扫码开始移动端阅读
随便玩玩Three.js
共
1370
字 需要≈
6.85
分钟 奇淫技巧
ThreeJs
首先看一下效果
🔍 滚轮可以放大,
🔄 左右拖动可以旋转视角
🛰️ Ctrl+拖动 移动视角
制作一个模型
首先要在appStore 下载一个软件,名字叫 3d Scanner App.
其次最好你的手机支持3d雷达。所有的iphone都是有面部的雷达,但是只有iphone 12 pro 以上的手机是有后面的雷达。同样,ipad Pro 也是有雷达的。
接着。你就可以扫描一个模型了。这个App比较傻瓜式。这里就不详细说明了。
导出模型
这个软件可以导出很多格式。
OBJ(Wavefront Object)
- 描述: OBJ是一种简单的文本格式,用于描述三维模型的几何形状和材质信息。
- 特点: 可以包含顶点、法线、纹理坐标等信息,但不支持动画和复杂的材质属性。
- 应用: 主要用于静态模型的导入和导出。
GLTF(GL Transmission Format)
- 描述: GLTF是一种基于JSON的文件格式,用于有效地传输和加载三维模型,支持材质、动画和其他属性。
- 特点: 支持PBR材质、动画、节点层次结构等高级特性,适合Web和移动应用。
- 应用: 被广泛应用于虚拟现实、增强现实和游戏开发领域。
GLB
- 描述: GLB是GLTF的二进制版本,将所有模型数据打包在一个文件中,提高加载效率。
- 特点: 包含模型的几何、材质、动画等数据,适合网络传输和实时加载。
- 应用: 在需要快速加载和高性能的场景中使用。
STL(Stereolithography)
- 描述: STL是一种用于表示三维表面几何的文件格式,通常用于3D打印。
- 特点: 简单且易于解析,适合描述几何形状的表面。
- 应用: 主要用于3D打印和CAD软件之间的数据交换。
Point Cloud
- 描述: Point Cloud是一组点的集合,用于表示物体的表面或场景的形状。
- 特点: 可以描述真实世界中的场景,但需要大量的点数据。
- 应用: 用于激光扫描、三维重建和虚拟现实等领域。
DAE(Digital Asset Exchange)
- 描述: DAE是一种基于XML的文件格式,用于交换数字资产,包括三维模型、动画和材质。
- 特点: 支持多种属性和节点信息,适合复杂的三维场景描述。
- 应用: 在建模软件和游戏引擎之间进行数据交换和共享。
FBX
- 描述: FBX是Autodesk开发的一种通用的三维文件格式,支持多种三维软件之间的数据交换。
- 特点: 包含几何、材质、动画、节点层次结构等多种数据,适用于复杂的三维场景。
- 应用: 在不同的三维软件之间进行数据交换和合作。
TIP
当然,我们今天选择的是GLB。本来从通用性考虑,STL是最好的选择,但是STL是没有色彩信息的,
显示模型
代码比较简单,毕竟是第一次玩,写的不好轻喷。
vue
<template>
<!-- 定义一个容器用于渲染3D场景 -->
<div ref="container" class="mt-2 cursor-move" style="height: 500px"></div>
</template>
<script setup>
import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { onMounted, ref, defineProps } from 'vue';
// 定义props,接收外部传入的模型路径
const props = defineProps({
src: {
type: String,
required: true,
},
});
// 创建一个ref用于引用容器元素
const container = ref(null);
// 在组件挂载后执行的操作
onMounted(() => {
// 创建一个场景
const scene = new THREE.Scene();
// 获取容器的宽度和高度
const width = container.value.clientWidth;
const height = container.value.clientHeight;
// 创建透视相机
const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000);
// 创建WebGL渲染器
const renderer = new THREE.WebGLRenderer({ alpha: true });
renderer.setSize(width, height);
// 将渲染器的dom元素添加到容器中
container.value.appendChild(renderer.domElement);
// 加载模型的函数
const loadModel = (modelPath) => {
const loader = new GLTFLoader();
loader.load(modelPath, (gltf) => {
const model = gltf.scene;
// 计算模型包围盒中心
const box = new THREE.Box3().setFromObject(model);
const center = box.getCenter(new THREE.Vector3());
// 将模型居中
model.position.sub(center);
scene.add(model);
});
};
// 创建控制器
const controls = new OrbitControls(camera, renderer.domElement);
// 窗口大小改变时的处理函数
const resize = () => {
const width = container.value.clientWidth;
const height = container.value.clientHeight;
// 更新相机的长宽比例和投影矩阵
camera.aspect = width / height;
camera.updateProjectionMatrix();
renderer.setSize(width, height);
};
// 监听窗口大小改变事件
window.addEventListener('resize', resize);
// 设置相机位置
camera.position.set(0, 0, 10);
camera.position.z = 5;
// 动画函数
const animate = () => {
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
};
// 加载模型并开始动画
loadModel(props.src);
animate();
});
</script>
优化
增加Loading
因为有些模型比较大,所以要加载很久,最好增加一个loading框.
页面
html
<div ref="container" class="mt-2 cursor-move" style="height: 500px">
<div class="w-full h-full flex items-center justify-center" v-if="isLoading">
// [!code focus] <span class="loading loading-lg text-primary"></span>
</div>
</div>
脚本
js
const isLoading = ref(true);
const loadModel = (modelPath) => {
const loader = new GLTFLoader();
loader.load(modelPath, (gltf) => {
const model = gltf.scene;
// 计算模型包围盒中心
const box = new THREE.Box3().setFromObject(model);
const center = box.getCenter(new THREE.Vector3());
// 将模型居中
model.position.sub(center);
scene.add(model);
isLoading.value = false;
});
};
总结
OrbitControls
真的很好用,完全不用手动实现镜头的控制了。具体感兴趣的可以看看文档OrbitControls
THREE.js 也是真的好玩,希望以后能有机会再深度玩玩。
转载请注明来源:LeeDaisen : 《随便玩玩Three.js》