three.js 3d模型使用|vue项目使用three.js

发布时间 2023-12-12 16:01:49作者: 朝颜浅语

three.js 3D模型使用

安装

安装three.js

npm install three

安装轨道控件插件

npm install three-orbit-controls

安装加载.obj和.mtl文件的插件

npm install --save three-obj-mtl-loader

安装渲染器插件

npm install --save three-css2drender

导入

import * as Three from "three";
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import { ConvexGeometry } from 'three/examples/jsm/geometries/ConvexGeometry.js'
import {BufferGeometryUtils} from 'three/examples/jsm/utils/BufferGeometryUtils.js'
// import { OBJLoader, MTLLoader } from 'three-obj-mtl-loader'
import {OBJLoader} from 'three/examples/jsm/loaders/OBJLoader.js';
import {MTLLoader} from 'three/examples/jsm/loaders/MTLLoader.js';

创建3Ddemo

创建场景对象Scene
var scene = new THREE.Scene();
创建几何模型
// var geometry = new THREE.SphereGeometry(60, 40, 40); //创建一个球体几何对象(球体半径,水平细分数,垂直细分数)
var geometry = new THREE.BoxGeometry(100, 100, 100); //创建一个立方体几何对象Geometry
模型的格式Geometry和BufferGeometry

当前Three.js内置了这两种几何体类型,这两个几何体类型都是用于存储模型的顶点位置、面的索引、法向量、颜色、uv纹理以及一些自定义的属性。
它们两个的区别是:BufferGeometry存储的都是一些原始的数据,性能比Geometry的性能高,很适合存储一些放入场景内不需要再额外操作的模型。而Geometry的优势刚好相反,Geometry比BufferGeometry更友好,使用了Three.js提供的THREE.Vector3或者THREE.Color这样的对象来存储数据(顶点位置,面,颜色等),这些对象易于阅读和编辑,但效率低于BufferGeometry使用的类型化数组。

Geometry和BufferGeometry互转
//实例化一个Geometry对象
var geo = new THREE.Geometry(); 
//调用对象的fromBufferGeometry方法,并将需要转换的bufferGeometry传入
geo.fromBufferGeometry(bufferGeometry);
//geo为转换转换成的Geometry
模型平移
mesh.position.set(120, 0, 0);//设置mesh3模型对象的xyz坐标为120,0,0
mesh.translateX(120); //球体网格模型沿X轴正方向平移120
自定义几何体
// 自定义几何体
var geometry1 = new THREE.BufferGeometry(); //创建一个Buffer类型几何体对象

//类型数组创建顶点数据
var vertices = new Float32Array([
    0, 0, 0, //顶点1坐标
    50, 0, 0, //顶点2坐标
    0, 100, 0, //顶点3坐标
    0, 0, 10, //顶点4坐标
    0, 0, 100, //顶点5坐标
    50, 0, 10, //顶点6坐标
]);
// 创建属性缓冲区对象
var attribue = new THREE.BufferAttribute(vertices, 3); //3个为一组,表示一个顶点的xyz坐标
// 设置几何体attributes属性的位置属性
geometry1.attributes.position = attribue;
网格渲染模式
// 三角面(网格)渲染模式
var material = new THREE.MeshBasicMaterial({
    color: 0x0000ff, //三角面颜色
    side: THREE.DoubleSide //两面可见
}); //材质对象
var mesh_zidingyi = new THREE.Mesh(geometry1, material); //网格模型对象Mesh
点渲染模式
// 点渲染模式
var material = new THREE.PointsMaterial({
  color: 0xff0000,
  size: 10.0 //点对象像素尺寸
}); //材质对象
var points = new THREE.Points(geometry, material); //点模型对象
scene.add(points); //点对象添加到场景中
线渲染模式
// 线条渲染模式
var material=new THREE.LineBasicMaterial({
    color:0xff0000 //线条颜色
});//材质对象
var line=new THREE.Line(geometry,material);//线条模型对象
scene.add(line);//线条对象添加到场景中
创建材质对象
var material = new THREE.MeshLambertMaterial({
    color: '#ffff66', //材质颜色
    opacity: 0.8, // 材质透明度
    transparent: true, // 开启透明效果
    wireframe:false, // 几何图形渲染为线框
}); //材质对象Material

//可以访问材质对象的属性设置 单独控制样式
this.material.opacity = 0.5;
this.material.transparent = true;
创建网格模型
var mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
scene.add(mesh); //网格模型添加到场景中
光源设置
点光源
var point = new THREE.PointLight(0xffffff);
point.position.set(400, 200, 300); //点光源位置
scene.add(point); //点光源添加到场景中
环境光
var ambient = new THREE.AmbientLight(0x444444);
scene.add(ambient);
相机设置
var width = window.innerWidth; //窗口宽度
var height = window.innerHeight; //窗口高度
var k = width / height; //窗口宽高比
var s = 200; //三维场景显示范围控制系数,系数越大,显示的范围越大
创建相机对象
var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
camera.position.set(200, 300, 200); //设置相机位置
camera.lookAt(scene.position); //设置相机方向(指向的场景对象)
创建渲染器对象
var renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);//设置渲染区域尺寸
renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
document.body.appendChild(renderer.domElement); //body元素中插入canvas对象
执行渲染操作 指定场景、相机作为参数
renderer.render(scene, camera);

功能

旋转
// 旋转渲染函数
render() {
    this.T1 = new Date();//本次时间
    let t = this.T1 - this.T0;//时间差
    console.log(t);
    this.T0 = this.T1;//把本次时间赋值给上次时间
    this.mesh.rotateY(0.0006 * t);//每秒旋转0.6弧度
    this.renderer.render(this.scene, this.camera);//执行渲染操作
    requestAnimationFrame(this.render) // 根据浏览器刷新频率实时控制循环时间
}
平移
this.mesh.translateX(100);//沿着x轴正方向平移距离100
缩放
this.mesh.scale.x = 2.0;
this.mesh.scale.set(0.5, 1.5, 2)
位置
this.mesh.position.set(80,2,10);
this.mesh.position.y = 80;

鼠标操作

var controls = new OrbitControls(this.camera, this.renderer.domElement);//创建控件对象
controls.addEventListener('change', this.render);//监听鼠标、键盘事件