three.js添加3d模型
three官方的几何体也就那么几个,想要生成各种各样的模型,其难度十分之大,这时引入外部模型也不失为一种选择。具体引入办法如下。
导入依赖
点击查看代码
import * as THREE from "three"; import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"; //鼠标控制器 import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js"; //模型加载器
虽然名字为GLTFLoader,但实际上glb文件也是能加载的。
初始化场景
点击查看代码
this.scene = new THREE.Scene(); //新建场景 let width = window.innerWidth; //窗口宽度 let height = window.innerHeight; //窗口高度 let k = width / height; //窗口宽高比 this.camera = new THREE.PerspectiveCamera(60, k, 0.1, 1000); //透视相机 this.camera.position.set(0, 0, 10); //设置相机位置 //创建渲染器 this.renderer = new THREE.WebGLRenderer({ antialias: true, //抗锯齿 alpha: true, }); this.renderer.setSize(width, height); //设置渲染区域尺寸 document .getElementById("container") .appendChild(this.renderer.domElement); //将画布添加到container中
其中需要注意的是调节相机参数与相机位置,否则很有可能导致场景中看不见任何东西。
创建背景
这里创建背景有3种办法,各有优劣。
1、直接加载一张贴图作为场景的background。优点:十分简单易于使用。缺点:始终是一张平行与屏幕的平面,无法随鼠标移动拖拽而变换。
点击查看代码
//创建宇宙背景 createUniverse() { let texture = new THREE.TextureLoader().load(BgImg); //加载背景贴图 this.scene.background = texture; //设置场景背景 },
2、使用天空盒子,加载CubeTextureLoader纹理,再将该纹理设为场景的background。优点:可随鼠标移动拖拽而变换。缺点:需要特制的六张天空盒子贴图,贴图不吻合时,立方体空间边缘会出现明显割裂感,视角两侧贴图会被拉伸。
点击查看代码
import right from "@/assets/img/space1/right.jpg"; import left from "@/assets/img/space1/left.jpg"; import top from "@/assets/img/space1/top.jpg"; import bottom from "@/assets/img/space1/bottom.jpg"; import front from "@/assets/img/space1/front.jpg"; import back from "@/assets/img/space1/back.jpg"; //创建天空盒子 createSkyBox() { //加载天空盒子纹理 let cubeTexture = new THREE.CubeTextureLoader().load([ right, left, top, bottom, front, back, ]); this.scene.background = cubeTexture; //设置场景背景 },
3、创建一个较大的球体,将场景内的物体全部放入球体内部,此思路也是全景图原理,在vr看房项目中大多能遇见。优点:可随鼠标移动拖拽而变换,由于球心距球壳距离相等,不会出现视角两侧贴图拉伸。缺点:需要调节球体半径到合适的尺度,保证空间相机在球体内部,否则空间会出现黑块。需要保证贴图为360全景图。否则球壳拼接边缘会出现明显空间割裂。
点击查看代码
//创建全景背景 createPanoramicBj() { let geometry = new THREE.SphereGeometry(10000, 100, 100); //几何体 let material = new THREE.MeshBasicMaterial({ map: new THREE.TextureLoader().load(panoramicImg), //导入图片纹理 color: 0xffffff, //材质背面显示 side: THREE.BackSide, }); let mesh = new THREE.Mesh(geometry, material); this.scene.add(mesh); },
其中必须使用side: THREE.BackSide,显示材质背面。
3种办法视情况选择,当然也可能有其他我不知道办法。本文使用为创建球体的办法。
创建鼠标控制器
点击查看代码
//创建轨道控制 createOrbitControls() { //没有缩放阻尼 this.mouseControls = new OrbitControls( this.camera, this.renderer.domElement ); //创建控件对象 this.mouseControls.enablePan = true; //右键平移拖拽 this.mouseControls.enableZoom = true; //鼠标缩放 this.mouseControls.minDistance = 0; //相机距离原点的距离范围 this.mouseControls.maxDistance = 100; this.mouseControls.enableDamping = true; //滑动阻尼 this.mouseControls.dampingFactor = 0.1; //(默认.25) this.mouseControls.maxPolarAngle = (Math.PI / 4) * 3; //y旋转角度范围 this.mouseControls.minPolarAngle = Math.PI / 4; // this.mouseControls.autoRotate = true; //自转(相机) // this.mouseControls.autoRotateSpeed = 5; //自转速度 },
相机的最大与最小距离需要注意调节,否则会出现缩放异常。
创建光源
点击查看代码
//创建光源 createLight() { this.ambientLight = new THREE.AmbientLight(0x6aceff); //设置环境光 this.scene.add(this.ambientLight); //将环境光添加到场景中 this.pointLight = new THREE.PointLight(0xffffff, 1, 0); this.pointLight.position.set(10, 10, 0); //设置点光源位置 this.scene.add(this.pointLight); //将点光源添加至场景 },
模型最终显示出来的颜色与环境光和点光源均有关。同时也需要注意调节点光源位置。
加载模型
点击查看代码
//加载模型 loadModel() { let loader = new GLTFLoader(); //此路径是相当对于public中index.html的,模型必须放在public路径下 loader.load("model/bdd.glb", (gltf) => { console.log(gltf); gltf.scene.position.set(0, 0, 0); this.scene.add(gltf.scene); }); },
需要注意的是这里加载的模型是必须放在public路径下的,否则会无法加载。注意根据模型尺寸,调节场景的各种参数,否则会无法看见模型。
渲染场景
点击查看代码
//重复渲染 repeatRender() { //请求动画帧,屏幕每刷新一次调用一次,绑定屏幕刷新频率 requestAnimationFrame(this.repeatRender); this.mouseControls.update(); //实时更新轨道控制 // this.cube.rotation.y += 0.01; //以y为轴心的旋转角度每帧自加0.01 this.renderer.render(this.scene, this.camera); //将场景和相机进行渲染 },
渲染场景时不要忘记实时update鼠标控制器。
完成
加载一个冰墩墩。
加载一朵玫瑰(win10自带的3D Viewer里面导出的,本文使用的模型全是glb文件。如果是gltf整体文件也可直接导入three,但如果贴图与模型是分开的松散gltf文件可以使用3D Viewer直接另存为glb文件即可导入three)。
加载一个凯瑟琳(在这里下载的,注册用户后里面有大量免费模型可使用)
加载一个剑刃星舰(也是sketchfab里面下载的)。
浏览地址(第一次浏览会缓存模型文件,加载较长时间):http://xisite.top/original/webGL/8/index.html
源码地址:https://gitee.com/xi1213/three-load-model
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)