本节使用到的图片、素材、gltf文件,都是@老陈打码的原素材 支持!!!!!!!!!!!!!!!!!!!!!
链接:https://pan.baidu.com/s/1WWWHgekCIH7OnjI7S_3ZtQ
提取码:6666
看他们的threejs里面都地球啊,城市啊,飞机场啊啥的,如何做出一个这样的效果来呢?
其实,根本做不到,咋可能用哪些什么物料自己做一个嘛,多费时间,一般都是引入一个文件直接生成的,也就是gltf文件,继续跟着@老陈打码炫threejs
引入gltf模型文件
我们在遇到gltf文件的时候,同样需要一个专门解析gltf文件的解析器,所以需要先引入gltf解析器,并且创建解析器的实例
// 导入gltf加载器
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
// 实例化加载器gltf加载器
const gltfLoader = new GLTFLoader();
1.无压缩的gltf文件
在处理一个相对叫单一,没有那么大的gltf文件的时候,我们直接使用解析器解析就可以完成。
gltfLoader.load("/public/model/Duck.glb", (gltf) => {
console.log(gltf)
scene.add(gltf.scene);
});
我们打印发现这是一个标准物理材质,需要有光照才可以看到他的颜色, 所以,我们加入之前的环境贴图 因为这个贴图是环绕类球形的,所以需要加上球形反射贴图属性。
// 加载环境贴图
let rgbLoader = new RGBELoader();
rgbLoader.load("/public/texture/Alex_Hart-Nature_Lab_Bones_2k.hdr", (envMap) => {
//球形的反射贴图
envMap.mapping = THREE.EquirectangularReflectionMapping;
// 设置环境贴图
scene.environment = envMap;
});
这时候就会发现。我们的gltf文件成功的显示在了画布的上面。 证明我们成功的引入了gltf文件。
2.压缩过的gltf文件
在引入压缩过的gltf文件的时候,我们会发现行不通
gltfLoader.load("/public/model/city.glb", (gltf) => {
console.log(gltf)
scene.add(gltf.scene);
});
提示没有解压缩之类的话语应该是,这时候 我们就需要用工具对压缩过的gltf文件进行解压缩。
1.导入draco解码器
// 导入draco解码器
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader.js";
在threejs中 提供了一个现成的解析压缩过的gltf模型文件的解码器,我们在使用gltf文件生成我们的threejs模型时候,就需要用到他。
2. 找到draco文件夹 移动
我们最好找到draco文件夹,将其移入我们的public路径下
3.实例化draco解码器,设置draco解码路径,然后再设置draco解码器
// 实例化 draco解码器
const dracoLoader = new DRACOLoader();
// 设置draco解码器路径
dracoLoader.setDecoderPath("/public/draco/");
// 设置gltf加载器的draco解码器
gltfLoader.setDRACOLoader(dracoLoader);
这时候,再引入压缩过的gltf就可以正常的显示了。
所有代码
//导入 threejs
import * as THREE from "three";
//导入轨道控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
//导入hdr加载器
import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader.js";
// 导入gltf加载器
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
// 导入draco解码器
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader.js";
// 创建场景
const scene = new THREE.Scene();
// 创建相机
const camera = new THREE.PerspectiveCamera(
45, // 视角
window.innerWidth / window.innerHeight, // 宽高比 窗口的宽高进行设置的
0.1, // 近平面 相机最近最近能看到的物体
1000 // 远平面 相机最远能看到的物体
);
// 创建渲染器
const renderer = new THREE.WebGLRenderer();
// 设置渲染器的大小 (窗口大小)
renderer.setSize(window.innerWidth, window.innerHeight);
// 将渲染器的dom元素添加到body中
document.body.appendChild(renderer.domElement);
camera.position.z = 5;
// 为了看到z轴
camera.position.y = 2;
// 设置x轴
camera.position.x = 2;
//设置相机的焦点 (相机看向哪个点)
camera.lookAt(0, 0, 0);
//添加世界坐标辅助器 (红色x轴,绿色y轴,蓝色z轴)一个线段 参数为 线段长度
const axesHelper = new THREE.AxesHelper(5);
//添加到场景之中
scene.add(axesHelper);
// 添加轨道控制器 (修改侦听位置) 一般监听画布的事件 不监听document.body
const controls = new OrbitControls(camera, renderer.domElement);
//渲染函数
function animate() {
controls.update();
//请求动画帧
requestAnimationFrame(animate);
//渲染
renderer.render(scene, camera);
}
animate();
//渲染
// 监听窗口的变化 重新设置渲染器的大小 画布自适应窗口
window.addEventListener("resize", () => {
// 重新设置渲染器的大小
renderer.setSize(window.innerWidth, window.innerHeight);
// 重新设置相机的宽高比
camera.aspect = window.innerWidth / window.innerHeight;
// 重新计算相机的投影矩阵
camera.updateProjectionMatrix();
});
//创建gui实例
// const gui = new GUI();
//创建场景雾
scene.fog = new THREE.Fog(0xffffff, 0.1, 50);
scene.background = new THREE.Color(0x999999);
// 实例化加载器gltf加载器
const gltfLoader = new GLTFLoader();
gltfLoader.load("/public/model/Duck.glb", (gltf) => {
console.log(gltf)
scene.add(gltf.scene);
});
// 实例化 draco解码器
const dracoLoader = new DRACOLoader();
// 设置draco解码器路径
dracoLoader.setDecoderPath("/public/draco/");
// 设置gltf加载器的draco解码器
gltfLoader.setDRACOLoader(dracoLoader);
//需要解压缩
gltfLoader.load("/public/model/city.glb", (gltf) => {
console.log(gltf)
scene.add(gltf.scene);
});
// 加载环境贴图
let rgbLoader = new RGBELoader();
rgbLoader.load("/public/texture/Alex_Hart-Nature_Lab_Bones_2k.hdr", (envMap) => {
//球形的反射贴图
envMap.mapping = THREE.EquirectangularReflectionMapping;
// 设置环境贴图
scene.environment = envMap;
});