共计 4068 个字符,预计需要花费 11 分钟才能阅读完成。
npm install --save three@0.149.0
页面引入 three.js
import * as THREE from 'three'
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls.js'
import {GLTFLoader} from 'three/examples/jsm/loaders/GLTFLoader.js';
import {FBXLoader} from 'three/examples/jsm/loaders/FBXLoader.js';
创建 three.js 场景
init() {
// 创建一个场景
this.scene = new THREE.Scene()
// 三位坐标线
// const axesHelper = new THREE.AxesHelper(5);
// this.scene.add(axesHelper);
// 创建相机对象,45 是相机的视角,宽高比是屏幕的宽高比,最近能看到 0.1,最远能看到 10000
// this.camera = new THREE.OrthographicCamera(-s * k, s * k, s , -s, 1, 1000);
// this.camera.position.set(0, 20, 300);
this.camera = new THREE.PerspectiveCamera()
//100,300,500
this.camera.position.set(500, 0, 700); // 设置相机位置
// this.camera.position.set(100, -800, 500);
// this.scene.position.set(0,40,0)
console.log(this.scene.position)
this.camera.lookAt(this.scene.position); // 设置相机方向 (指向的场景对象)
// 执行一个渲染函数
this.rendererGLR()
/* 光源设置 */
this.pointLight()
this.clock = new THREE.Clock()
// 创建控件对象
this.change()
// 更新轨道控件
this.animate()
let fileName = this.modelUrl.lastIndexOf(".")
let fileFormat = this.modelUrl.substring(fileName + 1, this.modelUrl.length).toLowerCase()
if (fileFormat == 'fbx') {this.fbxLoader()
} else if(fileFormat == 'glb') {this.gblLoader()
}
this.renderer.render(this.scene, this.camera);
},
渲染
// 渲染函数
rendererGLR(){this.$nextTick(() => {const element = document.getElementById('threeView')
this.renderer.setSize(element.clientWidth, element.clientHeight);
element.appendChild(this.renderer.domElement);
})
this.renderer = new THREE.WebGLRenderer({alpha:true, antialias: true});//alpha:true 背景透明
this.renderer.setPixelRatio(window.devicePixelRatio * 2);
this.renderer.toneMapping = THREE.ACESFilmicToneMapping;
this.renderer.toneMappingExposure = 1.0;
this.renderer.shadowMap.enabled = true;
this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
},
设置光源(我这边设置的是四束光源)
let ambientLight = new THREE.AmbientLight(0xffffff,1);
this.scene.add(ambientLight);
const directional_light = new THREE.DirectionalLight(0xffffff, 1);
directional_light.position.set(0, 1, 0);
directional_light.castShadow = true;
this.scene.add(directional_light);
let a=1,b=0.6,c=10;
let directionalLight1 = new THREE.DirectionalLight(0xffffff,b);
directionalLight1.position.set(-a,-a ,a*c).normalize();
let directionalLight2 = new THREE.DirectionalLight(0xffffff,b);
directionalLight2.position.set(a,-a,-a*c).normalize();
let directionalLight3 = new THREE.DirectionalLight(0xffffff,b);
directionalLight3.position.set(-a,a,-a*c).normalize();
let directionalLight4 = new THREE.DirectionalLight(0xffffff,b);
directionalLight4.position.set(a,a,a*c).normalize();
this.scene.add(directionalLight1);
this.scene.add(directionalLight2);
this.scene.add(directionalLight3);
this.scene.add(directionalLight4);
创建控件对象,这步主要是为了可以手动控制 3D 旋转,放大缩小等效果
// 创建控件对象
change(){this.controls = new OrbitControls(this.camera, this.renderer.domElement);
this.controls.minDistance = 300
this.controls.maxDistance = 1000
this.controls.addEventListener('change', () => {this.renderer.render(this.scene, this.camera);
}); // 监听鼠标、键盘事件
// 禁止缩放
this.controls.enableZoom = this.changeFlag
// 禁止旋转
this.controls.enableRotate = this.changeFlag
// 禁止右键拖拽
this.controls.enablePan = this.changeFlag
},
创建轨道控件(这一步是为了 3D 效果自旋转)
// 更新轨道控件
animate() {if (this.renderer) {// console.log(this.stats)
// this.stats.update()
let T = this.clock.getDelta()
let renderT = 1 / 30
this.timeS = this.timeS + T
if(this.timeS> renderT) {this.controls.update();
this.renderer.render(this.scene, this.camera);
this.timeS = 0
}
requestAnimationFrame(this.animate);
if (!this.changeFlag) {this.controls.autoRotateSpeed = 15}
this.controls.autoRotate = true // 是否自动旋转
}
// 创建一个时钟对象
// this.clock = new THREE.Clock()
// this.scene.rotateY(0.01)
// 获得两帧的时间间隔 更新混合器相关的时间
// if (this.mixer) {this.mixer.update(this.clock.getDelta())}
},
根据不同的文件类型使用不同的方法导入
// 导入 FBX 模型文件
fbxLoader(){
let that=this
const loader = new FBXLoader();
loader.load(this.modelUrl,function(mesh){that.scene.add(mesh);
that.ownerInstance.callMethod('onload')
})
},
// 导入 GLB 模型文件
gblLoader(){
let that=this
const loader = new GLTFLoader();
loader.load(this.modelUrl, function(gltf) {console.log(gltf)
that.mesh = gltf.scene
let model = gltf.scene
that.scene.add(model);
that.ownerInstance.callMethod('onload')
});
},
注意事项:该效果在 uniapp 只能在 H5 运行,在 APP 运行需要使用 renderjs 这个我后续应该会有文章出来说明
原文地址: Uniapp 中 three.js 初使用(加载 fbx 或者 glb)
正文完