赞
踩
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 这个我后续应该会有文章出来说明
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。